反向传播算法是大多数神经网络的基础,咱们应该多花点时间掌握它。算法
还有一些技术可以帮助咱们改进反向传播算法,从而改进神经网络的学习方式,包括:网络
这里来看一个很是简单的神经元,咱们输入1,指望它输出0。app
咱们看看 Gradient Descent 是如何帮助咱们学习 Weights 和 Biases 的。函数
咱们的初始值以下:
$$
Weight = 0.6 \
Bias = 0.9 \
\eta = 0.15
$$
性能
这个神经元的初始输出是 0.82 。学习
咱们看到神经元可以迅速地学习 Weights 和 Biases ,通过300 epoch 的学习,最终输出是 0.09,已经很接近咱们的预期 0 ,这个结果已经足够好了。测试
咱们修改下初始值,再来看下:
$$
Weight = 2 \
Bias = 2 \
\eta = 0.15
$$
ui
这个神经元的初始输出是 0.98 。3d
尽管 Learning Rate 同样,可是咱们看到学习在一开始很是缓慢。看起来在前150 epoch ,Weights 和 Biases 都没有改变太多。blog
从这个例子咱们能够看出,人工神经元在偏差很大的时候,学习遇到了问题,学习速度变慢了。
神经元的学习方式:
经过计算代价函数的偏导 $\frac{\partial C}{\partial w}$ 和 $\frac{\partial C}{\partial b}$ 来改变 Weights 和 Biases 。
咱们说学习速度变慢,其实是在说偏导很小。
咱们的代价函数是均方偏差代价函数
$$
C = \frac{ (y-a)^2 }{2}
$$
在激活函数是Sigmoid函数时
$$
a = \sigma(z) \
z = wx+b
$$
代价函数的偏导是
$$
\frac{\partial C}{\partial w} = (a-y) \sigma'(z) x \
\frac{\partial C}{\partial b} = (a-y) \sigma'(z) \
$$
当x=1,y=0时
$$
\frac{\partial C}{\partial w} = a \sigma'(z) \
\frac{\partial C}{\partial b} = a \sigma'(z) \
$$
咱们来看下Sigmoid函数的形状
当神经元的输出接近1时,曲线变得很是平缓,$\sigma'(z)$ 就变得很是小,从而 代价函数的偏导 $\frac{\partial C}{\partial w}$ 和 $\frac{\partial C}{\partial b}$ 也会变得很是小。
这就是学习速度变慢的根源。
那么,咱们换个代价函数能不能解决上面的问题?
再看拥有多个输入变量神经元模型
$$
z = \sum_j w_j x_j + b
$$
咱们为这个神经元定义交叉熵代价函数以下:
$$
C = -\frac{1}{n} \sum_x \left[y \ln a + (1-y ) \ln (1-a) \right]
$$
好比对于样本x,它的
$$
y = 0 \
a \approx 0
$$
这样,等式的第一项就是0
从图上能够看出,等式的第二项$\ln(1-a) \approx 0$
对于样本x
$$
y = 1 \
a \approx 1
$$
等式的第二项为0
等式的第一项$\ln a \approx 0$
上面两种状况,交叉熵代价函数都约等于0
先看下交叉熵关于权重的偏导
$$
\frac{\partial C}{\partial w_j} = -\frac{1}{n} \sum_x \left(
\frac{y }{\sigma(z)} -\frac{(1-y)}{1-\sigma(z)} \right)
\frac{\partial \sigma}{\partial w_j}
\
= -\frac{1}{n} \sum_x \left(
\frac{y}{\sigma(z)}
-\frac{(1-y)}{1-\sigma(z)} \right)\sigma'(z) x_j
$$
通分简化后
$$
\begin{eqnarray}
\frac{\partial C}{\partial w_j} & = & \frac{1}{n}
\sum_x \frac{\sigma'(z) x_j}{\sigma(z) (1-\sigma(z))}
(\sigma(z)-y).
\tag{60}\end{eqnarray}
$$
咱们知道$\sigma'$
$$
\sigma(z) = \frac{1}{1+e^{-z}} \
\sigma'(z) = \sigma(z)(1-\sigma(z))
$$
代入到上面的公式中
$$
\frac{\partial C}{\partial w_j} = \frac{1}{n} \sum_x x_j(\sigma(z)-y)
$$
从交叉熵关于权重的偏导中,咱们看到权重的学习速率能够是被输出结果的偏差所控制。
以前均方偏差关于权重的偏导中,偏差太大致使$\sigma'(z)$很是小,形成学习速度很是慢。
如今交叉熵关于权重的偏导中,$\sigma'(z)$被抵消掉了,所以不会担忧偏差太大会致使学习速度慢。相反,偏差越大咱们的神经元学习速率越大。
再来看看使用交叉熵代价函数时的学习速度。
$$
Weight = 0.6 \
Bias = 0.9 \
\eta = 0.15
$$
对于交叉熵代价函数而言,Learning Rate = 0.15 过高了,学得太快,以致于咱们看不清楚代价函数的值是如何变化的。
这里将 Learning Rate 换成 0.005 再看一次。
$$
Weight = 0.6 \
Bias = 0.9 \
\eta = 0.005
$$
咱们看到和以前同样好。
$$
Weight = 2 \
Bias = 2 \
\eta = 0.005
$$
咱们看到偏差太大没有致使学习速度变慢。
激活函数除了Sigmoid,还有Softmax。
第j个输出神经元的激活值 $a_j^L$ 是
$$
a_j^L = \frac{e^{z_j^L}}{\sum_k e^{z_k^L}}
$$
分母是对全部输出神经元求和。
从公式咱们能够看出,Softmax层的全部输出激活值都是正数,而且它们加起来和为1。
这样就能够把Softmax层获得的输出看做是一个几率分布,将数据激活值 $a_j^L$看做是神经网络认为结果是 j 的几率。
函数的单调性,指函数的自变量增大或减少,函数值也增大或减少。
Softmax也有这样的特性,当加权输入 $z_j^L$ 增长时,激活值 $a_j^L$ 也增长。
sigmoid层的第j个神经元的输出是
$$
a_j^L = \sigma(z_j^L)
$$
它是只关于第j个神级元的加权输入的一个函数。
而 Softmax 层的任何一个 $a_j^L$ ,都要依赖该层全部神经元的加权输入。
咱们有一个带有Softmax层的神经网络,已知激活值,那么加权输入为:
$$
z_j^L = \ln a_j^L + C
$$
Sigmoid 输出层与 Cross-Entropy 代价函数搭配
Softmax 输出层与 Log-Likelihood 代价函数搭配
Log-Likelihood 代价函数的公式是:
$$
C \equiv - \ln a_y^L
$$
若是输入的是数字 7 对应的图像,那么 Log-Likelihood 代价是
$$
-\ln a_7^L
$$
若是网络工做很好,对输出 7 很是自信,$a_7^L$ 会很是接近1,那么$-\ln a_7^L$ 就会很小。
若是网络工做很差,几率 $a_7^L$ 会很小,而 $-\ln a_7^L$ 会很大。
$$
\frac{\partial C}{\partial b^L_j} = a^L_j-y_j
\
\frac{\partial C}{\partial w^L_{jk}} = a^{L-1}_k (a^L_j-y_j)
$$
这些表达式确保咱们不会遇到学习速度衰退的问题。
$\delta_j^L = a_j^L - y_j$
Johnny von Neumann 说四个参数能够模拟一头大象,五个参数可让它摇动鼻子。
Enrico Fermi 认为,拥有大量自由参数的模型可以描述一个足够宽泛的现象。即便这样的模型与现有数据拟合得很是好,但它并无真正地洞察到现象背后的本质,以致于不能普及到新的状况上。
训练数据的代价
测试数据的准确度
测试数据的代价
训练数据的准确度
咱们看到,训练数据的代价一直在降低,这可能让咱们以为模型彷佛一直在改进。
可是从测试数据的准确度来看,280 epoch 后就几乎中止改善。
从测试数据的代价来看,更直观,在15 epoch前代价一直在下降,但以后却开始变大。而训练数据的代价是一直在下降的。
从训练数据的准确度来看,训练数据的准确率上升到100%,能正确分类全部的训练数据,可是在测试数据上的准确率却直邮82.27% 。
以上种种迹象代表,280 epoch 开始的网络产生了 OverFitting 。
在含有大量 Weights 和 Biases 参数时,神经网络很容易过拟合。咱们须要跟踪网络训练过程当中测试数据的准确度,若是测数据集的准确度不在提升,就应该中止训练。
咱们引入 Validation Data,每一步训练后,计算 Validation Data 的分类准确度,一旦分类准确度达到饱和,就中止训练。这种策略叫作 Early Stopping(提早终止)。
若是基于 Test Data 去作,有可能咱们最后的网络是对 Test Data 过拟合的,网络的性能不能推广到其它数据集。
能够将 Validation Data 看做帮助咱们学习合适超参的一种训练数据。
这里超参是指网络层数,隐藏层神经元个数,学习率,批次大小。
增长训练数据是下降过拟合的最好方法之一。
同样的超参,只是训练图片从1000增长到50000,测试数据和训练数据的准确度更加接近,差距从以前17.73%下降到1.53% 。
虽然过拟合依然存在,但已经大大下降,咱们的网络能从训练数据更好地泛化到测试数据。
除了增长训练数据,还能经过减少网络规模去避免过拟合。可是咱们以为大型网络更有潜力,不肯意减少规模。
在固定网络规模和固定训练数据大小的时候,咱们还能够选择 Regularization(正则化)技术。
权重衰减是最经常使用的正则化技术,也叫 L2 Regularization(L2 正则)。它的思想是在代价函数中加入一个额外的正则化项。
$$
C = C_0 + \frac{\lambda}{2n} \sum_w w^2
$$
当 $\lambda$ 较小时,咱们偏好最小化原来的代价函数,当 $\lambda$ 较大时,咱们让网络偏好学习更小的 Weights 。
在正则化的网络中应用随机梯度降低算法,对上面的公式求偏导可知:
$$
\frac{\partial C}{\partial w} = \frac{\partial C_0}{\partial w} + \frac{\lambda}{n} w \
\frac{\partial C}{\partial b} = \frac{\partial C_0}{\partial b}
$$
只要照常使用反向传播,并把 $\frac{\lambda}{n} w$ 代入
$$
b \rightarrow b - \eta \frac{\partial C_0}{\partial b} \
w \rightarrow w - \eta \frac{\partial C_0}{\partial w} - \frac{\eta \lambda}{n} w \
= \left(1 - \frac{\eta \lambda}{n}\right) w - \eta \frac{\partial C_0}{\partial w}
$$
咱们看到,跟以前惟一的变化时,咱们用 $\left(1 - \frac{\eta \lambda}{n}\right) $ 来调整 Weights ,这种调叫作 Weight Decay(权重衰减)。
以前咱们的随机梯度降低,时在包含m个训练样本的mini-batch数据中进行平均以估计$\frac{\partial C_0}{\partial w}$,如今对于随机梯度降低法而言正则化的学习方法变成了:
$$
w \rightarrow \left(1 - \frac{\eta \lambda}{n}\right) w - \frac{\eta}{m} \sum_x \frac{\partial C_x}{\partial w} \
b \rightarrow b - \frac{\eta}{m} \sum_x \frac{\partial C_x}{\partial wb}
$$
$\sum$ 是针对mini-batch中全部训练样本进行求和
$C_x$ 是每一个样本未进行正则化的代价
咱们看到,正则化只是增长了权重衰减。
咱们使用 $n = 1000$ 个训练样本再跑一次,此次由30个隐藏层神经元,每一个mini-batch的大小是10,学习率是0.5,使用交叉熵代价函数,正则化参数 $\lambda = 0.1$。使用1000个训练样本。
咱们看到训练数据的代价函数一直在降低,与以前没有进行正则化时同样。
可是从测试数据的准确度,咱们看到应用正则化抑制了过拟合。
准确度也从以前的82.27上升到87.1 。
此次将训练样本增长到 $n=50000$ ,相应的,也须要调整正则化参数 $\lambda = 5$,让权重衰减跟以前保持同样。
咱们以前看到过,对于50000样本量的训练数据,过拟合已经再也不是个大问题了。可是应用正则化后,咱们在测试数据上的准确度从95.49%提高到96.49% 。
从经验来看,正则化让咱们的网络声称得更好,并有效地减弱了过拟合效应。
使用随机 Weights 初始化时,常常卡在代价函数的局部最优中,结果就是每次运行可能产生至关不一样的结果。
而应用了正则化后,每次运行能够提供更容易复现的结果。
通常的说法是:某种程度上,越小的权重复杂度越低,能更简单有效地描绘数据,因此咱们倾向于选择这样的权重。
$$
C = C_0 + \frac{\lambda}{n} \sum_w |w|
$$
咱们再来看下L2正则的代价函数
$$
C = C_0 + \frac{\lambda}{2n} \sum_w w^2
$$
对L1代价函数求偏导
$$
\frac{\partial C}{\partial w} = \frac{\partial C_0}{\partial w} + \frac{\lambda}{n} sgn(w)
$$
$sgn(w)$是取w的符号,当w为正数时,$sgn(w) = +1$。当w为负数时,$sgn(w) = -1$。
对反向传播进行修改,使用基于L1正则化的随机梯度降低进行学习。
$$
w \rightarrow w' = w - \frac{\eta \lambda}{n} sgn(w) - \eta \frac{\partial C_0}{\partial w}
$$
咱们可使用 mini-batch 的均值去估计 $\frac{ \partial C_0}{\partial w}$,
$$
w \rightarrow w' = (1 - \frac{\eta \lambda}{n}) w - \eta \frac{\partial C_0}{\partial w}
$$
咱们再来看下L2正则的:
$$
w \rightarrow w' = \left(1 - \frac{\eta \lambda}{n}\right) w - \frac{\eta}{m} \sum_x \frac{\partial C_x}{\partial w}
$$
L1 和 L2 的共同点是都惩罚大的权重。
L1 中,权值经过一个常量向 0 缩小。
L2中,权值经过一个和 w 成比例的量进行缩小。
结果是,L1 会将权值保留在少许的高重要度的链接上,其它权值会趋向0接近。
L1 和 L2 正则化是对代价函数的修改。Dropout 是改变网络自己。
假设咱们有训练数据 x,和输出 y,通常会经过在网络中正向传播 x 进行训练,再反向传播肯定梯度的贡献。
当使用 Dropout 时:
咱们弃权掉不一样的神经元几何,这样就像是咱们在训练不一样的神经元集合。弃权过程如同大量不一样网络的效果的平均。不一样的网络会以不一样的方式过分拟合,因此弃权过的网络效果会减轻过拟合。
好比咱们训练了五个网络,其中三个把数字分类为3,那极可能就是3了。
在图像、语音识别、天然语言处理时,颇有效。大规模深度网络时也颇有用,由于这样的网络过拟合问题特别突出。
通常咱们认为大量的训练数据会获得更好的性能。
但这个代价很大。有时咱们能够人为扩展训练数据,好比图片5,将其作一个旋转,转换,扭曲,都懂,使用扩展后的训练数据来提高网络的性能。
更多的训练数据能补偿不一样算法的差距。
以前咱们一直用均值为0,标准差为1的独立高斯随机变量来选择权值和偏置。
其实用归一化的高斯分布不是最好的。
跟之前的归一化问题同样,若是权值大,$z$ 也大,$\sigma ( z )$ 就接近 1 或 0,隐藏层神经元会饱和,梯度降低算法学习慢。
以前咱们经过选择不一样的代价函数来解决,但那只是对输出神经元有效,对隐藏神经元不起做用。
假设咱们有一个神经元,它的输入权值是 $n_{in}$,而后咱们用均值是0,标准差是 $\frac{1}{\sqrt{n_{in}}}$ 的高斯随机变量来初始化这些权值。
这样,$z = \sum_j w_j x_j +b$ 的取值更小。
这样的神经元更不容易饱和,也更不可能使学习速度降低。
$\frac{1}{\sqrt{n_{in}}}$ 权值初始化,能够加快训练速度,有时也能提高网络的最终性能。
每一 epoch 的精确度一直降低,可是咱们一开始并不知道哪些超参数应该被调整。
咱们很容易就会迷失方向。这里咱们解释一些启发式的方法,帮助你开发一个工做流,能让你更好地设置超参数。
宽泛策略很差。
$\eta = 0.025$,代价函数平滑降低到最后回合。
$\eta = 2.5$,代价一直震荡。
震荡的缘由是$\eta$太大,使算法在接近最小值时,又越过谷底。
随机梯度降低指望咱们可以逐渐地抵达代价函数的谷底。
学习率太大,代价一直震荡,过小又算法变慢,若是可变学习速度会更好。开始时使用$\eta = 0.25$,接近谷底换成$\eta = 0.025$。
策略是:
在每一个 epoch 结束时,咱们都会在验证数据上计算分类精度。当分类精度再也不提高时,咱们就结束它。Early Stopping 会自动防止过拟合。可是在试验的早期阶段,咱们会关闭 Early Stopping ,这样咱们可以看到任何过拟合的信号,并用这些信息去选择正则化算法。
即便是整体趋势在提高的状况下,咱们也能看到精度在抖动和震荡。若是咱们在精度刚开始降低的时候就终止它,咱们确定会错过更好的模型。一个更好的准则是当最好的分类精度一段时间都没有提高时,再终止它。这样既不会错过什么,也不会等过久。
这里有一个准则:连续十次没有提高就终止。可是网络有时会在很长一段时间内,分类精度很平缓,而后才会有提高。若是你想要得到更好的性能,这个准则就太草率了。
咱们一直将 $\eta$ 设置为常量。一开始,咱们会使用一个大的学习速率,让权值变化地快一点。而后,咱们减少学习速率,这样能够对权值作出更加精良的调整。
一个观点是保持学习速率不变,直到验证数据集精度开始变差时,按照 1/2 或 1/10 去下降学习速率。这样重复几回,直到学习学习速率变为初始值的 1/1000,就中止。