神经网络的原理,算法推导,python编程实现

1.前言

如图是一个神经网络的简化结构,隐藏层每一个节点都是一个神经元,比如下图的a1,a2,a3。机器学习中的神经网络是模拟生物神经网络结构,每个神经元与其他神经元相连,当神经元的电位超过了一个‘阈值’,那么它就会被激活,即‘兴奋’起来。

   机器学习的神经网络是怎么模拟大脑神经元‘兴奋’这个概念的?结合a1这个神经元做简要的分析:

首先对于a1的定义,我们给出如下的公式..

                      \large {a_{1}}=g(h(x)))={w_{11}}*{x_{1}}+{w_{21}}*{x_{2}}\cdot \cdot \cdot \cdot {w_{n1}}*{x_{n}}+{w_{m1}}*{x_{m}}+{b_{01}}*{x_{0}}

    剖析神经元兴奋的定义“当神经元的电位超过了一个‘阈值’,那么它就会被激活”,对应与上面公式,怎么使得上诉公式达到神经元的效果?

    当\small h(x)达到某一阀值时候\small {a_{1}}=g(h(x))=1,即兴奋状态,反之当未达到阀值时\small {a_{1}}=g(h(x))=0,即未兴奋状态。

所以理想情况下\small \small g(z)这个函数应该如下图的红色,因为起特性就是大于零被激活,小于零未激活,所以称之为激活函数。 :

但是红色函数存在不连续,不光滑等不太好的性质...所以在实际情况下,我们一般会使用sigmod函数来作为激活函数(即图中蓝线):

                                                                                \large sigmoid(z)=\frac{1}{1+e^{-z}}

其实我们可以发现,对于神经网络来说,每一个神经元我们都可以理解成一个逻辑回归(LR)模型。这样去理解它或许对你之后的理解有所帮助。对于逻辑回归算法模型的推到及编程可以查看我之前的一篇文章:点击此处跳转

2.前向传播的神经网络运算

          由图,输入层的输入矩阵(\large x_{i})可以表示为:                 隐藏层的输入矩阵(\large a_{j})可以表示为:

                                   \large \begin{bmatrix} x_{1}\\ x_{2}\\ x_{3} \end{bmatrix}                                                                        \large \begin{bmatrix} a_{1}\\ a_{2}\\ a_{3} \end{bmatrix}                        

          输入层的每个输入\large x_{i}对应每个隐藏层\large a_{j}的权重为\large w_{ij},所以权重的矩阵(\large w_{ij})可以表示为:

                                                                   \large \begin{bmatrix} w_{11} &w_{12} \\ w_{21} &w_{22} \\ w_{31}&w_{32} \end{bmatrix}

          由神经元的兴奋启发可以将上式表示为:

                                                                  \large h_{1}=\begin{bmatrix} w_{11} & w_{21}& w_{31} \end{bmatrix}*\begin{bmatrix} x_{1}\\ x_{2}\\ x_{3} \end{bmatrix}   

                                                                  \large a_{1}=g(h_{1})=\frac{1}{1+e^{-h_{1}}}

       由上式子可以整理得;

                                                                 \large h=w^{T}x+[b]    (b为偏置单元,对应图1的,x0,a0,在本节介绍中省略)

       将矩阵代入上式:

                                                               \large h_{j}=w^{T}x+[b]=\begin{bmatrix} w_{11} &w_{21} & w_{31} \\ w_{12} &w_{22}&w_{32} \end{bmatrix}*\begin{bmatrix} x_{1}\\ x_{2}\\ x_{3} \end{bmatrix}

                                                              \large a_{i}=g(h_{j})=\frac{1}{1+e^{-h_{j}}}

    同理,我们对于接下来的隐藏层和输出层也用同样的方法,那么我们最终的输出层就是一个在0,1之间分布的值,当其大于0时,即输入的x属于1这个类别。当其小于0时,输入的x属于0这个类别。

 

3.梯度下降与代价函数

   你可能会因为不清楚第二节的前向传播算法中的权重矩阵(\large w_{ij})是怎么来的,从而导致你对整个算法的过程有些不知所云。这一章节会为你解决这个疑惑。

     需要明白的是,在设计一个神经网络算法模型的时候,有些参数是提前人为定义的。

#参数1:
隐藏层的层数
#参数2:
每层隐藏层的神经元个数
#参数3:
输出层的神经元个数
#参数4
定义每次训练的样本数
#参数5
定义训练的次数
#参数6
定义学习率

当上诉参数设定后,将在神经网络中起到怎样的作用呢?结合下图来说明一下:

1.在定义了隐藏层的层数,每层神经元的个数,输出层神经元个数后我们能确定上图中w,b,v,b_,u,b__的矩阵大小。在神经网络第一轮训练时候,上诉矩阵的参数即w11,w12...等的值是人为定义的一系列满足正态分布的随机值。实质上之后你会发现,无论起先w,b的矩阵值如何,通过代价函数的反复迭代都能让其收敛到最低点。

