神经网络¶
参数和变量¶
- \(x_i\):输入层(input layer)第 \(i\) 个神经单元的输入值,与输出值相同;
- \(w^l_{ji}\):从第 \(l-1\) 层第 \(i\) 个神经单元指向第 \(l\) 层的第 \(j\) 个神经单元的权重(weight);
- \(b^l_j\):第 \(l\) 层第 \(j\) 个神经单元的偏置(bias);
- \(z^l_j\):第 \(l\) 层第 \(j\) 个神经单元的加权输入;
- \(a^l_j\):第 \(l\) 层第 \(j\) 个神经单元的输出值,当 \(l=1\) 时,有 \(a^1_j=x_j\);
- \(y_j\):输出层(output layer)第 \(j\) 个神经单元的输出值(最终的预测值),有 \(y_j=a^L_j\);
- \(t_j\):输出层第 \(j\) 个神经单元对应的正解;
- \(x_i[k],z^l_j[k],a^l_j[k]\):第 \(k\) 个训练实例的变量值。
每层(除输入层外)神经单元的加权输入,与上一层的神经单元的输出以及之间的权重和偏置有关,设第 \(l-1\) 层有 \(m\) 个神经单元,则其正向传播(forward propagation)如下,
设第 \(l\) 层的神经单元的个数为 \(n\),则两层之间的矩阵表示如下,
可以把偏置设为 \(w_0\),其对应输入为 \(x_0=1\).
激活函数¶
每一个神经单元输出值和输入值之间的关系称为激活函数(activation function),设 \(f\) 为激活函数,则有,
以下是几种常用的激活函数。
Sigmoid 函数¶
ReLU 函数¶
softmax 函数¶
神经网络在处理分类问题时,常使用 softmax 函数作为输出层的激活函数。设输出层有 \(n\) 个神经单元,则 softmax 函数如下,
由上式易知,softmax 函数的输出总和为 \(1\),因此可以将其输出解释为每种输出类别的概率。
在实际计算时,为了防止溢出,通常在指数运算前,加上一个常数 \(C\)(一般取输入值的最大值的负值),即等价于,
损失函数¶
损失函数(cost function)表示神经网络对给定输入的预测值和正解之间的误差程度。
均方误差¶
损失函数的一个例子是均方误差(mean squared error),设输出层有 \(N\) 个神经单元,训练实例总数为 \(K\),则均方误差的计算方式如下,
交叉熵误差¶
损失函数的另一个常用的例子是交叉熵误差(cross entropy error),其计算方式如下,
梯度¶
由多元函数的全部自变量的偏导数汇总而成的向量称为梯度(gradient),设有函数 \(f(x_1,x_2,\mathellipsis,x_n)\),则其梯度表示如下,
数值微分¶
利用微小的差分求偏导数的过程称为数值微分(numerical calculus),计算方式如下,
其中 \(\epsilon\) 是个小数,例如 \(10^{-4}\).
误差反向传播法¶
误差反向传播法(back propagation)的特点是将繁杂的导数计算替换为数列的递推关系式,从而简化梯度求解。设第 \(l\) 层第 \(j\) 个神经单元误差为 \(\delta^{l}_{j}\),定义如下,
根据式 \((1)\) 和链式法则,易知误差对权重和偏置的偏导数如下,
因此,只要求出各个神经单元误差 \(\delta^l_j\),即可得到梯度下降所需的偏导数(梯度)。
设 \(f\) 为激活函数,根据链式法则有,
根据选择的损失函数和激活函数即可求得输出层的神经单元误差。
设第 \(l\) 层有 \(n\) 个神经单元,根据多元函数的链式法则及式 \((1)\) 有,
设第 \(l-1\) 层有 \(m\) 个神经单元,则上述递推关系的矩阵表示如下(其中 \(\odot\) 表示 Hadamard 乘积),
从输出层开始,根据以上递推关系(反向传播)即可依次求得隐藏层的神经单元误差,再代入式\((14)\),从而求得损失函数在当前参数处的梯度。
参数优化¶
神经网络学习的目的是找到使损失函数的值尽可能小的参数。这是寻找最优参数的问题,解决这个问题的过程称为最优化(optimization),以下是几种常见的最优化方法(参数集合记作 \(W\),梯度记作 \(g\))。
随机梯度下降法¶
当参数沿着梯度反方向(反向共线)移动时,误差减小得最快,表示如下,
其中,\(\eta\) 是一个微小的正数,称作学习率。\(\eta\) 是一个超参数(hyper parameter)。
以上参数优化方法称为随机梯度下降法(stochastic gradient descent),简称 SGD。但是在 SGD 中,梯度向量的方向并没有指向最小值的方向,如果函数是各向异性的,则其搜索路径是比较低效的。
动量法(Momentum)¶
其中,\(v\) 对应物理上的速度,随着参数沿着梯度反方向移动,\(v\) 会逐渐增加。
AdaGrad¶
学习率衰减,指的是随着学习的进行,使学习率逐渐减小的方法,这里的学习率减小是针对所有的参数。AdaGrad 进一步发展了这个方法,不同的参数使用不同的学习率,并随着学习而减小。
其中,\(h\) 保存了之前所有梯度值的平方和,然后通过系数 \(\frac{1}{\epsilon + \sqrt{h}}\) 调整每个参数学习的尺度,如果参数变化较大,其学习率也会衰减地较快。\(\epsilon\) 常取 \(10^{-7}\),防止分母为零。
RMSProp¶
在 AdaGrad 算法中,随着学习的进行,\(h\) 会越来越大,导致学习率太低,即 \(\frac{1}{\sqrt{h}}\rarr0\)。一个解决方案是使用 RMSProp 方法,加权计算梯度值的平方和,以更多地反映新的梯度变化,即“指数移动平均”。
其中,\(\rho\) 是指数衰减率,通常取 \(0.9\).
Adam¶
Adam 算法结合了 AdaGrad 和 RMSProp 两个算法的优点,同时考虑了梯度的一阶矩估计(梯度的均值)和二阶矩估计(梯度的方差),
其中,\(\beta_1\) 是一阶矩的指数衰减率,默认为 \(0.9\),\(\beta_2\) 是二阶矩的指数衰减率,默认为 \(0.999\)。训练初期时,\(m_t\) 和 \(v_t\) 偏向零,因此计算 \(\hat{m}_t\) 和 \(\hat{v}_t\) 进行修正。最后根据学习率 \(\alpha\)(默认为 \(0.001\))更新参数。
后三行公式可以修改如下,提高算法效率。
算法¶
- 准备训练数据;
- 初始设置权重 \(w\)、偏置 \(b\) 和学习率 \(\eta\):
- 通常使用随机数作为权重和偏置的初始值;
- 选择适当小的正数作为学习率;
- 学习率的设置大多需要反复试错。同样地,对于权重和偏置的初始值,为了取得好的结果,也可能需要多次变更设置;
- 选择小批量的训练实例,计算出所有神经单元的输出值 \(a\) 以及误差 \(E\):
- 利用式 \((2)\) 和激活函数,正向计算各层神经单元的加权输入 \(z\)、输出值 \(a\);
- 根据选择的损失函数,计算出预测值和正解之间的误差;
- 利用误差反向传播法,反向计算出所有的神经单元误差 \(\delta\),代入式 \((14)\),从而计算出此时的梯度;
- 根据选择的参数优化算法,更新权重和偏置;
- 重复执行第 3~5 步,直至判定误差 \(E\) 的值充分小为止。
权重初始值¶
Xavier 初始值¶
如果前一层的节点数为 \(n\),则当前层的权重初始值使用标准差 \(\frac{1}{\sqrt{n}}\) 的正态分布,此时,各层的输出值 \(a^l_j\) 具有相同广度的分布。
ReLU 初始值¶
当选择 ReLU 作为激活函数时,因为其负值区域的值为零,为了使其更有广度,需要 2 倍的系数,即如果前一层的节点数为 \(n\),则当前层的权重初始值使用标准差为 \(\sqrt{\frac{2}{n}}\) 的正态分布。
BatchNorm¶
在神经网络中,数据分布对学习的影响很大。假设某个神经单元的输入 \(z_j=20\),并选择像 Sigmoid 函数这样的非线性的激活函数,则其输出值 \(a_j\approx 1\),处于激活函数的饱和阶段,即无论 \(z_j\) 再怎么扩大,其输出值变化也很小(只能趋近 \(1\)),或者说神经网络对这个范围的加权输入不敏感了。
为了解决这个问题,Batch Normalization 的思路是对各层的加权输入进行正规化处理,从而使输出值拥有适当的广度。
首先对 mini-batch 的输入的集合 \(B=\{z_1,z_2,\cdots,z_n\}\) 求均值 \(\mu_B\) 和方差 \(\sigma_B^2\),然后对输入进行均值为 \(0\)、方差为 \(1\) 的正规化,最后对正规化后的数据进行缩放和平移变换。初始时,\(\gamma=1,\beta=0\),然后通过学习调整到合适的值。
过拟合 Overfit¶
主要原因有:
- 模型拥有大量参数,表现力强;
- 训练数据少。
权值衰减¶
Dropout¶
在每一个批次的学习过程中,让某个神经元以一定概率停止工作,这样不会太依赖某些局部特征,可以使神经网络泛化性更强,也明显地减少过拟合现象。
假设某个神经元的输出为 \(a\),其输出期望也为 \(a\),在加上 Dropout 后,这个神经元有 \(p\) 的概率失活,则其输出期望变为了 \((1-p)*a+p*0=(1-p)a\),为了保证这个神经元在训练阶段(有 Dropout)和测试阶段(无 Dropout)的输出期望一致,有以下两种方式:
- 训练时,将该神经元的输出缩放 \(\frac{1}{1-p}\) 倍,即 \(\frac{1}{1-p}((1-p)*a+p*0)=a\);
- 测试时,将该神经元的输出缩放 \((1-p)\) 倍,其输出期望变为 \((1-p)a\).
Note
Dropout 其实等效于集成学习,即让多个模型单独进行学习,推理时再取各个模型输出的平均值。
超参数¶
- 设定超参数的范围(对数尺度),例如 \(0.01-100\);
- 从该范围中随机采样,并进行学习,通过验证数据评估识别精度(epoch 需要设置得很小);
- 多次重复上一步骤,根据识别的精度,缩小超参数的范围;
- 缩小到一定程度后,从中选择一个超参数的值。
参考¶
- 涌井良幸, 涌井贞美. 深度学习的数学.
- 斋藤康毅. 深度学习入门:基于 Python 的理论与实现.
- 吴恩达机器学习系列课程
- Adam: A Method for Stochastic Optimization.
- Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift.