机器学习—神经网络

1. 起源

为了使算法来模拟人的大脑。神经网络算法在上世纪八十年代和90年代早期被广泛的使用,然后在90年代末逐渐变得没那么留下。但最近神经网络又东山再起了,其中一个原因是神经网络的计算量够大且计算机的运算能力能够应对这么大的计算量。

2. 为什么需要神经网络

举个例子,针对一个非线性分类问题,如下图所示:

假如用逻辑回归的话,可以构造一个包含很多非线性项的逻辑回归函数:                                                                                                                                                   g(\theta_{0}+\theta_{1}x_{1}+\theta_{2}x_{2}+\theta_{3}x_{1}x_{2}+\theta_{4}x_{1}^{2}x_{2}+\theta_{5}x_{1}^{3}x_{2}+\theta_{6}x_{1}x_2^{2}+.... )

g是一个sigmoid函数。这样可能就能得到下图的一个函数来把两个类别分开:

当只有两个特征的时候,这样做还可以接受。但是对于很多的机器学习问题,特征远不止两项。比如当特征有100个时,若组合起来的特征只有二次项,比如:x_{1}^{2},x_{1}x_2,x_1x_3,......,x_1x_{100}.......那么也有(100-1)*100/2=4950项。如果还包含三次项的话,那么数据量将会是n^3级别。这时如果用逻辑回归的话,就会存在运算量过大的问题。所以这时候就需要另外一种算法。

3. 神经网络模型表示

一个简单的神经元即一个逻辑单元可以表示如下:

其中X表示输入数据,黄色的圈表示一个类似神经元细胞。然后输出一些结果。和逻辑回归的表达很相似。

神经网络其实就是一组神经元连接起来,类似下图:

从左到右有输入层、隐含层(可能不止一层)和输出层。分别有输入单元:x_1,x_2,x_3;隐含单元:a_1^{(2)},a_2^{(2)},a_3^{(2)};输出单元。

一些符号的表示内容如下:

a_i^{(j)}:第j层的第i个激活项,即由一个神经计算并输出的值。

\theta^{(j)}:控制从第j层到第j+1层的映射的矩阵。

4. 前向传播

在上一小节中,我们知道了神经网络的模型表示和一些参数的表示。现在我们来讲讲神经网络是如何提取数据的特征的。

还是以这幅图为例:

上图中省略了x_{0},a_0^{(2)}这两个单元,它们分别表示第一层和第二层的偏置项。

我们首先根据输入数据得到各个隐含层单元:

a_1^{(2)}=g(\theta_{10}^{(1)}x_0+\theta_{11}^{(1)}x_1+\theta_{12}^{(1)}x_2+\theta_{13}^{(1)}x_3)

a_2^{(2)}=g(\theta_{20}^{(1)}x_0+\theta_{21}^{(1)}x_1+\theta_{22}^{(1)}x_2+\theta_{23}^{(1)}x_3)

a_3^{(2)}=g(\theta_{30}^{(1)}x_0+\theta_{31}^{(1)}x_1+\theta_{32}^{(1)}x_2+\theta_{33}^{(1)}x_3)

最后得到的输出为:

h_\theta(x)=g(\theta_{10}^{(2)}a_0^{(2)}+\theta_{11}^{(2)}a_1^{(2)}+\theta_{12}^{(2)}a_2^{(2)}+\theta_{13}^{(2)}a_3^{(2)})

在上面几条式子中,\theta_{ij}^{(l)}表示连接第l层的第j个单元和第l+1层第i个单元的边的值。

当有很多层时,第二层有一些关于输入的相对简单的函数,第三层又在此基础上计算更加复杂的方程。再往后一层,计算的函数越来越复杂,这也是为什么神经网络能够表达复杂函数的原因。

5. 多分类问题

5.1 问题及输入输出描述

问题:现在我们有一张图片,类别有{人,轿车,摩托车和卡车}四类,我们需要识别图片为这四类中的哪一类。

上述是一个多分类问题,我们现在设计一个如下图的神经网络来解决这个问题:

我们有训练数据(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)}),其中X是图片转换而来的矩阵,y代表其真实结果,m代表训练样本的数量。在上图中可以看到输出层有4个单元,我们对其定义如下:

h_\theta(x)\approx \begin{bmatrix}1 \\ 0 \\ 0 \\ 0 \end{bmatrix}  ,结果为人;