2.定义每次训练的样本数即确定了输入层输入x的个数。

3.人为定义不同的训练的次数,学习率,通过观察准确率的变化,来选择最适合神经网络的参数。

 

在前言部分为大家介绍到,一个神经网络的每个神经元可以看做一个逻辑回归算法模型。

逻辑回归的代价函数如下:

                                     \large j(w)=\frac{1}{m}\sum_{i=1}^{m}[-y^{i}(h_{w}(x^{i}))-(1-y^{i})log(1-h_{w}(x^{i}))]

关于逻辑回归代价函数的推到,我简要说明一下:

1.在二分类问题中,对于每个观察样本:

                             \large p(x_{i},y_{i})=p(y_{i}=1|x_{i})^{y_{i}}(1-p(y_{i}=1|x_{i}))^{1-y_{i}}

这个公式很好理解,拆分开来可以这样表示:

                             \large p(x_{i},y_{i})=\left\{\begin{matrix} p(y_{i}=1|x_{i})& y_{i}=1\\ (1-p(y_{i}=1|x_{i})) &y_{i}=0\end{matrix}\right.

2.对于n个出现的样本,样本间相互独立,则n个出现的概率为每一个出现的概率的乘积。

                             \large L(w)=\prod p(y_{i}=1|x_{i})^{y_{i}}(1-p(y_{i}=1|x_{i}))^{1-y_{i}}

3.为了满足凸函数求最优解的思想,我们对L(w)取对数,并化简:

                              \large L(w)=\prod p(y_{i}=1|x_{i})^{y_{i}}(1-p(y_{i}=1|x_{i}))^{1-y_{i}}

                             \large j(w)=\sum_{i=1}^{n}[ y_{i}log(p(y_{i}=1|x_{i}))+(1-y_{i})log(1-p(y_{i}=1|x_{i}))]

4.由sigmod函数可以推到出如下结果:

                             \large p(y_{i}=1|x_{i})=\frac{1}{1+e^{-z}}               

                             \large 1-p(y_{i}=1|x_{i})=\frac{1}{1+e^{z}}

5.有次推导逻辑回归的代价函数:

                          \large j(w)=\frac{1}{m}\sum_{i=1}^{m}[-y^{i}(h_{w}(x^{i}))-(1-y^{i})log(1-h_{w}(x^{i}))]

    对于神经网络来说,我们可以由上一章节的前向传播的算法得到最后的输出,之后我们算出这个输出与真实值的误差,然后用同样的方式反向传播回去迭代修正之前w,b,v,b_,u,b__矩阵的值。

   而对于每个隐藏层来说,其每个神经元都可以作为一个逻辑回归单元,这样神经网络误差算法的代价函数就可以做出如下表示:

                           \large j(w)=\frac{1}{m}\sum_{i=1}^{m}\sum_{k=1}^{k}[-y_{k}^{i}(h_{w}(x^{i})_{k})-(1-y_{k}^{i})log(1-h_{w}(x^{i})_{k})](k表示神经元的序号)

同理我们可以用逻辑回归算法模型的方式来对\large j(w)做梯度下降算法,即找出满足:

                                                                 \large \frac{\partial j(w)}{\partial w_{ij}^{l}}=0

时,的w和b的值。对\small \frac{\partial j(w)}{\partial w_{ij}^{l}}的求解,可以使用链式法则:

                                                                 \large \frac{\partial y}{\partial x}=\frac{\partial y}{\partial u}\frac{\partial u}{\partial x}

                                                               \large \frac{\partial j(w)}{\partial w_{ij}^{l}}=\frac{\partial j(w)}{\partial z_{j}^{l+1}}\frac{\partial z_{j}^{l+1}}{\partial w_{ij}^{l}}

 对于神经元的求和:

                                                               \large z_{j}^{l+1}=\sum_{i=0}^{n}w_{ij}^{l}a_{j}^{l}(这个公式可由前向传播算法矩阵运算中得出)

所以

         \large \frac{\partial z_{j}^{l+1}}{\partial w_{ij}^{l}}=(\frac{\partial\sum_{i=0}^{n} w_{ij}^{l}a_{j}^{l} }{\partial w_{ij}^{l}})=a_{j}^{l}

假设:

        \large \xi_{i}^{l+1}=\frac{\partial j(w)}{\partial z_{j}^{l+1}} 

那么:

         \large \frac{\partial j(w)}{\partial w_{ij}^{l}}=\xi_{i}^{l+1}a_{j}^{l}

所以由梯度下降算法可以求得:

                                             \bg_white \large \dpi{120} \large w_{j}:=w_{j}+ \eta \xi_{i}^{l+1}a_{j}^{l}           (\eta为人为设定的学习率。)

3.BP反向传播算法

(未完待续)

                         

猜你喜欢

转载自blog.csdn.net/qq_41664845/article/details/82685491