以下内容是自己学习北京邮电大学鲁鹏副教授计算机视觉与深度学习课程(A02)的一些笔记,
笔者能力有限,如有错误还望各位大佬在评论区批评指正 。
先贴一下课程官网:CV-XUEBA
篇3地址:计算机视觉与深度学习-线性分类器
目录
全连接神经网络
1、线性分类器的权值
2、全连接神经网络与线性不可分
3、全连接神经网络绘制与命名
4、激活函数
5、神经网络结构设计
6、 SOFTMAX
7、交叉熵损失
8、计算图
9、再看激活函数
10、梯度算法改进
11、权值初始化
12、 批归一化
13、欠拟合、过拟合与Dropout
14、超参数
还是从按照框图走,第一步是图像表示,本课程的图像表示都是直接利用原始像素作为特征,展开为列向量。
全连接神经网络通过级联多个变换来实现输入到输出的映射。
两层全连接神经网络可以表示为:。通过两次线性变换级联来得到最后的结果。其中max函数是一个激活函数,它将第一次变换的结果处理再送给后面的层,在级联系统中比较重要,后面会详细介绍。以此类推,对于三层的全连接神经网络可以表示为:。全连接神经网络的核心是线性分类器,其中的非线性操作(max函数)是不可去的。
在线性分类器中,W可以看作是模板,在全连接神经网络网络中,也可以看作是模板,但是模板的个数可以人为指定,而行数必须与类别个数一致。指定的作用是:丰富模板,让神经网络学习的更好。融合多个模板的匹配结果来实现最终类别打分。
对于线性可分的情况,至少存在一个线性分界面能把样本没有错误的分开。
而实际中我们采集的样本通常是线性不可分的,因此我们需要通过非线性的操作将样本分开。
这就是线性分类器与全连接神经网络的区别,线性分类器只能解决线性可分的问题,而对于线性不可分的问题线性分类器并不能很好的解决,就可以通过全连接神经网络来解决。全连接神经网络可以通过非线性操作级联一些简单的线性分类器来实现,但是要注意激活函数的重要性。
每个隐层神经元都要与前层的神经元连接所以我们把它叫做全连接神经网络。每条连接上都有一条边,每条边上都有一个权值,因此对于第一个模板而言有多少个神经元就有多少个权值,所有权值组合起来就是,以此类推。通过,就能将x映射出来。
它的命名规则是除了输入层以外这个神经网络有几层就叫几层神经网络。
如果网络中缺少了激活函数,全连接神经网络将变成一个线性分类器,因此对于全连接伸进网络我们不能把激活函数去掉。
常用的激活函数有以下几种。
Sigmoid函数能把输入的值输出为范围在0--1之间的值,太大的值输出1,太小的值输出0,中间的随输入的值的大小变化,同时它输出的值都是大于0而且不是中心对称。
tanh函数能把输入的值输出为范围在-1--1之间的值,从图像上可以知道当输入值小于-2.5或大于2.5时,输出一直是-1或1。同时输出的值是中心对称的,在数据处理时由于有正负的数据因此它比Sigmoid函数更好。
ReLU函数也就是我们前面一直提到的max函数,输入的值大于0则直接输出这个值,如果输入的值小于0则输出0。
Leaky ReLU函数将输入小于0的值乘上0.1后在输出。对于小于0的输入值不那么绝对的输出0。
激活函数是对前一层输出的每一个维度分别进行处理。
对于神经网络的结构设计并没有统一的答案。神经网络结构设计有三个要素,分别是深度设计(多少个隐层)、宽度设计(每个隐层多少个神经元)、激活函数。
就宽度设计而言, 神经元个数越多,分界面就可以越复杂,在集合上的分类能力就越强。但是也可能会出现过拟合的问题。
在设计神经网络结构时,我们要依据分类任务的难易程度来调整神经网络模型的复杂程度。分类任务越难,我们设计的神经网络结构就应该越深、越宽。但是,需要注意的是对训练集分类精度最高的全连接神经网络模型,在真实场景下识别性能未必是最好的(过拟合)。
在通常情况下,神经网络输出的是类别得分,经过Softmax操作后,我们可以得到样本是这个类别的概率,可以更加直观的反应结果。具体的过程就是将得到的分数取e的指数次方再归一化后就得到类别的概率。
通常我们会把标答表示成one-hot向量,即只有正确的类别为一,其余都为零的一维向量。
得到概率后对于后面模型的训练有很大的帮助,在神经网络训练的过程中,我们需要将预测值与真实值进行比较,从而度量当前分类器的性能。而多类支撑向量机只能在预测值中比较,并不能度量分类器输出与预测值之间的距离。由此我们引入交叉熵损失。
在介绍交叉熵损失前,我们先了解一下熵的概念,熵可以体现信息的不确定性。相对熵也叫KL散度,用来度量两个分布之间的不相似性。注意这里是散度,不是距离,距离的话pq之间的距离与qp之间的距离相等,而散度pq与qp是不一样的,。
那么为什么我们不用相对熵呢?因为在标答是one-hot向量时,交叉熵就是相对熵。
注意的结果就是KL散度,当且仅当真实分布是one-hot时才可以用交叉熵度量不相似程度。
在训练的时候,运用交叉熵我们会碰到损失变化不大,但是分类器的性能却在提高的情况,这是交叉熵特殊的地方。
计算图是一种有向图,它用来表达输入、输出以及中间变量之间的计算关系,图中的每个节点对应着一种数学运算。
下面以一个例子讲解一下:
计算图就是通过图像对一个式子进行表达。
计算图从前向就是从输入得到输出,不论函数多复杂每次只运算局部环节最后就可以得到输出。反向就可以得到输出对于输入的导数,就得到了每级运算的梯度。
需要注意的是,由于链式法则,每一级都在相乘,因此当梯度小于1时,相乘的结果是梯度在下降,可能在后面出现梯度为0的情况,这种现象叫做梯度下降。有时可以通过整体的函数来替换很长的链式(门),例如sigmoid函数,提高了计算效率,这就是计算颗粒度,门函数越多计算速率越快,计算颗粒度小,通过特定或者已知的函数替代门函数提高了计算速率,同时颗粒度变大,但是中间的函数需要自己定义。
对于梯度图来说,正向计算可以通过输入找到输出,反向计算可以找到中间任意门单元的梯度。
一些常见的门单元,加法门,正向就是相加,反向是上游梯度直接传过去;乘法门,正向相乘,反向相互交换后与上游梯度相乘;拷贝门,正向直接拷贝,反向则将上游的梯度都回传后相加;max,门正向将更大的数往后传,反向将上游梯度传给更大数的那一段,其余为零。
之前介绍了梯度消失,是由于链式法则的乘法特性导致的一种情况,还有另一种情况就是梯度爆炸,在断崖处的梯度乘以学习率后会是一个非常大的值,从而飞出了合理区域,最终导致算法不收敛。解决方案就是把沿梯度方向前进的步长限制在某个值内,这叫做梯度裁剪。这些情况并不适合网络中信息流的传递,于是在网络中的激活函数并不会选择sigmoid函数,与此类似的还有tanh函数。而ReLU函数则比较合适,不过由于在小于0的部分过于绝对,因此在全连接神经网络中一般使用Leakly ReLU函数。
10.1 梯度算法存在的问题
损失函数的特性:一个方向上变化迅速而在另一个方向上变化缓慢。我们的目标是从起点走到笑脸位置,在计算梯度的时候,很多的下降算法都存在示意图中在山壁间震荡,而在谷底前进缓慢的情况。表现出来就是,网络在训练过程中时间长,损失下降慢。而简单的增大步长可能只是加大了震荡。因此引入动量的方法。
10.2 动量法
动量法采用累加的方法求解梯度,在震荡的地方左右摇摆累加求均值,在谷底累加可以加快速度。
在更新速度时,将梯度g与衰减系数和历史速度的乘积相加。在更新权值时,小批量梯度下降算法使用的是梯度值,而动量法使用的是累加后的值,因此该算法可以减少震荡,同时加速谷底速度。对于来说,如果衰减系数取值是1,则即使梯度g为0,速度的更新也不会停止,始终有一个值,因此算法会一直运行,如果衰减系数是0.9则算法迭代几次速度也将趋于0。
损失函数通常还会具有不太友好的局部最小值或鞍点(高维空间非常常见)---局部梯度为0的点但是并不是最小值。传统的下降算法在这种情况下算法将停下,而动量法由于速度的存在,算法可以通过局部最小值或鞍点。
10.3 自适应梯度法
自适应梯度法可以在震荡方向减小步长,在平坦方向增大步长。梯度幅度的平方较大的方向是震荡方向,梯度幅度的平方较小的方向是平坦方向。但处于震荡位置时,由于累积的平方梯度r的值是很大,因此前一学习率(步长)与的比值就比较小,从而在下次迭代时学习率(步长)就变小,平坦方向则相反,由此自适应的调节了步长。当累积平方梯度r相对于学习率(步长)过大后,将失去对学习率(步长)的调节作用,因此加入衰减速率,调节方法与动量法中的动量系数(衰减系数)类似。
10.4 ADAM
Adam同时使用了动量与自适应梯度的思想,由于衰减系数,动量系数取值的问题,初始时系统运行将很缓慢,因此引入第五步进行修正偏差。
全零初始化:网络中不同的神经元有相同的输出,进行同样的参数更新;因此,这些神经元学到的参数都一样,等价于一个神经元。
有效的初始化方法应该是使网络各层的激活值和局部梯度的方差在传播过程中尽量保持一致;以保持网络中正向和反向数据流动。
好的初始化方法可以防止前向传播过程中的信息消失,也可以解决反向传播过程中的梯度消失。
Xavier初始化:
式中,当变量w与z独立且均值都为0是,则平方项结果都为零,因此式子最后结果如图,这样使得每层神经元激活值和局部梯度的方差在传播过程中尽量保持一致。也就是说权值采样自的高斯分布---(均值为0,方差设为1/N时采样),N为输入神经元个数,符合我们的目标,即最后一个隐层的所有神经元的值还是符合正态分布。
当Xavier初始化采用ReLU激活函数时,不符合我们的目标。而HE初始化(MSRA)可以使用ReLU激活函数,将权值采样改成
在每一层神经元输出后进行批归一化,使输出值符合0均值1方差,也能解决前向传递过程中的信号消失问题和梯度消失问题。
过拟合:模型在训练集的准确率很高,实际使用场景识别率很低(已经n次提到),原因可能只是记住了训练集数据,而不是学习了规律。
欠拟合:模型描述能力太弱,不能很好学习到数据中的规律,原因可能是模型过于简单。
机器学习的根本问题就是优化(调节模型参数,让模型在数据上得到最佳性能)和泛化(训练好的模型在前所未见的数据上的性能好坏)的问题。
应对过拟合最优的方法:学习更多的数据;次优的方法:调节模型允许存储的信息量或者对模型允许存储的信息加以约束,该类方法也称为正则化,添加正则项可以使权值分散,使系统学习更多的特征。还有调节模型大小,随机失活的方法。
随机失活(Dropout):让隐层的神经元以一定的概率不被激活。实现方式:训练过程中,对某一层使用Dropout,就是随机将该层的一些输出舍弃(输出值设置为0),这些被舍弃的神经元就好像被网络删除了一样。
随机失活比率(Dropout ratio):是被设为0的特征所占的比例,通常在0.2~0.5范围内。
那么随机失活为什么可以防止过拟合呢?
解释1:随机失活减少了计算网络的参数,降低了模型容量,从而防止了拟合。
解释2:随机失活使得权重分散,相当于正则化的作用,从而防止了拟合。
解释3:Dropout可以看作模型集成(即可能是未关闭的神经元输出一个值,下次可能是上次关闭的神经元这次未关闭输出,而上次未关闭的神经元这次关闭),从而防止了拟合。
实际应用中通常要对测试结果乘一个系数p,使测试和训练输出一致。
下面以三层神经网络为例:
p = 0.5 # 神经元保持激活状态的概率,改值越高失活的单元越少
def train(X):
H1 = np.maximum(0, np.dot(W1, X) + b1)
U1 = np.random.rand(*H1.shape) < p # 第一层的mask
H1 *= U1 # 第一层dropout操作
H2 = np.maximum(0, np.dot(W2, X) + b2)
U2 = np.random.rand(*H2.shape) < p # 第二层的mask
H2 *= U2 # 第二层dropout操作
out = np.dot(W3, H2) + b3
def predict(X):
H1 = np.maximum(0, np.dot(W1, X) + b1) * p
H2 = np.maximum(0, np.dot(W2, X) + b2) * p
out = np.dot(W3, H2) + b3
上述方法在测试阶段也引入了随机失活,而测试阶段所有的神经元必须打开,改进方法:
p = 0.5 # 神经元保持激活状态的概率,改值越高失活的单元越少
def train_new(X):
H1 = np.maximum(0, np.dot(W1, X) + b1)
U1 = (np.random.rand(*H1.shape) < p) / p # 第一层的mask
H1 *= U1 # 第一层dropout操作
H2 = np.maximum(0, np.dot(W2, X) + b2)
U2 = (np.random.rand(*H2.shape) < p) / p # 第二层的mask
H2 *= U2 # 第二层dropout操作
out = np.dot(W3, H2) + b3
def predict_new(X):
H1 = np.maximum(0, np.dot(W1, X) + b1)
H2 = np.maximum(0, np.dot(W2, X) + b2)
out = np.dot(W3, H2) + b3
对于网络结构来说:隐层神经元个数,网络层数,非线性单元选择等
对于优化相关来说:学习率、dropout比率、正则项强度等
14.1 学习率设置
学习率过大,训练过程无法收敛。
学习率偏大,在最小值附近震荡,达不到最优。
学习率太小,收敛时间较长。
学习率适中,收敛快、结果好。
14.2 超参数优化方法
网格搜索法:
1、每个超参数分别取几个值,组合这些超参数值,形成多组超参数;
2、在验证集上评估每组超参数的模型性能;
3、选择性能最优的模型所采用的那组值作为最终的超参数的值。
随机搜索法:
1、参数空间内随机取点,每个点对应一组超参数;
2、在验证集上评估每组超参数的模型性能;
3、选择性能最优的模型所采用的那组值作为最终的超参数的值。
超参数的搜索策略有粗搜索,即利用随机法在较大范围里采用超参数,训练一个周期,依据验证集正确率缩小超参数范围。还有精搜索,即利用随机法在较大范围里采用超参数,训练五到十个周期,选择验证集上精度最高的那组超参数。一般采用精搜索。
在超参数的标尺空间上建议在对数空间上进行随机采样。
*再次申明这只是笔者自学课程的一些笔记,想着学了留下点东西,限于笔者能力有限,
如有错误还望大神指正。如果觉得笔者水平太低大可当作饭后消遣。希望我们在视觉学习的道路上勇往直前!