写在前面
- 此文是我学习ML入门的笔记。学习教材《neural networks and deep learning》,作者Michael Nielsen。
- 这是一本免费的书籍,网址在这里。
- 此文是第三章的学习笔记。
- 初学者入门, 可能会有错误,请大家指正。
- 第一章笔记和第二章笔记的链接。
———————————————————————————————————
为什么要改善?
要改善我们之前的神经网络,是因为它存在着以下几个问题:
1. 在一定条件下学习缓慢。
在我们之前用二次代价函数、随机梯度下降和反向传播算法定义的神经网络中,网络的学习速率主要取决于权重的偏导数,其表达式为
因此权重的偏导数正比于S型函数的一阶导数。而其一阶导数的图像如下所示
可以看出,当z的值很大或者很小的时候,学习速率会非常缓慢。
2. 过度拟合(overfitting)/过度训练(overtraining)
如何理解过度拟合呢?
打一个简单的比方:你很喜欢吃土豆丝这道菜,所以妈妈会你如何把土豆去皮切成丝。你每天很勤奋的练习,最后可以切出粗细均匀的完美的土豆丝了。
然后有一天你吃腻了土豆丝,想吃胡萝卜。
但是你看着眼前的胡萝卜,不知道该如何下刀。
因为,切丝这个学习行为,你只能把它运用在土豆这个特定的训练对象上,而不能泛化(generalization) 到其他诸如胡萝卜等的身上,这样的学习是非常无效的。
回到神经网络。
我的理解,过度拟合指的是训练得出的权重、偏置只能在训练数据上得到很好的表现,而在真实数据(如测试数据、验证集)上则无法体现出学习的行为。
过度拟合常常发生在拥有大量自由参数的模型上,比如神经网络。
举个例子。
我们只使用前1000个训练数据,设置400个迭代期,其他条件不变,则得到的代价函数看起来还不错。
但分类准确率在测试集上的表现,就…
过度拟合现象发生了。
3.权重初始化
在前面的学习中,我们对权重的初始化一直是用高斯随机变量,使其被归一化为均值为0,标准差为1。而这种情况下,带权输入z的值会如下分布
可以看出,z的绝对值会很大,所以神经元会趋向饱和。
———————————————————————————————————
如何改善?
1.交叉熵代价函数(cross-entropy cost function)
对于单个如下形式的神经元
其对应的交叉熵代价函数为
其中 n 是训练数据的总数,求和是在所有的训练输⼊ x 上进⾏的,y 是对应的⽬标输出。
而由此计算出的权重的偏导数的形式为
由此避免了学习速率下降的问题。
定义在神经网络上的交叉熵函数的形式为:
可以看成在所有的输出神经元上,对上上式求和。
其权重的偏导数形式为
很好的避免了学习速率下降的问题。
2.柔性最大值(softmax)
柔性最大值的想法是为神经网络定义一种新式的输出层。刚开始在输入层和隐藏层上都是一样的,但是在输出层上应用一种柔性最大值函数作用在带权输入zjL上。根据这个函数,第j个神经元的激活值ajL就是
其中,分母是对所有输出层上的神经元的求和。因此输出层上所有激活值和为1. 换言之,柔性最大层的输出可以用看作是一个概率分布。
3.对数似然代价函数(log-likelihood cost function)
我们使⽤ x 表⽰⽹络的训练输⼊,y 表⽰对应的⽬标输出。然后关
联这个训练输⼊的对数似然代价函数就是
通过代数运算我们可以得到
运用柔性最大值函数与对数似然代价函数的结合,也可以很好的解决学习速率下降的问题。
4.提前停止(early stopping)和hold-out方法
我们之前定义过一个validation_data(验证集),它是从测试集中单独拿出的一批数据,我们还没有使用过它。
现在我们使用验证集来解决过度拟合问题:
在每轮迭代期之后,我们使用validation_data来测试其分类准确率,一旦准确率达到饱和,我们就停止训练。这个策略叫做提前停止。
当然,实际应⽤中,我们不会⽴即知道什么时候准确率会饱和。相反,我们会⼀直训练直到我们确信准确率已经饱和。
就是为何⽤ validation_data 取代 test_data 来设置更好的超参数?因为如果我们设置超参数是基于 test_data 的话,可能最终我们就会得到过度拟合于test_data 的超参数。也就是说,我们可能会找到那些符合test_data 特点的超参数,但是⽹络的性能并不能够泛化到其他数据集合上。我们借助 validation_data 来克服这个问题。然后⼀旦获得了想要的超参数,最终我们就使⽤ test_data 进⾏准确率测量。
换⾔之,你可以将验证集看成是⼀种特殊的训练数据集能够帮助我们学习好的超参数。这种寻找好的超参数的⽅法有时候被称为 hold out ⽅法,因为 validation_data是从traning_data 训练集中留出或者“拿出”的⼀部分。
5. L2规范化(regularization)
所谓的L2规范化,就是在代价函数上增加一个额外的项,这个项叫规范项。下面以交叉熵代价函数举例说明。
规范化后的交叉熵代价函数为
其中第⼀个项就是常规的交叉熵的表达式。第⼆个现在加⼊的就是所有权重的平⽅的和。然后使⽤⼀个因⼦ λ/2n 进⾏量化调整,其中 λ > 0 可以称为规范化参数,⽽ n 就是训练集合的大小。
在这种情况下,求得的权重和偏置的偏导数为
因此每次更新权重时的公式为
这和通常的梯度下降的规则相似,除了通过一个因子(1−ηλ÷n1-ηλ \div n1−η**λ÷n)调整了权重w。这种做法有时也叫做权重下降(weights decay),因为它使权重变得更小。
为什么更小的权重可以减轻过度拟合?
我的理解
- 小的权重在某种程度上,意味着更低的复杂性,也就对数据做出了一种更简单,更强大的解释。
- 更小的权重意味着网络的行为不会因为我们随便改变了一个输入而改变太大,因此能够抵抗训练数据中噪声的影响。
- 小权重神经网络给出的是一个更“一般”而“通用”的解释,能够根据已经学到的内容进行更好的泛化。
6. L1规范化
与L2规范化类似,L1规范化是在在未规范化的代价函数上加上⼀个权重绝对值的和:
在两种情形下,规范化的效果就是缩小权重。但权重缩小的方式不同。
- 在 L1 规范化中,权重通过⼀个常量向 0 进行缩小。
- 在 L2 规范化中,权重通过⼀个和 w 成比例的量进行缩小的。
- 所以,当⼀个特定的权重绝对值 |w| 很⼤时,L1 规范化的权重缩⼩得远⽐ L2 规范化要⼩得多。
- 相反,当⼀个特定的权重绝对值 |w| 很⼩时,L1 规范化的权重缩⼩得要⽐ L2 规范化⼤得多。
- 最终的结果就是:L1 规范化倾向于聚集⽹络的权重在相对少量的⾼重要度连接上,⽽其他权重就会被驱使向 0 接近。
7.弃权(dropout)
原理:随机删除一半的隐藏神经元,用这个‘’新‘’的网络进行学习。
注:输入层和输出层不变。
理解:
- 弃权,是一种构造大量不同神经网络的过程,让数据在不同的网络中学习,最后求平均值。
- 确保模型对一部分证据丢失健壮。
注:
- 输入层和输出层不变
- 最后运用实际整个神经网络时,隐藏神经元的权重要减半。
8.人为扩展训练数据(Artificially expanding the training data)
很容易理解,神经网络的训练数据越多,网络能够学习到的变化就越大,性能自然就越好,但是在真实状态下,好的训练数据是很难拿到的。
但是我们可以人为扩展训练数据。
以手写识别数字为例。
我们的训练数据是MNIST训练图像
将其进行旋转,比如说15度。
这还是会被设别为同样的数字的。但是在像素层级这和任何⼀幅在 MNIST 训练数据中的图像都不相同。所以将这样的样本加⼊到训练数据中是很可能帮助我们的⽹络学会更多如何分类数字。
不只旋转,还可以用转换和扭曲图像来扩展训练数据。
9.权重初始化
我们选用一种新的方法初始化权重。
假设我们有⼀个有 n个输⼊权重的神经元。我们会使⽤均值为 0 标准差为 1/√n的⾼斯随机分布初始化这些权重。
也就是说,我们会向下挤压⾼斯分布,让我们的神经元更不可能饱和。
这样的⼀个神经元更不可能饱和,因此也不⼤可能遇到学习速度下降的问题。
———————————————————————————————————
如何选择神经网络的超参数(hyper-paramets)?
宽泛策略(broad strategy)
1.简化需要解决的问题
丢开训练和验证集合中的那些除了 0 和 1的那些图像。然后试着训练⼀个⽹络来区分 0 和 1。不仅仅问题⽐ 10 个分类的情况简化了,同样也会减少 80% 的训练数据,这样就给出了 5 倍的加速。
2.简化网络来加速实验
如果你相信 [784, 10] 的⽹络更可能⽐随机更加好的分类效果,那么就从这个⽹络开始实验。这会比训练⼀个 [784, 30, 10] 的⽹络更快,你可以进⼀步尝试后⼀个。
3.减少验证图像数
减少每一轮迭代期的验证图像数,能够通过更加频繁的监控准确率而获得反馈。
下面对具体的参数进行分析。
学习速率
首先要清楚,我们使用随机梯度下降算法的目的,是希望我们能够逐渐抵达代价函数谷底的。
- 学习速率太小:会导致学习速率过慢,造成浪费。
- 学习速率过大:可能会导致算法在接近最小值的时候又越过了谷底,造成震荡。
那应该如何设置学习速率呢?
-
我们选择在训练数据上的代价立即开始下降而非震荡或者增加时作为 η 的阈值的估计。
因为此时我们还在“山坡上”,还未到达谷底。
-
如果代价在训练的前⾯若⼲回合开始下降,你就可以逐步地尝试增加 η,直到你找到⼀个 η 的值使得在开始若⼲回合代价就开始震荡或者增加。
为了避免疑惑,我将英文原版书中的原句放在此处。
With this picture in mind, we can set η as follows. First, we estimate the threshold value for η at which the cost on the training data immediately begins decreasing, instead of oscillating or increasing. This estimate doesn’t need to be too accurate. You can estimate the order of magnitude by starting with η=0.01. If the cost decreases during the first few epochs, then you should successively try η=0.1,1.0,… until you find a value for η where the cost oscillates or increases during the first few epochs. Alternately, if the cost oscillates or increases during the first few epochs when η=0.01, then try η=0.001,0.0001,… until you find a value for η where the cost decreases during the first few epochs. Following this procedure will give us an order of magnitude estimate for the threshold value of η. You may optionally refine your estimate, to pick out the largest value of η at which the cost decreases during the first few epochs, say η=0.5 or η=0.2 (there’s no need for this to be super-accurate). This gives us an estimate for the threshold value of η.
使用提前停止来确定训练的迭代期数量
正如我们在前⾯讨论的那样,提前停止表⽰在每个迭代期的最后,我们都要计算验证集上的分类准确率。当准确率不再提升,就终止它。这让选择迭代期数变得很简单。
可变学习速率
我们⼀直都将学习速率设置为常量。但是,通常采⽤可变的学习速率更加有
效。在学习的前期,权重可能⾮常糟糕。所以最好是使⽤⼀个较大的学习速率让权重变化得更快。越往后,我们可以降低学习速率,这样可以作出更加精良的调整。
关于如何设置可变学习速率,⼀种观点是使用提前终止的想法。就是保持学习速率为⼀个常量知道验证准确率开始变差。然后按照某个量下降学习速率,比如说按照 10 或者 2。我们重复此过程若⼲次,直到学习速率是初始值的 1/1024(或者 1/1000)。那时就终止。
规范化参数λ
书作者建议,开始时不包含规范化(λ = 0.0),确定 η 的值。使用确定出来的 η,我们可以使用验证数据来选择好的 λ。从尝试 λ = 1.0 开始,然后根据验证集上的性能按照因子10增加或减少其值。⼀旦我已经找到⼀个好的量级,你可以改进 λ 的值。这⾥搞定后,你就可以返回再重新优化 η。
小批量数据大小(mini-batch size)
首先要指出,我们在网络中是使用矩阵技术来对所有在⼩批量数据中的样本同时计算梯度更新,而不是进行单个循环累加。
- size太小:没有办法发挥矩阵的优势。
- size太大:无法频繁快速的更新权重。
因此我们需要一个折中的方法。
幸运的是,小批量数据大小的选择其实是相对独立的⼀个超参数(网络整体架
构外的参数),所以你不需要优化其他参数来寻找好的小批量数据大小。
所以,使用一个(可以接受的)初始值,然后进行不同小批量数据大小的尝试。画出验证准确率的值随时间(⾮迭代期)变化的图,选择哪个得到最快性能的提升的小批量数据大小。
———————————————————————————————————
其他技术
1.Hessian技术
Hessian技术是一个用来最小化代价函数的方法。
假设 C 是一个有多个参数的函数,w = w1, w2, …,所以 C = C(w)。
因此得到
其中 ∇C 是通常的梯度向量,H就是Hessian矩阵。
运用微积分知识,我们可以得到,当代价函数最小化的时候,Δw的取值为
∆w = -H-1∇C
因此一个优化代价函数的方法如下:
- 选择开始点,w
- 更新 w 到新点 w′ = w -H-1∇C,其中 Hessian H 和 ∇C 是在 w 处计算出来的。
- 不断更新……
缺点:Hessian 矩阵的太⼤了,因此计算 H-1∇C就变得极其困难。
2.基于 momentum 的梯度下降
我们引⼊速度变量 v = v1, v2, . . .,其中每⼀个对应 wj 变 量。
修改梯度下降的更新规则如下:
在这些⽅程中,µ 是⽤来控制阻碍或者摩擦力的量的超参数。
准确地说,你应该将 1 - µ 看成是摩擦力的量。
- 当 µ = 1 时,没有摩擦,速度完全由梯度 ∇C 决定。
- 若是 µ = 0,就存在很⼤的摩擦,速度⽆法叠加,上述公式就变成了通常的梯
度下降。 - 在实践中,使⽤ 0 和 1 之间的 µ 值可以给我们避免过量⽽⼜能够叠加速度的好处。
- 我们可以使⽤ hold out 验证数据集来选择合适的 µ 值,就像我们之前选择 η 和 λ 那样。
———————————————————————————————————
人工神经元的其他模型
1.tanh神经元
表达式:
图像:
2.修正线性神经元(rectified linear neuron)
修正线性神经元(rectified linear neuron)或者修正线性单元(rectified
linear unit),简记为 ReLU。输⼊为 x,权重向量为 w,偏置为 b 的 ReLU 神经元的输出是:max(0, w · x + b)
图像是:
———————————————————————————————————
小总结
这一章讲的内容很杂,提到了改善神经网络的很多技术和方法,以及超参数选择的方法。但是要注意的是,至今没有针对超参数设置的“金科玉律”,很有可能花费了大量的时间和精力,设置出来的参数依旧不满意,要做好准备。