zl程序教程

您现在的位置是:首页 >  硬件

当前栏目

机器学习:神经网络向前/后传播的基本原理与运算(以多元分类问题为例)

机器学习神经网络 分类 运算 为例 传播 基本原理
2023-09-27 14:28:32 时间

为什么要有神经网络

我们已经学会了线性回归和逻辑回归,它们在拟合曲线与划分类别方面的表现都还不错,为什么我们还需要神经网络呢?因为在许多应用场景中,特征值的数量远超之前练习中的规模,一张灰度图就包含成千上万的像素点信息,对于这样的问题,光是一次项就有成千上万个,若再考虑高次项,矩阵的大小将超出算法的承受范围。因此,我们需要可以更有效表示复杂多项式的工具——神经网络。

神经网络的基本结构

输入数据的一层为输入层,输出结果的一层为输出层,中间都是隐藏层(可以没有,也可以有不只一层)。
在这里插入图片描述
除了输入节点和由输入运算得到的节点 x 1 − 3 , a 1 − 3 x_{1-3},a_{1-3} x13,a13一般还会在网络中加入偏置,即 x 0 , a 0 x_0,a_0 x0,a0

我们定义 L L L为网络层数, s l s_l sl为第 l l l层的节点个数。 a i ( j ) a_i^{(j)} ai(j)为第 j j j层第 i i i个单元的值,而 Θ ( j ) \Theta^{(j)} Θ(j)表示从第 j j j层向第 j + 1 j+1 j+1层的转移矩阵,其中 Θ p q ( j ) \Theta_{pq}^{(j)} Θpq(j)表示从 a q ( j ) a_q^{(j)} aq(j) a p ( j + 1 ) a_p^{(j+1)} ap(j+1)转移的权值,因此 Θ ( j ) \Theta^{(j)} Θ(j)的大小为 s j + 1 × ( s j + 1 ) s_{j+1}\times (s_j+1) sj+1×(sj+1)

神经网络中的运算

正向传播

单个列向量传播

在输入层后续的节点中,我们都引入了逻辑函数 g ( z ) = 1 1 + e − z g(z)=\frac{1}{1+e^{-z}} g(z)=1+ez1,转移的代数形式为
a i ( j + 1 ) = g ( ∑ k = 0 s j Θ i k ( j ) a k ( j ) ) a_i^{(j+1)}=g\left(\sum_{k=0}^{s_j}\Theta_{ik}^{(j)}a_k^{(j)} \right) ai(j+1)=g(k=0sjΘik(j)ak(j))

在改进后的神经网络中,我们不再使用逻辑函数,因为其在远大于0的区域非常平缓,梯度很小所以收敛速度也很慢。一种改进是使用类似SVM中的曲线,叫做ReLU函数,大概长下面这样:
在这里插入图片描述
< 0 <0 <0时ReLU函数恒为0;而 > 0 >0 >0时,ReLU函数斜率恒为1,使得梯度下降能一直保持一个不慢的下降速率。不过这已经涉及到后面深度学习的内容了,本文还是按吴恩达讲的来,用逻辑函数。

很显然,层与层之间的转移可以写成矩阵运算形式,令
Θ ( j ) = [ Θ 10 ( j ) Θ 11 ( j ) ⋯ Θ 1 s j ( j ) Θ 20 ( j ) Θ 21 ( j ) ⋯ Θ 2 s j ( j ) ⋮ ⋮ ⋱ ⋮ Θ s j + 1 0 ( j ) Θ s j + 1 1 ( j ) ⋯ Θ s j + 1 s j ( j ) ] , a ( j ) = [ a 1 ( j ) a 2 ( j ) ⋮ a s j ( j ) ] \Theta^{(j)}= \left[\begin{matrix} \Theta_{10}^{(j)}&\Theta_{11}^{(j)}&\cdots&\Theta_{1s_j}^{(j)}\\ \Theta_{20}^{(j)}&\Theta_{21}^{(j)}&\cdots&\Theta_{2s_j}^{(j)}\\ \vdots&\vdots&\ddots&\vdots\\ \Theta_{s_{j+1}0}^{(j)}&\Theta_{s_{j+1}1}^{(j)}&\cdots&\Theta_{s_{j+1}s_j}^{(j)}\\ \end{matrix}\right], a^{(j)}= \left[\begin{matrix} a_1^{(j)}\\ a_2^{(j)}\\ \vdots\\ a_{s_{j}}^{(j)}\\ \end{matrix}\right] Θ(j)=Θ10(j)Θ20(j)Θsj+10(j)Θ11(j)Θ21(j)Θsj+11(j)Θ1sj(j)Θ2sj(j)Θsj+1sj(j),a(j)=a1(j)a2(j)asj(j)
s j + 1 × ( s j + 1 ) s_{j+1}\times (s_j+1) sj+1×(sj+1) Θ ( j ) \Theta^{(j)} Θ(j)乘上 ( s j + 1 ) × 1 (s_j+1)\times1 (sj+1)×1 a ( j ) a^{(j)} a(j)在套用逻辑函数就可以得到 a ( j + 1 ) a^{(j+1)} a(j+1)完成一次从 j j j层到 j + 1 j+1 j+1层的转移。注意这里 a ( j ) a^{(j)} a(j)在运算之前要在加上偏置单位 a 0 a_0 a0,一般 a 0 = 1 a_0=1 a0=1

