神经网络优化的多种途径
优化神经网络表现的几种方法
更改损失函数为交叉熵损失函数
交叉熵损失函数的形式为:$C=-\frac{1}{n}\sum_x{[y\ln{a}+(1-y)\ln{(1-a)}]}$
此时$\frac{\partial{C}}{\partial{w_j}}=\frac{1}{n}\sum_x{\frac{\sigma’(z)x_j}{\sigma(z)(1-\sigma(z))}(\sigma(z)-y)}$
当$\sigma$为sigmoid函数时,它有一个特殊的性质就是$\sigma’(z)x_j=\sigma(z)(1-\sigma(z))$,所以$\frac{\partial{C}}{\partial{w_j}}=\frac{1}{n}\sum_x{x_j(\sigma(z)-y))}$,可以发现这里的$\frac{\partial{C}}{\partial{w_j}}$已经和$\sigma’(z)$无关了,就算$\sigma(z)$已经很接近0或者1,也不会对学习速率产生什么影响,并且预期结果与输出结果差别越大,学习的速率就越快。
同样可以得出$\frac{\partial{C}}{\partial{b}}=\frac{1}{n}\sum_x{(\sigma(z)-y))}$与$\sigma’(z)$无关。
所以使用sigmoid函数时,交叉熵损失函数可以有效地避免神经元饱和的情况。当使用平方和损失函数时,则对于sigmoid函数没有这样的约分作用。但当激活函数是线性函数时,平方和损失函数也是一个不错的选择,这时他也会得到和$\frac{\partial{C}}{\partial{w_j}}=\frac{1}{n}\sum_x{x_j(\sigma(z)-y))}$相同的结果,可以说交叉熵损失函数是为了sigmoid函数族量身定做的一个损失函数。
softmax激活函数
$$a_j^L=\frac{e^{z_j^L}}{\sum_k{e^{z_k^L}}}$$
这里的$z_j^L$还是指输入x的线性组合$(w_j^L)^Tx^{L-1}+b_j^L$。
softmax输出的结果是一个概率,这是相对于sigmoid的一个优势。同时softmax的一个值和同一层的其他值有关,而sigmoid只和自己的值有关。
同时,对于softmax梯度消失的问题,使用$C\equiv-\ln{a_y^L}$这样的损失函数(对于类别为y的样本,预测概率$a_y^L$越高越好): $$\frac{\partial{C}}{\partial{b_j^L}}=a_j^L-y_j$$ $$\frac{\partial{C}}{\partial{w_{jk}^L}}=a_k^{L-1}(a_j^L-y_j)$$
weights中x过小造成的梯度消失则不可能通过设计损失函数来避免。
过拟合与正则化
过拟合
-
一个有效的观察是否过拟合的方式就是观察准确率曲线,如果训练集准确率不断上升,测试集准确率却开始下下降,就说明出现过拟合了。
-
early stopping:使用验证集,当验证集的准确率已经饱和(saturated)时,停止训练,以此防止过拟合。如何判断是否已经饱和:这可以自己决定,比如连续三次没有提升到更高等。 为什么使用验证集:使用验证集可以避免对测试集过拟合,从而得到正确的测试效果。
-
增大训练集规模(not always the option,要是有这么大的训练集规模,那早就给你了= =)
-
降低网络规模(not always the option,大网络有大智慧)
-
正则化(接下来详解)
正则化
$L2$正则化的交叉熵损失函数,这里第二个部分就是正则化部分,n是训练集的大小: $$C = -\frac{1}{n}\sum_{xj}[y_j\ln{a_j^L} + (1-y_j)\ln(1-a_j^L)]+\frac{\lambda}{2n}\sum_w{w^2}$$
正则化不需要bias,因为这个不和任何值相乘,只定义阈值,所以不会造成过拟合。
正则化让网络更倾向于小的权重,大的权重只有在显著减小损失函数的时候才会被采用。
求导:对于正则化之后的损失函数求导,求$w$的偏导只需要加上一个$\frac{\lambda}{n}w$,求$b$的偏导则完全不变。从这里可以看到,在随机梯度下降的时候,$w=(1-\frac{\eta\lambda}{n})w-\frac{\eta}{m}\sum_x{\frac{\partial{C_x}}{\partial{w}}}$,这里的w会因为$1-\frac{\eta\lambda}{n}$这个系数而越来越小
正则化的神经网络对于小的噪音会作出更小的反应,所以正则化神经网络可能更适合小规模的神经网络,而非正则化神经网络适合训练带有大量关于噪声的信息的数据,模型比较复杂。
正则化目前还没有系统的知识体系,来确定哪种正则化的效果更好。
事实上神经网络会有一个自我正则化的过程,但是这个机制并没有被很好地研究出来。
其它正则化技术
####L1正则化 正则化的形式改成L1曼哈顿距离: $$C = C_0+\frac{\lambda}{n}\sum_w|w|$$
如果对L1正则化的cost函数求偏导: $$\frac{\partial{C}}{\partial{w}}=\frac{\partial{C_0}}{\partial{w}}+\frac{\lambda}{n}sign(w)$$
和L2一样,L1正则化让w更小了。不同的是在L1中缩小的是一个常数,而L2是依靠一个乘积对w进行百分比的缩放。所以当w很大的时候,L1需要比L2更多的步数才会把w缩放到相同的效果;当w很大的时候,L1又比L2要快很多。结果就是L1倾向于把很重要的w相对缩小,而其他不是很重要的w减小到几乎为零。
Dropout
Dropout不依靠修改cost函数来避免过拟合,而是修改网络本身,它通过每次都随机删去一部分神经元,对于参数不断更新。由于每次都只有一半的神经元更新了,所以对于它们每次更新的梯度会减半。
Dropout可以看成不同神经网络对于权值更新都进行了投票,同时也可以这么理解:避免了某个权值依赖其他权值的情况,让训练的权值更鲁棒,让每个权值都能发挥作用。从这个方面看,dropout是直接让权值发挥作用,范数正则化则是惩罚大权值来间接让小权值发挥作用。
人工扩大训练集数量
通过旋转、变形、增加噪音等各种方法来扩大训练集数量,需要注意的是,这些方法需要因地制宜。在大规模的数据集上,不同的机器学习准确率差异不一定能说明某个算法更好,很可能在另一个数据集上另一种算法就更好。
权重初始化
前面讨论的修改损失函数只能解决最后一层输出时的梯度消失问题,在隐层中的梯度消失问题还是没有解决。如果使用标准正态分布来初始化权重,假设输入的都是1,那么最终的z期望就是一个标准正态分布,z的绝对值大于30的可能性还是比较大的,这个时候就会有梯度消失的问题,并且还影响到后面关联的神经元。输入都是1只是一个特殊情况,但是随机权重造成的一开始就梯度消失是实实在在存在的。
为了解决这个问题,可以让正态分布的坡度更陡,比如把标准差改为$\frac{1}{\sqrt{n_{in}}}$,那么如果输入一半为1一半为0,且bias的标准差还是1,那么最终z的标准差就是$\sqrt{\frac{3}{2}}$,大多数情况下,这样训练的最终的效果和标准正态分布是一样的,但是时间明显缩短了。但有些时候,这样做还会让最终的结果有所提升。
除了$\frac{1}{\sqrt{n_{in}}}$以外,还有其他的权值初始化方法,在《Practical Recommendations for Gradient-Based Training of Deep Architectures》有更多记载,但是一般来说$\frac{1}{\sqrt{n_{in}}}$已经可以取得很好的效果了。
L2正则化其实一定程度上也扮演了这里权值初始化的工作,当有些权值比较大时,它会进行惩罚,使这个权值更快下降。
选择参数的方法
Early Stop
通过诸如"最近N次无提升”($no-improvement-in-n$)、“平均准确率是否提升"等判断条件,可以让算法自己决定是否已过拟合。
学习率
首先寻找让cost显著下降的大概范围。比如从0.001开始,逐步提升到0.1, 1…,直到不再下降;再从0.0001,0.00001…,直到从前几个训练开始cost就不再下降。验证集cost比训练集cost更适合用来评估学习率。
其次,通过先设置较高的学习率,然后逐步减少学习率。如:“最近N次无提升"之后,就减半学习率,继续学习,直到学习率是原来的1024分之一。在测试模型时,只要固定学习率就好了,动态学习率在模型稳定的时候才应该考虑。关于动态学习率的论文:Practical recommendations for gradient-based training of deep architectures
正则项系数
建议先设置为0,然后在这个情况下训练出一个较好的$\eta$,再使用这个$\eta$训练出一个合适的正则项系数,最后用这个训练好的$\lambda$再反过来训练$\eta$(感觉类似于EM算法)
自动化参数选择
这两个算法都是2012年的论文中提到的。关于参数优化的论文数不胜数,但是真正有价值的不过寥寥数篇。在Neural Networks: Tricks of the Trade中涉及了很多近些年来关于深度学习的新成果。
神经网络的调优还没有一个系统的求解方法,但将其优化的回报也是巨大的。
随机梯度下降的不同实现
使用后向传播可以很好地完成随机梯度下降的工作,但是还有其他很多的方式来实现随机梯度下降,如Hessian技术和冲量技术。
Hessian技术
使用泰勒展式,利用到二次偏导,所以需要更少的迭代次数,但是每次的计算十分耗时,所以现在都不会使用这个方法,但是受到这个方法的启发,开发出了很多有效的方法,其中一个就是冲量方法。
Momentum技术(冲量技术)
随机梯度下降的更新方式是$\omega \to \omega’ = \omega -\eta\nabla C$,冲量梯度下降的更新方式是 $$v \to v'=\mu v-\eta\nabla C$$ $$\omega \to \omega'=\omega+v'$$
在冲量技术中,梯度不直接改变权值,而是类似物理运动一样,改变速度,再通过速度的改变来间接影响权值。这里的$\mu$类似物理中的摩擦力,如果$\mu=1$,说明没有摩擦力,$v$的改变完全依赖梯度。$\mu<1$则说明有摩擦力。