神经网络的一些概念
批大小、epoch
批大小,就是每次调整参数前所选取的样本(batch)数量,如果批大小为N,每次会选取N个样本,分别带入网络,算出它们分别对应的参数调整值,然后将所有调整值取平均,作为最后的调整值,以此调整网络的参数。
-
如果N较大,训练速度快,可保证得到的调整值很稳定;但占用显存大,且此时SGD中的梯度会更准确,但网络更容易陷入鞍点和极值点的泥潭,最终得到的网络性能往往不如批大小较小时的效果好。
-
如果N较小,训练速度慢,但占用显存小,且得到的调整值有一定的随机性,网络更容易跳出鞍点和极值点,合适的批大小对网络的训练很重要。
epoch,即每学一遍数据,就称为一个epoch.
例如,若数据集中有1000个样本,批大小为10,那么将样本全部训练一遍后,网络会被调整100次,但这不代表网络达到最优,重复这个过程,让网络多学习几遍。
每一个epoch都需要打乱数据的顺序,以使网络受到的调整更具有多样性。
非线性激活函数
非线性激活函数的必要性
神经元的输出是输入的线性函数,而线性函数之间的嵌套仍然会得到线性函数,因此,如果只是把神经元简单联结在一起,不加入非线性处理,那么最终得到的仍然是线性函数,这就无法描述各种复杂的现象。
常用的非线性激活函数
ReLU、sigmoid、tanh
sigmoid倒数计算过程如下:
而这三者众最常用的是ReLU函数,有以下优点:
- Relu的运算非常简单、快速
- Relu可避免“梯度消失”
- 使用Relu往往能带来比使用sigmoid和tanh时更佳的网络性能
梯度消失、梯度爆炸
梯度消失:如果采用sigmoid或tanh非线性,在输入的绝对值很大的时候,会出现饱和,即导数趋近0,会造成梯度消失
梯度爆炸:如果网络中的w很大,例如初始化网络时实用了过大的初始值,或者网络的权重随着训练越来越大,就可能发生梯度爆炸。对于循环神经网络和GAN,较为容易出现这种现象。
训练过程
假设我们的数据共有10000个,批大小为100.那么训练网络的典型过程如下:
- 读入所有数据。
- 将数据划分为训练集和测试集,例如前9000个作为训练集,后1000个作为测试集
- 开始第一个epoch。将训练集的9000个数据打乱
- 将第一个batch,即打乱后的数据的第1~100号,送入网络
- 正向传播。将结果与期望值比较,计算损失
- 反向传播,更新网络参数
- 将第2个batch,即打乱后的数据的第101~200号,送入网络,重复上述过程
- 在所有训练集完成后,即经过9000/100=90个batch后,完成第一个epoch
- 将测试集送入网络。正向传播,将结果与期望值比较,计算损失
- 观察训练集的损失和测试集的损失,调整超参数或停止训练
- 开始第二个epoch。重复上述过程
损失函数
损失函数用来评价模型的预测值和真实值不一样的程度,损失函数越好,通常模型的性能越好。不同的模型用的损失函数一般也不一样。
MSE损失(L2 Loss)
从直觉上理解均方差损失,这个损失函数的最小值为 0(当预测等于真实值时),最大值为无穷大。在模型输出与真实值的误差服从高斯分布的假设下,最小化均方差损失函数与极大似然估计本质上是一致的。
适用于回归问题
MAE损失(L1 Loss)
MAE 损失的最小值为 0(当预测等于真实值时),最大值为无穷大。MAE 假设误差服从拉普拉斯分布。
适用于回归问题
MAE 和 MSE 作为损失函数的主要区别是:
MSE 通常比 MAE 可以更快地收敛。
MAE 对于 outlier 更加 robust
softmax损失
适用于分类问题
p(x)是期望的概率,q(x)为网络输出的概率
欠拟合、过拟合
欠拟合
在训练集上性能差,称为欠拟合
梯度下降属于贪心算法,对于非凸的问题(绝大多数问题是非凸的),有可能陷入局部极小值点,无法保证到达全局极小值点。
出现欠拟合的原因:
-
网络的容量不足,因为网络的广度和深度不够,可通过增大网络的规模解决
-
如果网络规模很大,仍然拟合效果差,那就是因为网络陷入了局部的极值,或者网络的拟合速度不够, 可能是因为训练的超参数不够妥当,也可能是因为数据的问题。
过拟合
在训练集上性能好,在测试集上性能差,称为过拟合
常用的防止过拟合方法防止过拟合
学习速率
梯度下降公式
用简单的损失LOSS的等高线图,说明学习速率对于学习过程的影响
左图是学习速率合适的例子
右图是学习速率太大的例子,由于每步迈的太大,出现了明显的震荡,而且可能让网络崩溃
学习速率太小,训练速度会更慢,也更可能陷入局部最小值,出现欠拟合
学习速率的影响曲线如下:
最佳方式是在训练的初始阶段使用较高的学习速率,然后缩小学习速率,可改善最终的收敛效果。
在实际训练中,通常采取这样的方案:最初X个epoch使用a的学习速率,然后每过Y 个epoch将学习速率减少为原来的b分之一
参数初始化
神经网络的参数包括权重和偏置等,它们的初始化方法很重要,如果初始参数接近最终的参数,那么就可立即完成训练。通常我们会将网络的初始权重设置为正态分布的随机数,网络的初始偏置仍然可以设置为全零。还可通过预训练和精调实现。
神经网络训练常见bug和检查方法
bug来自数据
- 对数据做可视化,检查数据是否正确,尤其是格式是否正确,训练数据和测试数据的格式是否一致
- 检查每个batch是否正确的使用了随机次序的数据
- 检查数据迭代器是否正常工作
- 检查数据的增强代码和预处理代码是否正确,注意训练和测试时应使用相同的预处理代码
- 检查标签是否正确,在打散数据顺序时是否相应的打散了标签
bug来自模型
- 定义网络时是否写错了变量名、神经元个数、卷积核大小等,或是否写漏了层
- 检查模型是否能完全拟合一个很小的训练数据集
- 检查损失函数的计算是否正确,人工检查可视化网络的输出与正确标签,还可加入更多的性能指标
bug来自训练算法
如果手工写训练程序,手工定义特殊的层,手工定义特殊的运算,就可能出现错误