矩阵传播

输入数据也有可能不止一个列向量,而是包含了多组数据的矩阵,令 x i ( j ) x_i^{(j)} xi(j)表示第 j j j组数据中第 i i i个特征值,输入矩阵 X X X m × s 1 m\times s_1 m×s1矩阵
X = [ x 1 ( 1 ) x 2 ( 1 ) ⋯ x s 1 ( 1 ) x 1 ( 2 ) x 2 ( 2 ) ⋯ x s 1 ( 2 ) ⋮ ⋮ ⋱ ⋮ x 1 ( m ) x 2 ( m ) ⋯ x s 1 ( m ) ] X= \left[\begin{matrix} x_{1}^{(1)}&x_{2}^{(1)}&\cdots&x_{s_1}^{(1)}\\ x_{1}^{(2)}&x_{2}^{(2)}&\cdots&x_{s_1}^{(2)}\\ \vdots&\vdots&\ddots&\vdots\\ x_{1}^{(m)}&x_{2}^{(m)}&\cdots&x_{s_1}^{(m)}\\ \end{matrix}\right] X=x1(1)x1(2)x1(m)x2(1)x2(2)x2(m)xs1(1)xs1(2)xs1(m)
此时,要进行向前传播运算,则先在 X X X矩阵左侧增加一列 x 0 = 1 x_0=1 x0=1,再乘以参数矩阵的转置,通过逻辑函数得到下一层,通用的矩阵算式为
a ( j + 1 ) = g ( [ 1 a ( j ) ] Θ ( j ) T ) a^{(j+1)}=g([1\quad a^{(j)}]\Theta^{(j)T}) a(j+1)=g([1a(j)]Θ(j)T)
这样做的好处是, a ( j ) a^{(j)} a(j)矩阵始终是 m m m行的,对应 m m m个样本,添加偏置只需要在左侧加一列 m × 1 m\times1 m×1 1 1 1向量就可以了,不过每次参数矩阵都要专职一下。

如此一直到输出层,找到每行最大值所在索引,就能知道每个样本被分到哪一类了。

反向传播

代价函数

正向传播是利用已有参数进行预测,要优化参数则需要反向传播,这时也要用到代价函数的概念。令 K = s L K=s_L K=sL为输出层的单元个数,一般为分类问题中种类的个数,则代价函数为
J ( Θ ) = − 1 m ∑ i = 1 m ∑ k = 1 K [ y k ( i ) log ⁡ ( ( h Θ ( x ( i ) ) ) k ) + ( 1 − y k ( i ) ) log ⁡ ( 1 − ( h Θ ( x ( i ) ) ) k ) ] + λ 2 m ∑ l = 1 L − 1 ∑ i = 1 s l ∑ j = 1 s l + 1 ( Θ j i ( l ) ) 2 J(\Theta)=-\frac{1}{m}\sum_{i=1}^m\sum_{k=1}^K[y_k^{(i)}\log((h_\Theta(x^{(i)}))_k)+(1-y_k^{(i)})\log(1-(h_\Theta(x^{(i)}))_k)]+\frac{\lambda}{2m}\sum_{l=1}^{L-1}\sum_{i=1}^{s_l}\sum_{j=1}^{s_{l+1}}(\Theta_{ji}^{(l)})^2 J(Θ)=m1i=1mk=1K[yk(i)log((hΘ(x(i)))k)+(1yk(i))log(1(hΘ(x(i)))k)]+2mλl=1L1i=1slj=1sl+1(Θji(l))2
看起来很复杂,实际上只是把正则化逻辑回归代价函数的拟合程度部分扩展到了 K K K类,把正则项扩展到了 L L L层的所有矩阵。可以与正则化逻辑回归代价函数比对起来观察:
J ( θ ) = − 1 m ∑ i = 1 m [ y log ⁡ ( h θ ( x ⃗ ) ) + ( 1 − y ) log ⁡ ( 1 − h θ ( x ⃗ ) ) ] + λ 2 m ∑ j = 1 n θ j 2 J(\theta)=-\frac{1}{m}\sum_{i=1}^m\left[y\log(h_\theta(\vec{x}))+(1-y)\log(1-h_\theta(\vec{x}))\right] +\frac{\lambda}{2m}\sum_{j=1}^n\theta_j^2 J(θ)=m1i=1m[ylog(hθ(x ))+(1y)log(1hθ(x ))]+2mλj=1nθj2

