【深度学习系列(二)】:基于c++实现一个简单的神经网络(3)

3、前向和反向传播

1. 单个神经元的前向和反向计算

众所周知,神经网络是由一系列的神经元组成,那具体长什么样呢?可以看下面的图。

                                               

所以,对于一个神经元来说,其前向计算公式如下:

                                                    y=f(\sum_{i=1}^{n}\left ( w*x_{i}^{} \right )+b)

其中:f(x)为神经网络的激励函数。

为什么要使用激励函数呢?

激活函数是用来加入非线性因素的,增加线性模型的非线性表达能力。

如果没有激活函数,那么我们最终得到只是一系列直线/平面包围的学习区域,如下图:

最终得到的结果还是线性的, 最多不过是复杂的线性组合罢了,当然你可以说我们可以用无限条直线去逼近一条曲线。

但是如果加入激活函数,如sigmoid函数,这是一个不折不扣的非线性函数,如下图。最终我们得到的就是一个非线性的线\曲面。

 

既然知道了激活函数的好处,那么我们常用的激活函数有哪些呢?这里就不一一列举了,有兴趣的可以查看第一个参考链接中的常见激励函数介绍。在本程序中我们主要使用relu激活函数,该函数的公式为:f(x)=max(0,x),其具体形状如下:

                                              

这里,我们用c++实现了相关函数:

void NN::relu(Mat &X)
{
	//生成大于零的模板并归一化
	Mat mask = (X > 0) / 255;

	//将矩阵转化为float类型
	Mat mask2f;
	mask.convertTo(mask2f, CV_32FC1);

	//relu计算输出
	multiply(X, mask2f, X);
}

参考链接:

深度学习中常用的激励函数

【机器学习】神经网络-激活函数-面面观(Activation Function)

神经网络激励函数的作用是什么

这时我们很容易得到单个神经元的梯度,通过分别对w,b求导得到如下公式:

令:y=f(z)z= \sum_{n}^{i=1}w_{i}x_{i}+b,则:

\frac{\partial y}{\partial w}=\frac{\partial y}{\partial z}\frac{\partial z}{\partial w}

\frac{\partial y}{\partial b}=\frac{\partial y}{\partial z}\frac{\partial z}{\partial b}

其中:\frac{\partial y}{\partial z}=\left\{\begin{matrix} 1 & y>0\\ 0& y<0 \end{matrix}\right.\frac{\partial z}{\partial w}=x\frac{\partial z}{\partial b}=1,根据链式法则,最终得到单个神经元得反向传播得计算公式如下:

\frac{\partial y}{\partial w}=\left\{\begin{matrix} x & y>0\\ 0& y<0 \end{matrix}\right.

\frac{\partial y}{\partial b}=\left\{\begin{matrix} 1 & y>0\\ 0& y<0 \end{matrix}\right.

2. 多层神经网络的前向和反向传播的计算

是不是很简单,答案必须是的。但是如果有多个神经元连接在一起的时候,就会蒙逼了,这时候相对来说对于前向传播可能还比较简单,但反向传播,也就是求各个层的参数的导数,可能无从下手了。当然,这里我们先不着急进行反向传播得计算,先搞清楚前向传播得过程再说。我们假设有如下所示得一个神经网络:

 

 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值