1 机器学习,模型训练中的术语:
量词:
epoch 翻译是时代,纪元的意思,在机器学习中表示所有数据训练一个轮回的时间;
iteration 翻译是迭代的意思,在机器学习中表示,使用batchsize个样本训练一次;
batch/batchsize 翻译是一批/一批的尺寸的意思,在机器学习中表示,训练的最小量的单位,一个批次训练的数量;
举例:假设有500个样本,每次训练10个,训练50次,所有数据都进行一次训练,但是可以循环训练,训练了1000次;
上边这些简单易懂的话,我们翻译成术语是:
每个epoch训练500个样本,每个epoch有50个iteration(进行了50词迭代),每个epoch具有50个batch;
batchsize是10;
上述例子中,训练了1000次,即训练了100个iteration,2个epoch;模型权重更新次数是2 * 50 = 100;
2 常用技术方向的名称:
speaker diarization 翻译:说话人分类;
解释:这个实现的功能是,假设一个会议,有8个人发言,我们得到了一个长达一个小时的音频,我们可以通过机器学习,得到哪段语音是哪个人的发音的信息;解决的是:who spoke when的问题;
speaker verification 翻译:说话人确认,简称声纹技术(和指纹对应),简写为SV;
解释:就是用机器学习技术,来判断谁是谁,就像可以用指纹技术来确定人一样;
torch/pytorch 翻译:torch是火把,火炬的意思;
这里的torch是一个开源的机器学习框架;而pytorch是基于torch的python机器学习库;2017年由fair推出;可以方便快捷的进行机器学习工作,模型的搭建;
损失函数,loss function,或者代价函数,将随机事件,或者随机变量映射为非负实数,以表示该事件,风险或损失的函数;应用中,通过最小化损失函数,来优化和评估模型;
损失函数有很多,比如,L(y,f(x))=|y−f(x)|,指的是预测值和实际数值之间的差的绝对值;注:损失函数必须是非负的;
学习率,learning rate,运用梯度下降算法进行优化时,权重的更新规则中,在梯度项前会乘以一个系数,这个系数就叫学习速率α,就是训练的步长,一般是先大后小,先大,快速找到最优区域;后小,慢慢寻找最优解;
inference,就是推理,推测的意思,在机器学习中,就是验证,test和predict意思一样;
PLDA(probabilistic linear discriminant analysis) 概率线性判别分析;plda是一致线性分类技术;
偏导数,简单来说是对于一个多元函数,选定一个自变量并让其他自变量保持不变,只考察因变量与选定自变量的变化关系,偏导数只能表示多元函数沿某个坐标轴方向的导数;
方向导数,除开沿坐标轴方向上的导数,多元函数在非坐标轴方向上也可以求导数,这种导数称为方向导数。很容易发现,多元函数在特定点的方向导数有无穷多个,表示函数值在各个方向上的增长速度,在这些方向导数中,是否存在一个最大的方向导数,如果有,其值是否唯一?为了回答这个问题,便需要引入梯度的概念;
梯度,梯度的概念是建立在偏导数和方向导数的基础上的,梯度的本意是一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即该函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大;一般来说,梯度可以定义为一个函数的全部偏导数构成的向量(这一点与偏导数与方向导数不同,两者都为标量);
adam算法,意思是 a method for stochastic optimization,来源是:Adam: A Method for Stochastic Optimization
它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。它的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。其公式如下:
其中,前两个公式分别是对梯度的一阶矩估计和二阶矩估计,可以看作是对期望E|gt|,E|gt^2|的估计;
公式3,4是对一阶二阶矩估计的校正,这样可以近似为对期望的无偏估计。可以看出,直接对梯度的矩估计对内存没有额外的要求,而且可以根据梯度进行动态调整。最后一项前面部分是对学习率n形成的一个动态约束,而且有明确的范围;
3 一个机器学习示例代码
1 import * 2 3 def train_epoch(train_loader, model, criterion, optimizer, epoch): # 训练一个epoch的函数; 4 losses = AverageMeter() # AverageMeter,是用来管理参数的一个类,构造函数会调用reset,用update更新数值,可以调用ave等方法获取数值; 5 model.train() # 进行训练,核心函数; 6 for batch_idx, (inputs, tlabel) in enumerate(train_loader): 7 inputs = Variable(inputs.cuda()) 8 9 flabel = tlabel[:, ::hop] 10 flabel = Variable(flabel.float().cuda()) 11 12 optimizer.zero_grad() 13 out, act = model(inputs) 14 15 nf = min(flabel.shape[1], act.shape[1]) 16 out = out[:, :nf].squeeze(-1) 17 flabel = flabel[:, :nf]AverageMeter 18 loss = criterion(out, flabel) # 训练准则,即损失函数,结果是损失的数值; 19 20 torch.nn.utils.clip_grad_norm_(model.parameters(), 0.25) 21 loss.backward() 22 optimizer.step() 23 losses.update(loss.data, act.shape[0]) 24 25 return losses.avg 26 27 28 def main(): 29 parser = argparse.ArgumentParser(description="TEST Net") 30 parser.add_argument('--batch_size', type=int, default=4, help='Batch size') 31 ...... 32 args = parser.parse_args() # 定义args,细节参数省略; 33 34 os.makedirs(args.save_model_path, exist_ok=True) 35 36 train_set = ...... # 训练集合 37 train_set.__getitem__(0) # 定义了__getitem__ ,它的实例对象(假定为p),可以像这样p[key] 取值; 39 vset = ...... # 测试集合 40 41 train_loader = DataLoader(train_set, batch_size=args.batch_size, shuffle=True, num_workers=2) # 训练的结构体 42 43 criterion = nn.BCEWithLogitsLoss() 44 criterion = criterion.cuda() #定义训练准则 45 46 model = TDNN(n_classes=1000,m=0.35,encoder_type='asp') # 定义模型结构,详情见TDNN的文件 48 optimizer = optim.Adam(model.parameters(), lr=args.lr, betas=(0.9, 0.99), eps=1e-09, weight_decay=1e-6, amsgrad=False) # 优化器,根据规定准则,优化所有参数; 50 model = model.cuda() 52 scheduler = ReduceLROnPlateau(optimizer, mode='min', factor=0.5, patience=2, verbose=True, cooldown=0, min_lr=1e-7, eps=1e-08) 54 torch.backends.cudnn.benchmark = True # 大部分情况下,可以让内置的 cuDNN 的 auto-tuner 自动寻找最适合的高效算法,优化运行效率。 55 56 start_epoch = 0 57 for epoch in range(start_epoch, args.max_epoch): 58 train_loader.dataset.change_flength() 59 train_epoch(train_loader, model, criterion, optimizer, epoch) 60 61 if epoch % args.test_interval == 0: 62 epoch_error = validate...... # validate是测试函数,使用前边提到的vset进行测试 63 scheduler.step(epoch_error) # 更新scheduler 64 65 if epoch_error < best_error: # 错误率小于当前最优错误率,更新模型和最优错误率 66 best_error = epoch_error 67 save_name = os.path.join(args.save_model_path, 68 args.model+'_'+str(epoch)+'.tar') 69 torch.save...... 70 print(f"save model to {save_name}") 71 else: 72 print(f"The best loss error is still {best_error}") 73 74 if __name__ == '__main__': 75 main()