机器学习:神经网络的代价函数及反向传播算法

《机器学习:神经网络的模型构建》中,我记录了神经网络的一些基础知识,包括神经网络的逻辑单元、模型表示、前向传播等等。这篇笔记中,我会整理神经网络的代价函数以及反向传播算法~

那么如何在给定的训练集下,来为神经网络拟合参数呢?和之前学习的大多数算法一样,要从代价函数开始讨论起了。


神经网络在分类中的应用

神经网络可以应用在两种分类问题中:二分类问题和多分类问题。

在二分类问题中,y 等于 0 或 1,神经网络只有一个输出单元;多分类问题中,y 可能为任何实数,神经网络有多个输出单元。


神经网络的代价函数

现在我们有一个训练集: \left\{ (x^{(1)},y^{(1)}), (x^{(2)},y^{(2)}), ... , (x^{(m)},y^{(m)}) \right\} ,其中有 m 个训练样本,每个包含一组输入 x^{(i)} 和一组输出 y^{(i)} ,我们用 L 表示神经网络的总层数,用 s_{l} 表示第 l 层的单元数量,即神经元的数量(不包括偏置单元

一般来说,我们使用的神经网络的代价函数是逻辑回归里代价函数的一般形式。

在逻辑回归中,我们的代价函数通常为: J(\theta)=-\frac{1}{m}[\sum_{i=1}^{m}{y^{(i)}logh_{\theta}(x^{(i)})+(1-y^{(i)})log(1-h_{\theta}(x^{(i)}))}]+\frac{x}{2m}\sum_{j=1}^{n}{\theta_{j}^{2}} ,其中第一项表示预测值与实际值之间的差距,第二项为参数的正则化项。

对于神经网络来说,不再是只有一个输出单元,取而代之的是 K 个,那么其代价函数就表示为: 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}

其中 h_{\Theta}(x)\in R^{K} (K 维向量), (h_{\Theta}(x))_{i} 表示第 i 个输出。

即每一个的逻辑回归算法的代价函数,按输出的顺序 1 ~ K,依次相加。


反向传播算法

那么如何将神经网络的代价函数最小化呢?我们来看一下反向传播算法。

在上一个部分中,我们已经得到了代价函数 J(\theta) 的表达式,想要用梯度下降法或更高级的优化算法来求参数,就需要来计算 J(\theta)\frac{\partial}{\partial \Theta_{ij}^{(l)}}J(\Theta)

先回顾一下前向传播算法,如果有一个训练集,只有一组样本 (x,y) ,那么求训练集在神经网络中各层的输出值的过程为:

a^{(1)} 就是第一层的激励值,也就是输入层,所以为 x ,那么 z^{(2)} 就等于矩阵 \Theta^{(1)}a^{(1)} ,第二层的激励值 a^{(2)} 就为 g(z^{(2)}) ,后几层同理,同样用前向传播求出 a^{(3)}a^{(4)} ,其中 g 为 S 型激励函数。同样, a^{(4)} 也是假设函数的输出 h_{\Theta}(x)

⚠️接下来,为了计算导数项,我们就需要用到反向传播算法了!

简单来说,我们引入了一个误差变量 \delta_{j}^{(l)} ,代表第 l 层中第 j 个节点的误差,表示了该节点对最终输出值的残差产生的影响,也就是说这个误差捕捉到了该节点的激励值,然后计算出其误差,例如:

\delta_{j}^{(4)}=a_{j}^{(4)}-y_{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)})

(推导方法有很多种,式子太复杂就不记录了……)

到这里也看出来为什么叫反向传播算法了,因为是从输出层开始,一层一层往前推算的,一直计算到第二层,因为第一层是输入层,不存在误差。

这就是反向传播算法的大致过程,那么面对复杂的训练集时,如何使用反向传播算法呢?

假设训练集为 \left\{ (x^{(1)},y^{(1)}), (x^{(2)},y^{(2)}), ... , (x^{(m)},y^{(m)}) \right\} ,设误差 \Delta_{ij}^{(k)}=0 ,下面是一段伪代码:

For i=1 to m
{
Set a^{(1)}=x^{(i)}
Perform forward propagation to compute a^{(l)} for l=2,3,...,L
Using y^{(i)} , cpmpute \delta^{L}=a^{L}-y^{i}
Compute \delta^{(L-1)},\delta^{(L-2)},...,\delta^{2} \Delta_{ij}^{(l)}:=\Delta_{ij}^{(l)}+a_{j}^{(l)}\delta_{i}^{(l+1)}
}
D_{ij}^{(l)}:=\frac{1}{m}\Delta_{ij}^{(l)}+\lambda \Theta_{ij}^{(l)} if j\ne0 D_{ij}^{(l)}:=\frac{1}{m}\Delta_{ij}^{(l)} if j=0

简单来说就是,从后向前依次计算每一层的 \delta ,用 \Delta 代表总误差,每一层都有对应的 \Delta^{(l)} ,再引入代价函数对参数进行求导的结果 Dj=0 时对应偏置项。

一旦计算出了 D_{ij}^{(l)} ,就可以得到代价函数对每个参数的偏导数,因为可以证明得到:

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

D_{ij}^{(l)} 用来累加误差值,最后帮助我们计算偏微分~

发布了38 篇原创文章 · 获赞 23 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/cyan_soul/article/details/79946270