0%

Part1-神经网络学习

Part1-神经网络学习

代价函数

假设我们有一个与图片有类似的神经网络结构

训练集为:\(\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),\cdots,(x^{(m)},y^{(m)}) \}\)

符号表示:

L:网络层数

\(s_l\):第L层的单元数(不包括偏置单元数)

对于二分类问题:

\(y=0或1\)

有一个输出单元:

\(h_\Theta(x) \in \mathbb R\)

\(S_L=1简化为:K=1\)

对于多分类问题(K类):

\(y\in \mathbb R^K\)

有K个输出单元

\(h_\Theta(x) \in \mathbb R^k\)

\(S_L=K \ (K\ge 3)\)

代价函数

逻辑回归中代价函数:

\(J(\theta) = -\frac{1}{m}[\sum_{i=1}^my^{(i)}\log h_\theta(x^{(i)})+(1-y^{(i)})\log(1-h_\theta(x^{(i)}))]+\frac{\lambda}{2m}\sum_{j=1}^n \theta_j^2\)

在神经网络中:

\(h_\Theta(x)\in \mathbb R^K \ (h_\Theta(x))_i=第i个输出\)

\(\begin{split} J(\Theta) &=-\frac{1}{m}[\sum_{i=1}^m\sum_{k=1}^Ky_k^{(i)}\log(h_\Theta(x^{(i)}))_k+(1-y^{(i)}_k)\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 \end{split}\)

反向传播算法

\(\begin{split} J(\Theta) &=-\frac{1}{m}[\sum_{i=1}^m\sum_{k=1}^Ky_k^{(i)}\log(h_\Theta(x^{(i)}))_k+(1-y^{(i)}_k)\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 \end{split}\)

要使得\(\min_\Theta J(\Theta)\)

则需要计算:

  • \(J(\Theta)\)

  • \(\frac{\partial}{\partial\Theta_{ij}^{(l)}}J(\Theta)\) \((\Theta_{ij}^{(l)}\in \mathbb R)\)

梯度计算

假设给定训练样本\((x,y)\),神经网络结果如图,则:

前向传播(向量化形式): \[ \begin{split} a^{(1)} &= x\\ z^{(2)} &= \Theta^{(1)}a^{(1)}\\ a^{(2)} &= g(z^{(2)}) \ \ (加上a_0^{(2)})\\ z^{(3)} &= \Theta^{(2)}a^{(2)}\\ a^{(3)} &= g(z^{(3)}) \ \ (加上a_0^{(3)})\\ z^{(4)} &= \Theta^{(3)}a^{(3)}\\ a^{(4)} &= h_\Theta(x)=g(z^{(4)}) \end{split} \] 反向传播:

反向传播的直观解释:对每个结点计算:\(\delta_j^{(l)}\):表示第\(l\)层第\(j\)个结点的误差

对于每个输出单元(L=4):

\(\delta_j^{(4)}=a_j^{(4)}-y_j\) \((a_j^{(4)} \Leftrightarrow (h_\Theta(x))_j)\)

也就是:\(\delta^{(4)}=a^{(4)}-y(每个都是向量,并且向量维数等于输出单元的数目)\)

\(\delta^{(3)}=(\Theta^{(3)})^T\delta^{(4)}.*g'(z^{(3)})\)

\(\delta^{(2)}=(\Theta^{(2)})^T\delta^{(3)}.*g'(z^{(2)})\)

\((其中.*表示点乘)\)

\(g'(z^{(i)})=a^{(i)}.*(1-a^{(i)})(表示求导)\)

其中,没有\(\delta^{(1)}\),因为第一层对应输入层

\(\frac{\partial}{\partial\Theta_{ij}^{(l)}}J(\Theta)=a_j^{(l)}\delta_i^{(l+1)}(忽视标准化项,即\lambda=0)\)

反向传播算法总结

训练集:\(\{(x^{(1)},y^{(1)}),\cdots,(x^{(m)},y^{(m)}) \}\)

  1. 设置\(\Delta_{ij}^{l}=0 \ (对于所有的l,i,j)\) (用来计算偏导项:\(\frac{\partial}{\partial \Theta_{ij}^{(l)}}J(\Theta)\))

  2. 遍历:

    对于\(i\)从1到m:

    ​ 设置:\(a^{(1)}=x^{(i)}\)

    ​ 对于\(l=2,3,\cdots,L\),前向传播计算每层(不包括输入层)的激活值\(a^{(l)}\)

​ 使用\(y^{(i)}\),计算\(\delta^{(L)}=a^{(L)}-y^{(i)}\)

​ 计算\(\delta^{(L-1)},\delta^{(L-2)},\cdots,\delta^{(2)}\)

\(\Delta_{ij}^{(l)}:=\Delta_{ij}^{(l)}+a_j^{(l)}\delta_i^{(l+1)}(向量化:\Delta^{(l)}:=\Delta^{(l)}+\delta^{(l+1)}(a^{(l)})^T)\)

​ 如果\(j \ne 0\)\(D_{ij}^{(l)}:=\frac{1}{m}\Delta_{ij}^{(l)}+\lambda\Theta_{ij}^{(l)}\)

​ 如果\(j=0\)\(D_{ij}^{(l)}:=\frac{1}{m}\Delta_{ij}^{(l)}\)

\(\frac{\partial}{\partial\Theta_{ij}^{(l)}}J(\Theta)=D_{ij}^{(l)}\)

理解反向传播

如图:

在进行前向传播时,我们将样本\((x^{(i)},y^{(i)})\)输入到网络中,将\(x^{(i)}\)传到输入层中,因此可以将它们表示成\(x_1^{(i)},x_2^{(i)}\),对其进行正向传播,传播到第一个隐藏层时,我们计算出\(z^{(2)}_1\)\(z_2^{(2)}\),然后通过激活函数计算出\(a_1^{(2)}\)\(a_2^{(2)}\),然后继续前向传播,计算出\(z_1^{(3)}\)\(z_2^{(3)}\),再通过激函数计算出\(a_1^{(2)}\)\(a_2^{(2)}\),同理计算出\(z_1^{(4)}\)\(a_1^{(4)}\)

将图中一些权重标注出来,如\(\Theta_{10}^{(2)},\Theta_{11}^{(2)},\Theta_{12}^{(2)}\)(\(\Theta_{10}^{(2)}:(2):表示第2层;1:表示下一列的第1个;0:表示这一列的第0个\))

\(z_1^{(3)}=\Theta_{10}^{(2)}\times1+\Theta_{11}^{(2)}a_1^{(2)}+\Theta_{12}^{(2)}a_1^{(2)}\)\(a_1^{(3)}=g(z_1^{(3)})\)


如图:

注明:

\(\begin{split} J(\Theta) &=-\frac{1}{m}[\sum_{i=1}^m\sum_{k=1}^Ky_k^{(i)}\log(h_\Theta(x^{(i)}))_k+(1-y^{(i)}_k)\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 \end{split}\)

对于某个样本,1个输出单元,并且忽略正则项\((\lambda=0)\)则:

\(cost(i)=y^{(i)} \log h_\Theta(x^{(i)})+(1-y^{(i)})\log(1-h_\Theta(x^{(i)}))\)

\(\delta_j^{(l)}=\frac{\partial}{\partial z^{(l)}_j}cost(i)\)

在进行反向传播时

计算\(\delta_1^{(4)}=a_1^{(4)} - y^{(i)}\),然后反向传播计算出前一层的\(\delta_1^{(3)},\delta_2^{(3)}\),同理计算出\(\delta_1^{(2)},\delta_2^{(2)}\),而具体计算以\(\delta_2^{(3)}\)为例,过程如下:标定参数\(\Theta^{(2)}_{12},\Theta_{22}^{(2)}\),则\(\delta_2^{(2)}=\Theta_{12}^{(2)}\delta_1^{(3)}+\Theta_{22}^{(2)}\delta_2^{(3)}\),同理\(\delta_2^{(3)}=\Theta_{12}^{(3)}\delta_1^{(4)}\),但整个过程中实际上是省略了一部分的,因为按照前面所学的,\(\delta\)的计算过程应当是:\(\delta^{(l)}=(\Theta^{(l)})^T\delta^{(l+1)}.*g'(z^{(l)})\)

梯度检测

梯度的数值估计

假设有一个代价函数\(J(\Theta)\),对应的有一个\(\theta \in \mathbb R\),如果想估计\(\theta\)在函数上对应的导数,则该导数就是函数在该点切线的斜率,从数值上来求近似导数则首先需要计算\(\theta+\epsilon\),然后计算\(\theta-\epsilon\),然后需要将这两个值对应的点用直线连起来,则连线的斜率就是所求的该点导数的近似值,而这个连线的斜率就是该段的垂直高度除以该段的水平宽度,则高度差为\(J(\Theta+\epsilon)-J(\Theta-\epsilon)\),而宽度差为\(2\epsilon\),所以\(\frac{d}{d\Theta}J(\Theta) \approx \frac{J(\Theta+\epsilon)-J(\Theta-\epsilon)}{2\epsilon}\)\(\epsilon=10^{-4}\)

对于参数向量\(\theta\)\(\theta \in \mathbb R^{n},\theta=[\theta_1,\theta_2,\cdots,\theta_n]\) \[ \frac{\partial}{\partial \theta_1}J(\theta)\approx\frac{J(\theta_1+\epsilon,\theta_2,\cdots,\theta_n)-J(\theta_1-\epsilon,\theta_2,\cdots,\theta_n)}{2\epsilon} \\ \frac{\partial}{\partial \theta_2}J(\theta)\approx\frac{J(\theta_1,\theta_2+\epsilon,\cdots,\theta_n)-J(\theta_1,\theta_2-\epsilon,\cdots,\theta_n)}{2\epsilon} \\ \cdots \\ \frac{\partial}{\partial \theta_n}J(\theta)\approx\frac{J(\theta_1,\theta_2,\cdots,\theta_n+\epsilon)-J(\theta_1,\theta_2,\cdots,\theta_n-\epsilon)}{2\epsilon} \] 最后检查是否有:\(导数值\approx反向传播计算出的导数值\)

总结:

  • 使用反向传播计算DVec(展开后就是\(D^{(1)},D^{(2)},D^{(3)}\))
  • 使用梯度检验来计算gradApprox
  • 确保DVec和gradApprox都能得出相似的值
  • 在进行正式的反向传播学习前,关闭梯度检验(因为其计算量很大,耗时)

随机初始化

初始化\(\Theta\)的值,考虑梯度下降:

一种初始化方法是将其全部设为0,尽管在逻辑回归中这样做是可以的,但实际上在训练网络时,将所有参数初始化为0是不可行的。

如图,以图中对应的神经网络为例:

如果将所有参数都初始化为0,这就意味着所有参数一样,也就会导致\(a_1^{(2)}\)\(a_2^{(2)}\)都是以同一输入函数来计算,于是,对于所有训练样本,总会得到\(a_1^{(2)}=a_2^{(2)}\),也会得到\(\delta_1^{(2)}=\delta_2^{(2)}\),同时也会使得\(\frac{\partial}{\partial \Theta_{01}^{(1)}}J(\Theta)=\frac{\partial}{\partial \Theta_{03}^{(1)}}J(\Theta)\),这样,即使更新参数后,也会有\(\Theta_{01}^{(1)}=\Theta_{02}^{(1)}\)

所以,每次更新后,这两个隐藏单元的每个参数输入都是相等的,也就是每个输入单元输出的两条线对应的权重仍然相等,这就意味着即使梯度下降进行了一次迭代,仍然有\(a_1^{(2)}=a_2^{(2)}\),这也就意味着这个神经网络得不出比较有用的函数。

以上问题也被称为对称权重问题,也就是所有的权重都是一样的。

因此,在神经网络模型中,在对参数进行初始化时,需要使用随机初始化思想。

整合

训练一个神经网络

在训练一个神经网络时,我们要做的第一件事,就是选择一种网络架构 ,这个架构指的是神经元之间的连接模式,如图,可能是以下几种架构中的一种:

那么,我们该如何进行选择呢?

  1. 定义输入单元的数量:即特征的维度\(x^{(i)}\)
  2. 定义输出单元的数量:如果是多分类问题,则就是对应的类别数量
  3. 对于隐藏层单元个数和隐藏层的数目,一个合理的默认选项是只使用单个隐藏层,或者如果使用不上一个隐藏层的话,则默认每个隐藏层通常都应有相同的单元数,而对于隐藏单元的个数,通常是越多越好的,但多了也会导致计算量增大。并且通常来说,每个隐藏层的单元数量应该与输入x的维度相匹配,即和特征数目相匹配

训练的实现步骤

  1. 随机初始化权重,通常初始化为很小的接近于零的值

  2. 实现前向传播算法,计算对于任一\(x^{(i)}\)\(h_\Theta(x^{(i)})\)

  3. 代码实现计算代价函数\(J(\Theta)\)

  4. 实现反向传播算法来计算偏导项\(\frac{\partial}{\partial\Theta_{jk}^{(l)}}J(\Theta)\)

  5. 使用梯度检查来比较使用反向传播计算的\(\frac{\partial}{\partial\Theta_{jk}^{(l)}}J(\Theta)\)和使用梯度数值估计求出的\(J(\Theta)\)对应的偏导数值

    关闭梯度检查

  6. 使用梯度下降或其它优化算法和反向传播算法结合,计算\(J(\Theta)\)最小时对应的参数\(\Theta\)