用一个三层神经网络计算一个窗口的得分
维度分析:如果我们使用 4 维的词向量来表示每个单词并使用 5 个词的窗口,则输入是 x∈ 。如果我们在隐藏层使用 8 个 sigmoid 单元和从激活函数中生成一个分数输出,其中 W∈
, b∈
, U∈
, s∈R 。
使用SGD更新参数:
上节课有提到,在更新参数是时计算 ∇θJ(θ)的方法
- 手工计算
- 算法:反向传播
1.手工推导
1.1 导数链:
对于单变量函数:乘以导数
对于一次处理多个变量:乘以雅可比矩阵
由于使用的是 element-wise,所以 hi=f(zi)
函数有n个输出和n个输入 → n×n 的雅可比矩阵
1.2 推导
- 把方程分解成简单的片段
- 计算
- 计算
遵循惯例:导数的形状是参数的形状 (形状约定)
的形状是 n×m
因为 z=Wx+b,这表明
Why the Transposes?
- 粗糙的回答是:这样就可以解决尺寸问题了
- 检查工作的有用技巧
- 课堂讲稿中有完整的解释
- 每个输入到每个输出——得到的是外部积
What shape should derivatives be?
-
是行向量
但是习惯上说梯度应该是一个列向量因为 b 是一个列向量
- 雅可比矩阵形式(这使得链式法则很容易)和形状约定(这使得SGD很容易实现)之间的分歧
我们希望答案遵循形状约定
但是雅可比矩阵形式对于计算答案很有用
- 两个选择
1)尽量使用雅可比矩阵形式,最后按照约定进行整形
我们刚刚做的。但最后转置 使导数成为列向量,得到
2)始终遵循惯例
查看维度,找出何时转置 和/或 重新排序项。
2.反向传播
反向传播是一种利用微分链式法则来计算模型上任意参数的损失梯度的方法。
具体推导可参考:https://blog.youkuaiyun.com/transformer_WSZ/article/details/90321864
3.神经网络中的Tips and Tricks
3.1Gradient Check(梯度检查)
一种用数值近似梯度的方法——虽然在计算上的低效不能直接用于训练神经网络,这种方法可以非常准确地估计任何参数的导数;因此,它可以作为对导数的正确性的有用的检查。
其中 ϵ 是一个很小的值(一般约为 1e−5 )。当我们使用 +ϵ 扰动参数 θ 的第 i 个元素时,就可以在前向传播上计算误差 。相似地,当我们使用 −ϵ 扰动参数 θ 的第 i 个元素时,就可以在前向传播上计算误差
。因此,计算两次前向传播,我们可以估计在模型中任意给定参数的梯度。
可以看出每次估算梯度都需要计算两次,当很多大规模的神经网络含有几百万的参数,对每个参数都计算两次明显不是一个好的选择,其计算量将非常巨大,因此该方法不适用与直接训练神经网络。
3.2 Regularization(正则化)
神经网络很容易过拟合,这令到模型在训练集上能获得近乎完美的表现,但是却不能泛化到测试集上。一个常见的用于解决过拟合(“高方差问题”)的方法是使用 L2 正则化。我们只需要在损失函数 J 上增加一个正则项,现在的损失函数如下:
在上面的公式中,是矩阵
(在神经网络中的第 i 个权值矩阵)的 Frobenius 范数, λ 是超参数控制损失函数中的权值的大小。
当我们尝试去最小化 ,正则化本质上就是当优化损失函数的时候,惩罚数值太大的权值(让权值的数值分配更加均衡,防止出现部分权值特别大的情况)。由于 Frobenius 范数的二次的性质(计算矩阵的元素的平方和), L2 正则项有效地降低了模型的灵活性和因此减少出现过拟合的可能性。
有时候我们会用到其他类型的正则项,例如 L1 正则项,它将参数元素的绝对值全部加起来-然而,在实际中很少会用 L1 正则项,因为会令权值参数变得稀疏。
3.3 Dropout
这个想法是简单而有效的——训练过程中,在每次的前向/反向传播中我们按照一定概率 (1−p) 随机地“ drop ”一些神经元子集(或者等价的,我们保持一定概率 p 的神经元是激活的)。然后,在测试阶段,我们将使用全部的神经元来进行预测。使用 Dropout 神经网络一般能从数据中学到更多有意义的信息,更少出现过拟合和通常在现今的任务上获得更高的整体表现。这种技术应该如此有效的一个直观原因是, dropout 本质上作的是一次以指数形式训练许多较小的网络,并对其预测进行平均。
3.4 Neuron Units
常见的激活函数可见之前总结的神经网络激活函数
3.5 Parameter Initialization(参数初始化)
让神经网络实现最佳性能的关键一步是以合理的方式初始化参数。一个好的起始方法是将权值初始化为通常分布在 0 附近的很小的随机数-在实践中效果还不错。
3.6 Learning Strategies
训练期间模型参数更新的速率/幅度可以使用学习率进行控制。在最简单的梯度下降公式中, α 是学习率:
避免损失函数难以收敛的一个简答的解决方法是使用一个很小的学习率,让模型谨慎地在参数空间中迭代——当然,如果我们使用了一个太小的学习率,损失函数可能不会在合理的时间内收敛,或者会困在局部最优点。因此,与任何其他超参数一样,学习率必须有效地调整。
还有其他已经被证明有效的技术-这个方法叫 annealing 退火,在多次迭代之后,学习率以以下方式降低:保证以一个高的的学习率开始训练和快速逼近最小值;当越来越接近最小值时,开始降低学习率,让我们可以在更细微的范围内找到最优值。一个常见的实现 annealing 的方法是在每 n 次的迭代学习后,通过一个因子 x 来降低学习率 α 。
还有另外一种方法是允许学习率随着时间减少:
α0 是一个可调的参数,代表起始的学习率。 τ 也是一个可调参数,表示学习率应该在该时间点开始减少。
3.7 Momentum Updates¶
动量方法,灵感来自于物理学中的对动力学的研究,是梯度下降方法的一种变体,尝试使用更新的“速度”的一种更有效的更新方案。
3.8 Adaptive Optimization Methods
AdaGrad 是标准的随机梯度下降( SGD )的一种实现,但是有一点关键的不同:对每个参数学习率是不同的。每个参数的学习率取决于每个参数梯度更新的历史,参数的历史更新越小,就使用更大的学习率加快更新。换句话说,过去没有更新太大的参数现在更有可能有更高的学习率。
其他常见的自适应方法有 RMSProp 和 Adam
-
RMSProp 是利用平方梯度的移动平局值,是 AdaGrad 的一个变体——实际上,和 AdaGrad 不一样,它的更新不会单调变小。
-
Adam 更新规则又是 RMSProp 的一个变体,但是加上了动量更新。