- 作者:韩信子 @ShowMeAI
- 教程地址:http://www.showmeai.tech/tutorials/35
- 本文地址:http://www.showmeai.tech/article-detail/218
- 申明:版权所有,转载请分割平台与作者并注明出处
珍藏 ShowMeAI 查看更多精彩内容
本系列为吴恩达老师《深度学习专项课程 (Deep Learning Specialization)》学习与总结整顿所得,对应的课程视频能够在 这里 查看。
引言
在 ShowMeAI 前一篇文章 神经网络优化算法 中咱们对以下内容进行了介绍:
- batch/mini-batch/ Stochastic gradient descent
- 指数加权均匀 (Exponentially weighted averages) 和偏移校对(bias correction)
- 动量梯度降落、RMSprop 和 Adam 算法
- 学习率衰减法
- 部分最优的概念及论断
本篇咱们将重点开展介绍超参数调试、BN(Batch Normalization 批归一化)和深度学习编程框架三个局部的内容。
1. 超参数调试解决
深度神经网络须要调试的 超参数 (Hyperparameters) 较多,咱们来看看如何对其调试。
1.1 重要水平排序
吴恩达老师后面讲到过的超参数中,重要水平顺次是(仅供参考):
最重要:
- 学习率 \(\alpha\)
其次重要:
- \(\beta\):动量衰减参数,常设置为 0.9
- \(n^{[l]}\):各暗藏层神经元个数(#hidden units)
- Mini-Batch 的大小
再次重要:
- \(\beta_1\),\(\beta_2\),\(\varepsilon\):Adam 优化算法的超参数,常设为 0.9、0.999、\(10^{-8}\)
- \(L\):神经网络层数(#layers)
- decay_rate:学习衰减率
1.2 调参技巧
咱们上面来看看神经网络的超参数抉择与调试办法。在传统的机器学习中,咱们对每个参数等间隔选取任意个数的点,而后,别离应用不同点对应的参数组合进行训练,最初依据验证集上的体现好坏,来选定最佳的参数。
例如有两个待调试的参数 Hyperparameter 1 和Hyperparameter 2,在每个参数上别离平均距离选取 \(5\) 个点,这样形成了 \(5 \times 5=25\) 种参数组合,如图所示。这种做法在参数比拟少的时候成果较好。
然而在深度神经网络模型中,咱们个别不采纳这种平均距离取点的办法,比拟好的做法是应用随机抉择。也就是说,对于下面这个例子,咱们随机抉择 25 个点,作为待调试的超参数,如下图所示:
随机化抉择参数的目标是为了尽可能地失去更多种参数组合。还是下面的例子,如果应用平均采样的话,每个参数只有 5 种状况;而应用随机采样的话,每个参数有 25 种可能的状况,因而更有可能失去最佳的参数组合。
这种做法带来的另外一个益处就是 对重要性不同的参数之间的抉择成果更好。假如 hyperparameter1 为 \(\alpha\),hyperparameter2 为 \(\varepsilon\),显然二者的重要性是不一样的。
- 如果应用第一种 平均采样 的办法,\(\varepsilon\) 的影响很小,相当于只抉择了 5 个 \(\alpha\) 值。
- 如果应用第二种 随机采样 的办法,\(\varepsilon\) 和 \(\alpha\) 都有可能抉择 25 种不同值。这大大增加了 \(\alpha\) 调试的个数,更有可能抉择到最优值。
其实,在理论利用中齐全不晓得哪个参数更加重要的状况下,随机采样的形式能无效解决这一问题,然而平均采样做不到这点。
在通过随机采样之后,咱们可能失去某些区域模型的体现较好。然而,为了失去更准确的最佳参数 ,咱们应该持续对选定的区域进行 由粗到细的采样(coarse to fine sampling scheme)。也就是放大体现较好的区域,再对此区域做更密集的随机采样。例如,对图中右下角的方形区域再做 25 点的随机采样,以获得最佳参数。
综上,超参调试过程的技巧总结如下:
- ① 随机抉择点(而非平均选取),用这些点试验超参数的成果。这样做的起因是咱们提前很难晓得超参数的重要水平,能够通过抉择更多值来进行更多试验;
- ② 由毛糙到精密:聚焦成果不错的点组成的小区域,在其中更密集地取值,以此类推;
1.3 抉择适合的范畴
上一段讲到应用随机采样调试超参数,对于某些超参数是能够进行尺度平均采样的,然而某些超参数须要抉择不同的适合尺度进行随机采样。举例来说:
① 对于 超参数 (#layers) 和(#hidden units),都是正整数,是能够进行平均随机采样的,即超参数每次变动的尺度都是统一的(如每次变动为 1,犹如一个刻度尺一样,刻度是平均的)。
② 对于 超参数 \(\alpha\) ,待调范畴是 \([0.0001, 1]\)。
- 如果应用平均随机采样,那么有 90% 的采样点散布在 \([0.1, 1]\) 之间,只有 10% 散布在 \([0.0001, 0.1]\) 之间。这在理论利用中是不太好的,因为最佳的 \(\alpha\) 值可能次要散布在 \([0.0001, 0.1]\) 之间,而 \([0.1, 1]\) 范畴内 \(\alpha\) 值成果并不好。
- 咱们更关注的是区间 \([0.0001, 0.1]\),应该在这个区间内细分更多刻度。
对于非平均采样,一种罕用的做法是 将 linear scale 转换为 log scale,将平均尺度转化为非平均尺度,而后再在 log scale 下进行平均采样。这样,\([0.0001, 0.001]\)、\([0.001, 0.01]\)、\([0.01, 0.1]\)、\([0.1, 1]\) 各个区间内随机采样的超参数个数基本一致,也就扩充了之前 \([0.0001, 0.1]\) 区间内采样值个数。
咱们以重要参数 学习率 和动量衰减参数 为例:
- 对于学习率 \(\alpha\),用对数标尺而非线性轴更加正当:0.0001、0.001、0.01、0.1 等,而后在这些刻度之间再随机平均取值;
- 对于动量衰减参数 \(\beta\),取 0.9 就相当于在 10 个值中计算平均值,而取 0.999 就相当于在 1000 个值中计算平均值。能够思考给 \(1-\beta\) 取值,这样就和取学习率相似了。
上述操作的起因是当 \(\beta\) 靠近 1 时,即便 \(\beta\) 只有渺小的扭转,所得后果的灵敏度会有较大的变动。例如,\(\beta\) 从 0.9 减少到 0.9005 对后果 \((1/(1-\beta\) ))简直没有影响,而 \(\beta\) 从 0.999 到 0.9995 对后果的影响微小(从 1000 个值中计算平均值变为 2000 个值中计算平均值)。
1.4 一些倡议
(1) 深度学习现在曾经利用到许多不同的畛域。不同的利用呈现互相融合的景象,某个应用领域的超参数设定有可能通用于另一畛域。不同应用领域的人也应该更多地浏览其余钻研畛域的 paper,跨畛域地寻找灵感。
(2) 思考到数据的变动或者服务器的变更等因素,倡议每隔几个月至多一次,从新测试或评估超参数,来取得实时的最佳模型;
(3) 依据你所领有的计算资源来决定你训练模型的形式:
- Panda(熊猫形式):在在线广告设置或者在计算机视觉应用领域有大量的数据,但受计算能力所限,同时试验大量模型比拟艰难。能够采纳这种形式:试验一个或一小批模型,初始化,试着让其工作运行,察看它的体现,一直调整参数;
- Caviar(鱼子酱形式):领有足够的计算机去平行试验很多模型,尝试很多不同的超参数,选取成果最好的模型;
2.Batch Normalization
Sergey Ioffe 和 Christian Szegedy 两位学者在 paper 中提出了 批标准化 (Batch Normalization,常常简称为 BN) 办法。Batch Normalization 不仅能够让调试超参数更加简略,而且能够让神经网络模型更加「强壮」。也就是说较好模型可承受的超参数范畴更大一些,包容性更强,使得更容易去训练一个深度神经网络。
接下来,咱们就来介绍什么是 Batch Normalization,以及它是如何工作的。
之前,咱们对输出特色 \(X\) 应用了标准化解决。咱们也能够用同样的思路解决暗藏层的激活值 \(a^{[l]}\),以减速 \(W^{[l+1]}\) 和 \(b^{[l+1]}\) 的训练。在实践中,常常抉择标准化暗藏层输出 \(Z^{[l]}\),这里咱们对第 \(l\) 层隐层做如下解决:
其中,\(m\) 是单个 Mini-Batch 所蕴含的样本个数,\(\varepsilon\) 是为了避免分母为零,通常取 \(10^{-8}\)。
咱们来从「样本 」和「 通道」维度对上述 BN 环节做一个可视化开展详解,对于某一层 \(N \times D\) 的输出,咱们上述操作的计算过程如下图所示。(留神其中 \( i\) 为样本维度,\(j\) 为通道维度)
在通过上述解决前后的数据分布如下图所示,咱们能够看到这个解决对数据的「Normalization」影响。
这样,咱们使得所有的输出 \(z^{(i)}\) 均值为 0,方差为 1。但咱们不想粗犷地让解决后的暗藏层单元间接变为均值 0 方差 1,这样本来学习到的数据分布就被间接抹掉了。因而,咱们引入可学习参数 \(\gamma\) 和 \(\beta\),对 \(z_{norm}^{(i)}\) 进行线性变换,如下:
其中,\(\gamma\) 和 \(\beta\) 都是模型的学习参数,所以能够用各种梯度降落算法来更新 \(\gamma\) 和 \(\beta\) 的值,如同更新神经网络的权重一样。
通过对 \(\gamma\) 和 \(\beta\) 的正当设置,能够让 \(\tilde z^{(i)}\) 的均值和方差为任意值。这样,咱们对暗藏层的 \(z^{(i)}\) 进行标准化解决,用失去的 \(\tilde z^{(i)}\) 代替 \(z^{(i)}\)。
公式中设置可学习参数 \(\gamma\) 和 \(\beta\) ,起因是如果各暗藏层的输出均值在凑近 0 的区域,即处于激活函数的线性区域,不利于训练非线性神经网络,从而失去成果较差的模型。因而,须要用 \(\gamma\) 和 \(\beta\) 对标准化后的后果做进一步解决。
2.1 将 BN 利用于神经网络
下面解说了对某繁多隐层的所有神经元进行 BN 批归一化的办法,总结示意图如下:
接下来咱们钻研一下如何把 Bath Norm 利用到整个神经网络中,对于 L 层神经网络,通过 Batch Normalization 的作用,整体流程如下:
实际上,Batch Normalization 常常应用在 Mini-Batch 上,这也是其名称的由来。
应用 Batch Normalization 时,因为标准化解决中蕴含减去均值的一步,因而 \(b\) 实际上没有起到作用,其数值成果交由 \(\beta\) 来实现。因而,在 Batch Normalization 中,能够省略 \(b\) 或者临时设置为 0。
在应用梯度降落算法时,别离对 \(W^{[l]}\),\(\beta^{[l]}\) 和 \(\gamma ^{[l]}\) 进行迭代更新。
除了传统的梯度降落算法之外,也同样能够应用 ShowMeAI 上一篇文章 神经网络优化算法 提到的动量梯度降落、RMSProp 或者 Adam 等优化算法。
2.2 BN 无效的起因
Batch Normalization 成果很好的起因有以下两点:
- 通过对暗藏层各神经元的输出做相似的标准化解决,进步神经网络训练速度;
- 能够使后面层的权重变动对前面层造成的影响减小,整体网络更加强壮。
对于第二点,如果理论利用样本和训练样本的数据分布不同 (如下图中的黑猫图片和橘猫图片),咱们称产生了「Covariate Shift」。这种状况下,个别要对模型进行从新训练。Batch Normalization 的作用就是减小 Covariate Shift 所带来的影响,让模型变得更加强壮,鲁棒性(Robustness) 更强。
即便输出的值扭转了,因为 Batch Normalization 的作用,使得均值和方差放弃不变(由 \( \gamma\) 和 \(\beta\) 决定),限度了在前层的参数更新对数值散布的影响水平,因而后层的学习变得更容易一些。Batch Normalization 缩小了各层 \(W\) 和 \(b\) 之间的耦合性,让各层更加独立,实现自我训练学习的成果。
另外,Batch Normalization 也起到强劲的正则化 (regularization) 成果。因为在每个 Mini-Batch 而非整个数据集上计算均值和方差,只由这一小部分数据预计得出的均值和方差会有一些噪声,因而最终计算出的 \(\tilde z^{(i)}\) 也有肯定噪声。相似于 Dropout,这种噪声会使得神经元不会再特地依赖于任何一个输出特色。
因为 Batch Normalization 只有强劲的正则化成果,因而能够和 Dropout 一起应用,以取得更弱小的正则化成果。通过利用更大的 Mini-Batch 大小,能够缩小噪声,从而缩小这种正则化成果。
吴恩达老师也揭示大家,不要将 Batch Normalization 作为正则化的伎俩,而是当作减速学习的形式。正则化只是一种非冀望的副作用,Batch Normalization 解决的还是反向流传过程中的梯度问题(梯度隐没和爆炸)。
2.3 测试阶段的 Batch Normalization
Batch Normalization 将数据以 Mini-Batch 的模式逐个解决,但在测试时,可能须要对每一个样本逐个解决,这样无奈失去 \(\mu\) 和 \(\sigma^2\)。
实践上,咱们能够将所有训练集放入最终的神经网络模型中,而后将每个暗藏层计算失去的 \(\mu^{[l]}\) 和 \(\sigma^{2[l]}\) 间接作为测试过程的 \(\mu\) 和 \(\sigma\) 来应用。然而,理论利用中个别不应用这种办法,而是应用之前学习过的指数加权均匀的办法来预测测试过程单个样本的 \(\mu\) 和 \(\sigma^2\)。
对于第 \(l\) 层暗藏层,思考所有 Mini-Batch 在该暗藏层下的 \(\mu^{[l]}\) 和 \(\sigma^{2[l]}\),而后用指数加权均匀的形式来预测失去以后单个样本的 \(\mu^{[l]}\) 和 \(\sigma^{2[l]}\)。这样就实现了对测试过程单个样本的均值和方差预计。
3.Softmax 回归
目前为止,介绍的分类例子都是二分类问题:神经网络输入层只有一个神经元,示意预测输入 \(\hat{y}\) 是正类的概率 \(P(y = 1 \mid x)\),\(\hat{y}> 0.5\) 则判断为正类,反之判断为负类。
对于 多分类问题,用 \(C\) 示意品种个数,则神经网络输入层,也就是第 \(L\) 层的单元数量 \(n^{[L]} = C\)。每个神经元的输入顺次对应属于该类的概率,即 \(P(y=c \mid x),c=0,1,…,C-1\)。有一种 Logistic 回归的个别模式,叫做 Softmax 回归,能够解决多分类问题。
对于 Softmax 回归模型的输入层,即第 \(L\) 层,有:\(Z^{[L]} = W^{[L]}a^{[L-1]} + b^{[L]}\)
for i in range(L)
,有:\(a^{[L]}_i = \frac{e^{Z^{[L]}_i}}{\sum^C_{i=1}e^{Z^{[L]}_i}}\)
为输入层每个神经元的输入,对应属于该类的概率,满足:\(\sum^C_{i=1}a^{[L]}_i = 1\)
一个直观的计算例子如下:
下图为一些softmax 线性分类器失去的分类边界
3.1 损失函数和老本函数
咱们来看看 softmax 分类器的损失函数,这里定义其 损失函数 为:\(L(\hat y, y) = -\sum^C_{j=1}y_jlog\hat y_j\)
当 \(i\) 为样本实在类别,则有:\(y_j = 0, j \ne i\)
因而,损失函数能够简化为:\(L(\hat y, y) = -y_ilog\hat y_i = log \hat y_i\)
所有 \(m\) 个样本的老本函数为:\(J = \frac{1}{m}\sum^m_{i=1}L(\hat y, y)\)
3.2 梯度降落法
多分类的 Softmax 回归模型与二分类的 Logistic 回归模型只有输入层上有一点区别。通过不太一样的推导过程,仍有
$$
dZ^{[L]} = A^{[L]} – Y
$$
反向流传过程的其余步骤也和 Logistic 回归的统一。
参考资料:Softmax 回归 – Ufldl
4. 深度学习框架
4.1 比拟驰名的框架
- Caffe / Caffe2
- CNTK
- DL4J
- Keras
- Lasagne
- mxnet
- PaddlePaddle
- TensorFlow
- pytorch
4.2 抉择框架的规范
- 便于编程:包含神经网络的开发和迭代、配置产品;
- 运行速度:特地是训练大型数据集时;
- 是否真正凋谢:不仅须要开源,而且须要良好的治理,可能继续凋谢所有性能。
5.Tensorflow
目前最火的深度学习框架之一是来自 google 的 Tensorflow。上面简略做一个介绍。(更多的 TensorFlow 实战办法,请参考)
Tensorflow 框架内能够间接调用梯度降落算法,极大地升高了编程人员的工作量。例如以下代码:
import numpy as np
import tensorflow as tf
cofficients = np.array([[1.],[-10.],[25.]])
w = tf.Variable(0,dtype=tf.float32)
x = tf.placeholder(tf.float32,[3,1])
# Tensorflow 重载了加减乘除符号
cost = x[0][0]*w**2 + x[1][0]*w + x[2][0]
# 扭转上面这行代码,能够换用更好的优化算法
train = tf.train.GradientDescentOptimizer(0.01).minimize(cost)
init = tf.global_variables_initializer()
session = tf.Session()
session.run(init)
for i in range(1000):
session.run(train, feed_dict=(x:coefficients))
print(session.run(w))
打印为 4.99999,根本能够认为是咱们须要的后果。更改 cofficients 的值能够失去不同的后果 w。
上述代码中:
session = tf.Session()
session.run(init)
print(session.run(w))
也能够写作:
with tf.Session() as session:
session.run(init)
print(session.run(w))
with 语句实用于对资源进行拜访的场合,确保不论应用过程中是否产生异样都会执行必要的「清理」操作,开释资源,比方文件应用后主动敞开、线程中锁的主动获取和开释等。
想理解更多 Tensorflow 无关常识,请参考 官网文档。
参考资料:
- Softmax 回归 – Ufldl
- Tensorflow 官网文档
ShowMeAI 系列教程举荐
- 图解 Python 编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解 AI 数学根底:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学习算法:从入门到精通系列教程
- 机器学习实战:手把手教你玩转机器学习系列
- 深度学习教程 | 吴恩达专项课程 · 全套笔记解读
举荐文章
- 深度学习教程 | 深度学习概论
- 深度学习教程 | 神经网络根底
- 深度学习教程 | 浅层神经网络
- 深度学习教程 | 深层神经网络
- 深度学习教程 | 深度学习的实用层面
- 深度学习教程 | 神经网络优化算法
- 深度学习教程 | 网络优化:超参数调优、正则化、批归一化和程序框架
- 深度学习教程 | AI 利用实际策略(上)
- 深度学习教程 | AI 利用实际策略(下)
- 深度学习教程 | 卷积神经网络解读
- 深度学习教程 | 经典 CNN 网络实例详解
- 深度学习教程 | CNN 利用:指标检测
- 深度学习教程 | CNN 利用:人脸识别和神经格调转换
- 深度学习教程 | 序列模型与 RNN 网络
- 深度学习教程 | 自然语言解决与词嵌入
- 深度学习教程 | Seq2seq 序列模型和注意力机制