9.1 神经网络损失函数
神经网络数据集: ( x ( 1 ) , y ( 1 ) ) , ( x ( 2 ) , y ( 2 ) ) , . . . , ( x ( m ) , y ( m ) ) {(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})} (x(1),y(1)),(x(2),y(2)),...,(x(m),y(m))
神经网络层数: L L L
第 l l l层的神经元数( l l l层特征数): s l s_l sl(不包括偏差特征)
cost function:
∑ i = 1 m \sum^m_{i=1} ∑i=1m: 样本从1到m的累加
∑ k = 1 K \sum_{k=1}^K ∑k=1K: 输出类别从1到K的累加
∑ l = 1 L − 1 \sum^{L-1}_{l=1} ∑l=1L−1: 神经网络从第1层到第L-1层的累加
∑ i = 1 s l \sum_{i=1}^{s_l} ∑i=1sl: 第 l l l层神经网络中的神经元从1到 s l s_l sl的累加
∑ j = 1 s l + 1 \sum^{s_l+1}_{j=1} ∑j=1sl+1: 第 l l l层中第 i i i个神经元的特征 θ i j \theta_{ij} θij从 j = 0 j=0 j=0到 j = s l + 1 j=s_l+1 j=sl+1的特征累加
注意不要将 Θ i 0 \Theta_{i0} Θi0正则化
9.2损失函数优化算法—反向传播
前向传播向量化,计算神经网络结构中每个神经元的激活值。
首先由 a ( 1 ) = x a^{(1)}=x a(1)=x即输入层计算第二层的 z ( 2 ) z^{(2)} z(2)函数
再带入sigma函数(并加入偏移项)计算出 a ( 2 ) a^{(2)} a(2)层各神经元的激活值
a类推算出每层神经网络的每个神经元的激活值最终输出得出假设函数
反向传播算法(Backpropagation)
δ j ( l ) \delta_j^{(l)} δj(l): 第 l l l层神经网络的第 j j j个神经元的误差
a j ( l ) a_j^{(l)} aj(l): 第 l l l层神经网络的第 j j j个神经元的激活值
反向传播计算流程:
- 通过最后一层神经网络即输出层的预测值减去样本标签得出第 L L L层的误差
δ j ( 4 ) = a j ( 4 ) − l a b e l s j = h Θ ( x ) j − y j = g ( z ( 4 ) ) − l a b e l s j \delta^{(4)}_j=a_j^{(4)}-labels_j=h_\Theta(x)_j-y_j=g(z^{(4)})-labels_j δj(4)=aj(4)−labelsj=hΘ(x)j−yj=g(z(4))−labelsj
向量化后: δ ( 4 ) = a ( 4 ) − l a b e l s \delta^{(4)}=a^{(4)}-labels δ(4)=a(4)−labels
-
δ ( 3 ) = ( Θ ( 3 ) ) T δ ( 4 ) . ∗ g ′ ( z ( 3 ) ) \delta^{(3)}=(\Theta^{(3)})^T\delta^{(4)} .* g^{'}(z^{(3)}) δ(3)=(Θ(3))Tδ(4).∗g′(z(3)) 其中 g ′ ( z ( 3 ) ) g^{'}(z^{(3)}) g′(z(3)) 由 a ( 3 ) . ∗ ( 1 − a ( 3 ) ) a^{(3)} .* (1-a^{(3)}) a(3).∗(1−a(3))推出
-
δ ( 2 ) = ( Θ ( 2 ) ) T δ ( 3 ) . ∗ g ′ ( z ( 2 ) ) \delta^{(2)}=(\Theta^{(2)})^T\delta^{(3)} .* g^{'}(z^{(2)}) δ(2)=(Θ(2))Tδ(3).∗g′(z(2)) 其中 g ′ ( z ( 2 ) ) g^{'}(z^{(2)}) g′(z(2)) 由 a ( 2 ) . ∗ ( 1 − a ( 2 ) ) a^{(2)} .* (1-a^{(2)}) a(2).∗(1−a(2))推出
-
没有 δ ( 1 ) \delta^{(1)} δ(1)这一项,因为第一层神经网络为输入项,不存在误差。
一定要注意.*是矩阵的点乘,两个形状一样的矩阵对应元素相乘
最终将推得: ∂ ∂ Θ i j ( l ) J ( Θ ) = a j ( l ) δ j ( l + 1 ) {\partial\over \partial\Theta_ij^{(l)}}J(\Theta)=a_j^{(l)}\delta_j^{(l+1)} ∂Θij(l)∂J(Θ)=aj(l)δj(l+1)
注意这里忽略了正则化。后续会改善
反向传播算法思路:
-
定义训练数据集 ( x ( 1 ) , y ( 1 ) ) , . . . , ( x ( m ) , y ( m ) ) {(x^{(1)},y^{(1)}),...,(x^{(m)},y^{(m)})} (x(1),y(1)),...,(x(m),y(m))
-
初始化误差 Δ i j ( l ) \Delta_{ij}^{(l)} Δij(l)值
-
遍历所有样本的循环
3.1 定义 a ( 1 ) = x ( i ) a^{(1)}=x^{(i)} a(1)=x(i)即设置输入值为第一层神经元的激活值
3.2 前向传播计算出接下来各层的激活值 a ( l ) a^{(l)} a(l)
3.3 利用已知的样本标签,用第 L L L层的预测值减去实际标签值的出 L L L
层的误差值 δ ( L ) \delta^{(L)} δ(L)
3.4 反向传播计算出各层的 δ \delta δ值(除了第一层输入层没有误差)
3.5 计算 Δ 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
- 分开计算偏移项的偏导数和其他项的偏导数
9.3 理解反向传播算法
前向传播图解:
只有一个输出类别的举例:
反向传播理解:
9.4 矩阵展开为向量
9.5 梯度检验检查梯度传播bug
当 θ \theta θ是实数R的情况下,双侧差分计算该点的近似导数
当 θ \theta θ为向量参数的情况下,即为n维向量,计算导数近似值
计算过程:
执行笔记:
- 通过反向传播计算偏导数值DVec
- 实现数值上的梯度检验,通过计算gradApprox
- 确保DCvec和gradApprox取值近似
- 通过检验后代码实现的时候关闭梯度检验提升计算效率
9.6 随机初始化权重参数
在神经网络中将权重参数 θ \theta θ全部初始化为0是没有任何作用的
全部初始化为0的话会导致各向量值都一样,没有任何意义,相当于只有一个特征,形成了高度冗余。
因此参数需要进行随机初始化为 [ − ϵ , ϵ ] [-\epsilon,\epsilon] [−ϵ,ϵ]
9.7 总体回顾
训练一个神经网络
-
选取合适的神经网络结构:隐藏层数、神经元数
通过输出特征和输出类别数确定神经网络的第一层和最后一层的神经元个数。注意输出类别y的向量表示。
默认使用一层隐藏层,如果使用多个隐藏层默认每个隐藏层的神经元个数一致。隐藏单元一般为输入特征数的一倍或几倍
实现训练一个神经网络的步骤:
- 确定神经网络结构并随机初始化权重参数(很小,接近0)
- 执行前向传播算法,对输入特征x计算出相应的输出
- 计算损失函数 J ( Θ ) J(\Theta) J(Θ)
- 执行反向传播计算偏导数项 ∂ ∂ Θ i j ( l ) J ( Θ ) {\partial\over \partial\Theta_ij^{(l)}}J(\Theta) ∂Θij(l)∂J(Θ)
- 使用梯度检验比较偏导数值,确保值接近最后关闭梯度检验
- 使用一个优化算法,例如梯度下降或更先进的算法和反向传播结合去最小话损失函数 J ( Θ ) J(\Theta) J(Θ)(注意是非凸函数,可能优化至局部最优化处,但也很不错了,可以改变初始权重参数)