计算误差

既然要修正,首先就要定义误差, δ j ( l ) \delta_j^{(l)} δj(l)表示第 l l l层第 j j j个单元的误差。显然,对于输出层,就有 δ j ( L ) = a j ( L ) − y j \delta_j^{(L)}=a_j^{(L)}-y_j δj(L)=aj(L)yj,向量化之后就是 δ ( L ) = a ( L ) − y \delta^{(L)}=a^{(L)}-y δ(L)=a(L)y

得到了输出层的误差,接下来就要反推之前所有隐藏层的误差了(输入层无误差)。大致的思路是误差乘以参数矩阵传递一下再乘以逻辑函数的倒数,即
δ ( l ) = ( ( Θ ( l ) ) T δ ( l + 1 ) ) . ∗ g ′ ( z ( l ) ) \delta^{(l)}=((\Theta^{(l)})^T\delta^{(l+1)}).*g'(z^{(l)}) δ(l)=((Θ(l))Tδ(l+1)).g(z(l))
其中, a ( l ) = g ( z ( l ) ) a^{(l)}=g(z^{(l)}) a(l)=g(z(l)),故
g ′ ( z ( l ) ) = e − z ( l ) ( 1 + e − z ( l ) ) 2 = 1 1 + e − z ( l ) . ∗ ( 1 − 1 1 + e − z ( l ) ) = a ( l ) . ∗ ( 1 − a ( l ) ) g'(z^{(l)})=\frac{e^{-z^{(l)}}}{(1+e^{-z^{(l)}})^2}=\frac{1}{1+e^{-z^{(l)}}}.*(1-\frac{1}{1+e^{-z^{(l)}}})=a^{(l)}.*(1-a^{(l)}) g(z(l))=(1+ez(l))2ez(l)=1+ez(l)1.(11+ez(l)1)=a(l).(1a(l))
最终得到的误差传播公式为
δ ( l ) = ( ( Θ ( l ) ) T δ ( l + 1 ) ) . ∗ a ( l ) . ∗ ( 1 − a ( l ) ) \delta^{(l)}=((\Theta^{(l)})^T\delta^{(l+1)}).*a^{(l)}.*(1-a^{(l)}) δ(l)=((Θ(l))Tδ(l+1)).a(l).(1a(l))

计算梯度

定义 Δ i j ( l ) : = Δ i j ( l ) + a j ( l ) δ i ( l + 1 ) \Delta_{ij}^{(l)}:=\Delta_{ij}^{(l)}+a_j^{(l)}\delta_i^{(l+1)} Δij(l):=Δij(l)+aj(l)δi(l+1),矩阵运算形式为
Δ ( l ) : = Δ ( l ) + δ ( l + 1 ) ( a ( l ) ) T \Delta^{(l)}:=\Delta^{(l)}+\delta^{(l+1)}(a^{(l)})^T Δ(l):=Δ(l)+δ(l+1)(a(l))T
将误差与单元激励值相乘并累加后,经过一系列很复杂以至于吴恩达没讲的推导以后,我们就得到了梯度的表达式:
∂ ∂ Θ i j ( l ) J ( Θ ) = D i j ( l ) = { 1 m ( Δ i j ( l ) + λ Θ i j ( l ) ) j ≠ 0 1 m Δ i j ( l ) j = 0 \frac{\partial}{\partial\Theta_{ij}^{(l)}}J(\Theta)=D_{ij}^{(l)}=\left\{ \begin{aligned} &\frac{1}{m}(\Delta_{ij}^{(l)}+\lambda\Theta_{ij}^{(l)})&&j\not=0\\ &\frac{1}{m}\Delta_{ij}^{(l)}&&j=0\\ \end{aligned}\right. Θij(l)J(Θ)=Dij(l)=m1(Δij(l)+λΘij(l))m1Δij(l)j=0j=0
注意 j = 0 j=0 j=0为偏置,不参与正则化,故没有正则项。

综上,每次我们用已有参数进行一次向前传播,再进行一次向后传播修改参数,如此迭代多次就可以得到一个较准确的模型了。