对于MLP这样的最简单的,输入层的神经元数等于输入向量的维度。每个神经元接收向量中的一个值,进行加权求和;训练的是这里的参数,即权重和偏置。
某一层的输出,1*n,传递到下一层。 $y_i=\sum W_{ji} x_j +b=\sum W_{ji} x_{1j}+b=\sum W_{ij}^T x_{1j}+b $,
维数分别为$y:n1, x: m1,W: mn,b:n1?$。这里是全连接神经网络,每一个输入神经元和每一个输出神经元都有联系。并且是完全线性的。
$y=W^T X+b$,y:[n,1],x:[m,1];W:[m,n]
偏置b,对于每一层神经网络来说是一个常数(不对,和输出y是维度一样的),不同层可以取不同值。
偏置项充当了激活函数输入的常数补偿,使得神经元的激活可以在输入为零时仍然有非零响应。换句话说,它允许网络“平移”激活函数,而不仅仅是围绕原点展开。如果没有偏置项,每个神经元的激活函数都会被迫经过原点,这在很多情况下会限制模型的表达能力。
偏置项作为自由参数同样参与反向传播,它能够独立于输入的数值进行调节,使得整个网络更容易摆脱陷入局部极值或收敛到次优解的风险,从而提高训练效果。
此时,如果不考虑激活函数,没有必要添加隐藏层,因为都是线性变换,多个线性变换乘起来也还是线性变换。
所以每一层的输出传递到下一层之后需要乘上非线性的激活函数,再作为下一层的输入。
激活函数:
- RELU;求导是阶跃函数,0或者1,很方便;解决了梯度消失问题(反向传播时候,参数的更新是前一层梯度和该层激活函数导数的乘积,而sigmoid和tanh的激活函数导数很小)。当输入小于等于0时,ReLU输出为0,这造成了网络中一部分神经元不激活,从而实现了稀疏性,有时能带来更好的泛化能力。
- sigmoid;和Tanh一样,把输出压缩到(0,1);非均匀的压缩,平滑;在输出层多用,在隐藏层很少用;输入接近0的时候,接近线性变换,值=1,导数=0.25;
- tanh,关于原点中心对称.
另外,神经网络的信息不一定是要按部就班一层一层地传递的,可以跳。
- 残差神经网络,Resnet,核心贡献在于通过引入残差学习(Residual Learning)解决了深度网络训练中的梯度消失和梯度爆炸问题,使得网络可以训练得更深,性能更强。通过残差连接(residual connections)或快捷连接(shortcut connections)允许网络中的信号直接跳过某些层级,从而创建残差块(Residual Block)。
负反馈:梯度下降。这种方法几乎可以优化所有深度学习模型。 它通过不断地在损失函数递减的方向(梯度)上更新参数来降低误差。更新参数的快慢速度是learning rate。可以更新的参数是权重矩阵W和bias b。在训练一个小批量的样本后更新,这个小批量的样本数目是batch size.
需要定义损失函数。利用差的平方来定义,有系数1/2,为了方便对于损失函数求导(这样系数可以是1了)
$L(n)=\frac 1 n \frac 1 2 \sum_n (W^T x+b-y)^2,W:mn ; x:m1; b:n1常数列向量;y:n1; L(n)=\frac 1 n \frac 1 2 \sum_n \sum_i (\sum_j W_{ij}^T x_j+b-y_i)^2$
这里都是最后一层,y是神经网络最后一层的总输出。n是batch size。这里平方其实是对求差得到是n*1的结果进行的。
$\partial L/\partial W^T_{ij}=\frac 1 n \sum n (\sum_i \sum_j (W^T{ij} x_j+b-y_i)x_j) $,等于$\partial L/\partial W_{ji}=\frac 1 n \sum n (\sum_i \sum_j (W{ji} x_j+b-y_i)x_j) $
由于此时应该是[n,m]维的,所以x[m,1],y[n,1],所以此时应该是两个列向量外积。这也是会用到外积的地方。
这个对于Wij求导,$\partial L/\partial W_{ji}=\frac 1 n \sum n (\sum_i \sum_j (W{ji} x_j+b-y_i)x_j) $,现在所有的都拆成数了。并且注意,求导的时候要把$W_{ij}^T换回W_{ji}$,因为是对Wij求导. 或者,$\partial L/\partial W_{ij}=\frac 1 n \sum n (\sum_i \sum_j (W{ij} x_i+b-y_j)x_i)=\frac 1 n \sum n (\sum_i \sum_j (W{ji}^T x_i+b-y_j)x_i) =\frac 1 n \sum_n \sum_i \sum_j (W^T_{ij}x_j+b-y_j)x_i=\frac 1 n \sum_n \sum_i \sum_j x_i (W^T_{ij}x_j+b-y_j)$,此时应该看成两个列向量的外积,$M_{ij}=u_i v_j$.写成外积的时候经常可以不写明运算符。
$\partial L/\partial bi’=\frac 1 n \sum n (\sum_i \sum_j (W{ij}^T x_j+b_i-y_i))\delta_{ii’}$,即$\partial L/\partial b_i=\frac 1 n \sum_n \sum_j (W_{ij}^T x_j+b_i-y_i)=\frac 1 n \sum_n (W^Tx+b-y)_i $
这样完成了输出层的权重和bias的更新。之后把这一层作为新的输出层,往前逐渐更新每一层的权重W和bias。这个就是反向传播。
如果考虑到激活函数的贡献,还需要包含对于激活函数的求导,看这里。可以看成,W^Tx+b=z, v=f(z),f是激活函数,每一层的可以不一样。$L(n)=\frac 1 n \frac 1 2 \sum_n (f(W^T x+b)-y)^2=\frac 1 n \frac 1 2 \sum_n \sum_i (f(W^T x+b)i-y_i)^2$,$\partial L/\partial W{ij}=\frac 1 n \sum n \sum_i (f(z)-y)i \frac {\partial f(z_i)} {\partial W{ij}}) $,$\partial f(z_i)/\partial W{ij}=\frac {\partial f(z_i)}{\partial z_i }*\frac { \partial z_i }{\partial W_{ij}}=f’(z_i){\partial W_{ij}} $,
所以会出来$\partial L/\partial W_{ji}=\frac 1 n \sum_n \sum_i \sum_j x_i f’(z_j)(f(z_j)-y_j), z=W^T x+b,v=f(z)$.例如损失函数对于Wij求导,外积的第一个部分是xi,外积的另外部分就是$(z-y)_j*f(z_j)$。
同理,$\partial L/\partial b_i=\frac 1 n \sum_n (z-y)_i *f’(z)_i$
这里没有明显写出$\partial C/\partial a$,因为这个很明显,z对应直接的输出,a是激活之后的输出,$C=\frac 1 {2n} \sum_n (a-y)^2,\partial C/\partial a=\frac 1 n \sum_n (a-y) $,很好计算,所以就没写出来。
这里损失函数对于b的偏导和对于z的偏导一样,这个很好看出,z=b+wa这样的。并且损失函数对于W,b的偏导具体是多少,可以求出,上面有用向量形式写明。
总流程是,
- 就,先根据我推出的公式的计算方法,获得最后一层的$\partial C/\partial b=\delta_j^L$,然后更新最后一层的参数W b,再然后往前传播根据这里的关系,更新往前一层的$\delta_j^{L-1}$,更新这一层的参数,…
- 或者,直接按照这个图的流程就行,$\partial C/\partial a$很好求出。
- 以上似乎是假设求导结果是1.可能是RELU.
batch批量大小和学习率learning rate的值通常是手动预先指定,而不是通过模型训练得到的。 这些可以调整但不在训练过程中更新的参数称为超参数(hyperparameter)。 调参(hyperparameter tuning)是选择超参数的过程。 超参数通常是我们根据训练迭代结果来调整的, 而训练迭代结果是在独立的验证数据集(validation dataset)上评估得到的。
线性回归恰好是一个在整个域中只有一个最小值的学习问题。 但是对像深度神经网络这样复杂的模型来说,损失平面上通常包含多个最小值。 深度学习实践者很少会去花费大力气寻找这样一组参数,使得在训练集上的损失达到最小。 事实上,更难做到的是找到一组参数,这组参数能够在我们从未见过的数据上实现较低的损失, 这一挑战被称为泛化(generalization)。
但是,即使我们的函数确实是线性的且无噪声,这些估计值也不会使损失函数真正地达到最小值。 因为算法会使得损失向最小值缓慢收敛,但却不能在有限的步数内非常精确地达到最小值。