超参数调整
前面已经看到在神经网络调试过程中需要涉及很多的超参数,那么如何系统性的调整这些参数以快速的达到更好的学习效果?Andrew 的建议是按照以下的优先级:
α: 永恒重要,是训练中重点调整的对象之一
隐藏单元的数量、 mini-batch 的容量大小,如果采用动量梯度,那么 β 也是可以考虑的参数(一般取 0.9)
层数、学习率下降相关参数,同时如果采用 Adam,默认选择 β1 = 0.9 ,β2 = 0.999,ε = 10-8 即可
实际的参数选择过程可以先在预计有效的取值范围内采取随机测试的方式,再集中在表现较好的参数附近进一步细化选取:
对于单元数量和层数这类整数值的选取可采用随机均匀取值
对于学习率这类小数如果可能取值在 0.0001 - 1 之间则一般推荐按照 10 倍数量级的方式随机选取,例如可以令
r = -4 * np.random.rand()
,再令 α = 10 r对于 β 如果取值在 0.9 - 0.999 之间则可以令 1 - β = 10r ,再参照 α 的计算方式进行选择
输出的批量标准化 Batch Normalization
正如前面标准化输入可以改善学习速度一样,我们在使用 mini-batch 进行训练的时候同样可以通过标准化每一层的输出来进一步提高学习效率。这里的输出可以指应用了激活函数后的输出值 a[ l ],也可以指未应用激活函数的 z[ l ],在本课中 Andrew 使用的是对于 z[ l ] 的标准化,对于任意一层:
先对每一个 z( i ) 做标准化 znorm( i ) = (z( i ) - μ) / sqrt(σ2 + ε),ε 是为了防止除 0 而做的一个安全设置,同时这个参数还可以起到放大样本方差的作用。公式中的 μ 和 σ 是训练时的一个 mini-batch 的输出在激活前的 μ 和 σ
因为这一处理的结果会使得 z( i ) 呈(0, 1)分布,如果其取值严格遵循随机分布,在使用 ReLU 作为激活函数的时候会导致一半左右的 ReLU 失活,因此实际应用中需要代替 z( i ) 的是 z( i ) = γznorm( i ) + β,这里的 γ, β 是需要通过学习获得的参数,其作用同 w 和 b 类似都是实现了对输入的缩放
在应用中可以采用梯度下降法,通过 γ = γ - αγ, β = β - αβ 的方式更新这两个参数,并且 Batch Normalization 可以结合动量梯度下降、RMSprop 、Adam 等优化方法来加速学习。
另外一点需要注意的是,对 z( i ) 的标准化过程实际上会消除掉 b 这个参数的影响,因此在采用 Batch Normalization 的时候,可以省去 b 这个参数。
经过 Batch Normalization 的处理,使得每一个隐藏层的输出的分布情况得到了控制,后续层的学习就建立在更加坚实的基础上,因此使得学习得到的参数对于输入的波动耐受程度更高,使得整个网络更加稳健。
测试时的 Batch Normalization
由于在测试的时候样本的输入很可能是一个样本一个样本的方式进行的,而对于单一样本来说算法中的标准化处理部分求均值,方差,再做标准化并没有意义。因此在实际测试中是将前面采用 mini-batch 进行训练的到的每一个小批量的 μ 和 σ 做指数加权平均得到总体的 μ 和 σ,再用这两个参数对于测试样本进行标准化计算 znorm( i ) = (z( i ) - μ) / sqrt(σ2 + ε) 和 z( i ) = γznorm( i ) + β。
关于 Batch Normalization,更详细的解释可以参考 R2RT 的博客 和 Udacity 的这个练习。
Softmax 回归
前面学习的 Logistic 回归只能处理二元分类问题,实际应用中很多时候输出值可以有多个不同的分类,这个时候就要采用 Softmax 回归。
Softmax 回归最显著的特征就是输出层不再是一个单元,而是一个列向量,其维数为对应的分类种类,且每一个数值代表其取相应分类的概率,其计算过程如下:
在输出层首先计算 z[ L ] = w[ L ]a[ L-1 ] + b[ L ],这里依据之前的约定 L 大写代表输出层
之后在该层应用 softmax 激活函数:先对 z[ L ] 做基于元素的幂运算,即 t = ez[L],再将这个向量求和,然后取得每一个元素与求和的比值。
Softmax 函数之所以如此命名是对应的有一个叫 Hardmax 的函数,会将上述的输出结果中最大值转化为 1,其他值均转化为 0,而 Softmax 则会保留各个计算值。
Softmax 回归可以视作 Logistic 回归的一个泛化,当最终的分类为二元分类的时候,可以通过数学证明其等同于 Logistic 回归。由于最终的输出值不再是单一的一个值,因此 softmax 回归有单独的损失函数定义:
L(ŷ, y) = - ∑yj logŷj ,其中 j = 1, ... ,C,C 为最终的分类数
对应的成本函数为:
J = ∑L(ŷ(i), y(i)) / m,其中 i = 1, ... ,m,m 为样本的数量
在 python 中 softmax 函数的实现方式如下:
import numpy as np
def softmax(z):
exp_z = np.exp(z)
sum_of_z = np.sum(exp_z)
return exp_z / sum_of_z
神经网络的应用框架
神经网络的应用框架使得大家可以无需每做一个项目都从头开始,节省了大量的工作时间。同时需要注意到不同的框架都有其擅长处理的领域,所以在选择框架的时候 Andrew 建议大家注意以下几点:
是否易于开发和部署
运行速度是否够快
是否真正的开源