h_\theta(x)\approx \begin{bmatrix}0 \\ 1 \\ 0 \\ 0 \end{bmatrix}  ,结果为轿车;

h_\theta(x)\approx \begin{bmatrix}0 \\ 0 \\ 1 \\ 0 \end{bmatrix}  ,结果为摩托车;

h_\theta(x)\approx \begin{bmatrix}0 \\ 0 \\ 0 \\ 1 \end{bmatrix} ,结果为卡车。

即输出层的哪个单元的值为1,那么这个单元所代表的类别就是最后的结果。

5.2 Cost function

我们先定义几个符号:

L:网络总的层数,包括输入和输出层,在上图中:L=4

s_l:第l层的单元的数量。在上图中:s_1=3,s_2=5,s_3=5,s_4=4

(h_\theta(x))_i:输出层的第i个单元的值

K:输出层单元数量

那么Cost function定义如下:

J(\theta)=-\frac{1}{m}[\sum_{i=1}^m\sum_{k=1}^Ky_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

\frac{\lambda}{2m}\sum_{l=1}^{L-1}\sum_{i=1}^{s_l}\sum_{j=1}^{s_{l+1}}(\theta_{ji}^{(l)})^2是正则化式子,表示对所有参数进行选择。

-\frac{1}{m}[\sum_{i=1}^m\sum_{k=1}^Ky_k^{(i)}log(h_\theta(x^{(i)}))_k+(1-y_k^{(i)})log(1-h_\theta(x^{(i)}))_k]  类似逻辑回归中的一个求和项

\sum_{k=1}^K  这个求和项主要是K个输出单元求和。

5.3 参数更新算法:后向传播算法(Backpropagation algorithm)

这里我们总的目标是得到J(\theta)的最小值。如果我们要用梯度下降算法的话需要编写代码来计算J(\theta) 和 \frac{\partial }{\partial \theta_{(ij)}^{l}}J(\theta) 。

J(\theta)的值比较好得到,下面我主要讲讲如何得到这些偏导数的值。

还是以这幅图为例:

对于一个训练样本(x, y),首先我们执行前向传播算法:

  • a^{(1)}=x
  • z^{(2)}=\theta^{(1)}a^{(1)}
  • a^{(2)}=g(z^{(2)})
  • z^{(3)}=\theta^{(2)}a^{(2)}
  • a^{(3)}=g(z^{(3)})
  • z^{(3)}=\theta^{(3)}a^{(3)}
  • a^{(4)}=h_\theta(x)=g(z^{(4)})

上述所有公式是向量化后的表示方法,即对每层的每个单元进行逻辑回归计算,然后用向量整合表达每一层的值。其中a^{(i)}表示第i层所有单元的值。g是一个sigmoid函数,这样就计算得到最后输出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)})=(\theta^{(3)})^{T}\delta^{(4)}a^{(3)}.*(1-a^{(3)})

\delta^{(2)}=(\theta^{(2)})^{T}\delta^{(3)}.*g^{'}(z^{(2)})=(\theta^{(2)})^{T}\delta^{(3)}a^{(2)}.*(1-a^{(2)})

计算完这些后,我们可以通过数学证明得到在不考虑正则的情况下,即\lambda=0时:\frac{\partial }{\partial \theta_{(ij)}^{l}}J(\theta)=a_j^{(l)}\delta_i^{(l+1)}

后向传播算法总的步骤总结如下:

对于训练集合:{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})}

首先将所有的\Delta_{ij}^{(l)}=0  (\Delta是大写的\delta

For i = 1 to m

        令a^{(1)}=x

        开始前向传播算法来计算a^{(l)}(l=2,3,...,L)

        利用y计算:\delta^{(L)} = a^{(L)}- y^{(i)}

        计算:\delta^{(L-1)},\delta^{(L-2)},...,\delta^{(2)}。(\delta^{(1)}不用计算)​

        \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 \neq 0

D_{ij}^{(l)}=\frac{1}{m}\Delta_{ij}^{(l)}                        if j = 0  (对输入层的数据不做正则化)

最后:\frac{\partial }{\partial \theta_{(ij)}^{l}}J(\theta)=D_{ij}^{(l)}

从上面的步骤可以看出,反向传播算法是将误差从后向前来进行传播,这也是名字的由来。

PS:方向传播算法数学推导可以看看别的博主的博客,在这里我只介绍一下步骤。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值