文章目录

  • BP神经网络(Back Propagation)
    • 1. 主要过程
    • 2.整体思路
    • 3. 算法详解
    • 4. 代码实现

BP神经网络(Back Propagation)

  误差逆传播算法(error Back Propagation 简称BP),实际上是多层感知器的一种,在1986由Rumelhart和Hinton为首的科学小组提出。BP神经网络具有任意复杂的模式分类能力和优良的多维函数映射能力,解决了简单感知器不能解决的异或问题和其他问题。从结构而言具有输入层、隐含层和输出层;从本质上来讲是以网络误差平方为目标函数、采用梯度下降法来计算目标函数的最小值。

BP神经网络结构

1. 主要过程

  • (1)工作信号向前正向传播的子过程
  • (2)误差信号反向传播向后反馈的子过程
    借用一个例子BP(Back Propagation)神经网络学习笔记:我要追求女神,那我总得表示一下吧!于是我给她买花,讨她欢心。然后,她给我一些表示(或者叫暗示),根据这个表示,与我最终目的进行对比(追求到女神),然后我进行调整继续表示,一直循环往复,直到实现最终目的——成功最求到女神。我的表示就是“信号前向传播”,女神的表示就是“误差反向传播”。这就是BP神经网络的核心。
  • 其中主要的过程是:
    正向传播获得输出结果
Created with Raphaël 2.3.0输入层隐藏层输出层
BP正向传播

最小二乘、梯度下降等方法进行对比标签和输出,逐层向上反馈其结果误差,更新权值

Created with Raphaël 2.3.0输出层隐藏层输入层
BP反馈反向传播

2.整体思路

  • 学习目的:

得到一个模型,当输入一组新的数据可以输出我们所期望的数据

  • 学习方式:

输入样本数据经过激活函数的处理得到输出,输出与已知标签对比,反向改变权值。

  • 学习本质:

对各种连接权值进行动态调整

  • 学习核心:

权值的调整(在学习过程中对各个神经元的连接权进行的一定的调整规则)

3. 算法详解

  神经网络模拟生物的神经结构与活动,构造分类器。基本组成单位为神经元,当输入神经元的参量大于某一个阈值的时候,神经元变为兴奋状态,产生输出,否则不响应。这个输入与其相连接的所有神经元都有关系,神经元的响应函数可以分为多种不同形式的(即激活函数)。
下面介绍一下:

  1. 激活函数
  2. BP推导

1)激活函数

定义:神经网络中的每个神经元节点接受上一层神经元的输出值作为本神经元的输入值,并将输入值传递给下一层,输入层神经元节点会将输入属性值直接传递给下一层(隐层或输出层)。在多层神经网络中,上层节点的输出和下层节点的输入之间具有一个函数关系,这个函数称为激活函数(又称激励函数)。

应用原因:不使用激活函数(f(x)=xf(x) = xf(x)=x),每一层节点的输入就是上层输出的线性函数,无论多少层隐含层,最终输出的结果都是输入的线性组合,相当于最原始的感知机,网络的逼近能力非常有限。

常用激活函数及其特点:

(1)sigmoid函数
非线性激活函数,其数学公式为:
f(z)=11+e−zf(z) = \frac{1}{1+e^{-z}}f(z)=1+e−z1​
几何图像为:


sigmoid 函数及其导数图像

特点:

可将输入的连续值转变为0和1之间的输出,如果是非常小的负数输出为0,非常大的正数输出为1

缺点

  • 在深度神经网络中梯度反向传播时导致梯度爆炸和梯度消失
  • sigmoid的输出output不是0均值(zero-centerd)
  • 解析式中含有幂运算,计算求解的代价较高,对于大规模的机器学习算法和训练过程对时间空间的消耗较高

(2)tanh函数
函数解析式:
tanh(x)=ex−e−xex+e−xtanh(x) = \frac{e^x - e^{-x}}{e^x+e^{-x}}tanh(x)=ex+e−xex−e−x​
tanh函数及其导数图像

tanh 函数及其导数图像

优点:

  • 解决了Sigmoid函数不是zero-centered输出的问题

不足:

  • 梯度消失和幂运算的问题仍然存在

(3)Relu函数
Relu函数解析式
Relu=max(0,x)Relu = max(0,x)Relu=max(0,x)
Relu函数及其导数图像

Relu 函数及其导数图像

描述 >Relus是一个取最大值的函数,函数并非是全区间可导的

优点

  • 解决了梯度消失(gradient vanishing)的问题(在正区间)
  • 不含有幂指数计算,计算速度快
  • 收敛速度较快

注意问题:

  • Relu的输出不是zero-centered的值
  • Deep ReLU Problem,即有的神经元可能永远不会被激活,导致相应的参数永远不会被更新(主要原因:
    (1):初始化参数较差,发生的几率很小;
    (2)learning rate太高)

(4)Leaky ReLU函数(目前使用最为广泛和通用的activation function)
函数表达式:
f(x)=max(ax,x)f(x) = max(ax,x)f(x)=max(ax,x)
Leaky ReLU函数及其导数的图像:

Leakey Relu 函数图像
Leakey Relu 函数导数图像

解释:

为了解决Dead ReLU Problem,提出了将ReLU的前半段变为不为0的ax,通常a=0.01
看起来Leaky ReLU具有ReLU的优点,而且在一定的程度上克服了ReLU的缺点,但是在实际上通常还是习惯用ReLU,也没有完全证明Leaky ReLU总是优于ReLU

(5)ELU(exponential Linear Units)函数
函数表达式:
f(x)={xifx>0a(ex−1))otherwise{f(x)}=\left\{ \begin{array}{rcl} x && {if x > 0}\\ a(e^x-1)) && { otherwise} \end{array} \right. f(x)={xa(ex−1))​​ifx>0otherwise​
函数及其导数的图像

ELU函数及其导数

优点: >* 不存在Dead ReLU Problem >* 输出的均值接近于0,zero-centered

小问题:

计算量稍大

2) BP推导

定义变量:

推导过程:

1.网络初始化:
主要就是初始化各个连接权值w,值域于(-1,1);设定误差函数e;给定计算精度值ϵ\epsilonϵ和最大学习次数M。

2.随机选择第k个输入样本和其对应的期望输出(即标签结果)

3.计算隐含层的各个神经元的输入和输出

4.利用网络期望输出和实际输出,计算误差函数e对输出层的各神经元的偏导数


5.利用隐藏层到输出层的连接权值、隐含层的输出值、输出层的偏导数计算出误差函数对隐含层各神经元的偏导数

6.根据输出层各神经元的δo(k)\delta_o(k)δo​(k)和隐含层各神经元的输出来修正连接权值who(k)w_{ho}(k)who​(k)

7.利用隐含层各神经元的δo(k)\delta_o(k)δo​(k)和输入层的输出层的连接权

8.计算全局误差:

9.判断误差或者迭代次数是否满足要求,当误差在一定的精度范围之内或者达到迭代次数结束循环。否则返回到第三步重复进行下一轮学习。

4. 代码实现

import math
import random
import numpy as np
import matplotlib.pyplot as plt
random.seed(0)  # random加种子,让每次生成的随机数都是相同的
def rand(a, b):'''随机函数'''return (b - a) * random.random() + adef make_matrix(m, n, fill=0.0):# 方法1,:直接使用numpy的zeros函数return np.zeros([m,n]).tolist()#方法2:定义list,逐行加入#     mat = []#     for i in range(m):#         mat.append([fill] * n)#     return matdef sigmoid(x):'''sigmoid激活函数'''return 1.0 / (1.0 + math.exp(-x))def sigmoid_derivative(x):'''sigmoid函数的导数'''return x * (1 - x)class BPNeuralNetwork:def __init__(self):self.input_n = 0           # 初始化输入层神经元数self.hidden_n = 0          # 初始化隐含层神经元数self.output_n = 0          # 初始化输出层神经元数self.input_cells = []      # 初始化输入层神经元self.hidden_cells = []     # 初始化隐含层神经元self.output_cells = []     # 初始化输出层神经元self.input_weights = []    # 输入层到隐含层的权重self.output_weights = []   # 隐含层到输出层的权重self.input_correction = [] # 输入层校正值self.output_correction = [] # 输出层的校正值def setup(self, ni, nh, no):'''ni——输入层神经元的个数nh——隐含层神经元的个数no——输出层神经元的个数'''self.input_n = ni + 1      #加上一列偏置值self.hidden_n = nhself.output_n = no# init cellsself.input_cells = [1.0] * self.input_n   # 初始化1行ni+1列的单位矩阵self.hidden_cells = [1.0] * self.hidden_n # 初始化1行nh列的单位矩阵self.output_cells = [1.0] * self.output_n # 初始化1行no列的单位矩阵# 初始化输入层到隐含层之间的权重self.input_weights =(np.random.random([self.input_n,self.hidden_n])-0.8)# 初始化输入层到隐含层之间的权重self.output_weights =(np.random.random([self.hidden_n,self.output_n]))*2 # 初始化校正矩阵self.input_correction = make_matrix(self.input_n, self.hidden_n)self.output_correction = make_matrix(self.hidden_n, self.output_n)def predict(self, inputs):# 激活输出层神经元for i in range(self.input_n - 1):self.input_cells[i] = inputs[i]# 激活隐含层神经元for j in range(self.hidden_n):total = 0.0for i in range(self.input_n):total += self.input_cells[i] * self.input_weights[i][j]self.hidden_cells[j] = sigmoid(total)# 激活输出层神经元(即输出结果)for k in range(self.output_n):total = 0.0for j in range(self.hidden_n):total += self.hidden_cells[j] * self.output_weights[j][k]self.output_cells[k] = sigmoid(total)return self.output_cells[:]def back_propagate(self, case, label, learn, correct):'''case——输入数据label——标签数据learn——学习率correct——校正参数'''# 正向传参self.predict(case)# 获取输出层误差及误差相对于输出层神经元的偏导数output_deltas = [0.0] * self.output_nfor o in range(self.output_n):error = label[o] - self.output_cells[o]output_deltas[o] = sigmoid_derivative(self.output_cells[o]) * error# 获取隐含层的相对误差及其相对于隐含层神经元的偏导数hidden_deltas = [0.0] * self.hidden_nfor h in range(self.hidden_n):error = 0.0for o in range(self.output_n):error += output_deltas[o] * self.output_weights[h][o]hidden_deltas[h] = sigmoid_derivative(self.hidden_cells[h]) * error# 更新隐含层到输出层的权值for h in range(self.hidden_n):for o in range(self.output_n):change = output_deltas[o] * self.hidden_cells[h]self.output_weights[h][o] += learn * change + correct * self.output_correction[h][o]self.output_correction[h][o] = change# 更新输入层到输出层的权重for i in range(self.input_n):for h in range(self.hidden_n):change = hidden_deltas[h] * self.input_cells[i]self.input_weights[i][h] += learn * change + correct * self.input_correction[i][h]self.input_correction[i][h] = change# 获取全局误差error = 0.0for o in range(len(label)):error += 0.5 * (label[o] - self.output_cells[o]) ** 2return errordef train(self, cases, labels, limit=10000, learn=0.05, correct=0.1):for j in range(limit):error = 0.0for i in range(len(cases)):label = labels[i]case = cases[i]error += self.back_propagate(case, label, learn, correct)if j%100==0:   plt.scatter(j,error)plt.title('Error curve')plt.xlabel('iteration')plt.ylabel('error')plt.show()def test(self):cases = [[0, 0],[0, 1],[1, 0],[1, 1],]labels = [[0], [1], [1], [0]]self.setup(2, 5, 1)self.train(cases, labels, 10000, 0.05, 0.1)for case in cases:print(self.predict(case))if __name__ == '__main__':nn = BPNeuralNetwork()nn.test()

结果:

输出结果:

误差迭代图:

说明:

在迭代到1400次的时候误差明显开始降低,迭代到4000次的时候误差降低不太明显。(不同的初始化参数其下降的效率不同)

来都来了,点个赞给个建议再走呗

机器学习——神经网络(四):BP神经网络相关推荐

  1. 机器学习 | MATLAB实现BP神经网络newff参数设定(下)

    机器学习 | MATLAB实现BP神经网络newff参数设定(下) 目录 机器学习 | MATLAB实现BP神经网络newff参数设定(下) 基本介绍 程序设计 参考资料 致谢 基本介绍 newff搭 ...

  2. 机器学习 | MATLAB实现BP神经网络newff参数设定(上)

    机器学习 | MATLAB实现BP神经网络newff参数设定(上) 目录 机器学习 | MATLAB实现BP神经网络newff参数设定(上) 基本介绍 程序设计 参考资料 致谢 基本介绍 newff搭 ...

  3. 机器学习 | MATLAB实现BP神经网络newff参数设定(中)

    机器学习 | MATLAB实现BP神经网络newff参数设定(中) 目录 机器学习 | MATLAB实现BP神经网络newff参数设定(中) 基本介绍 程序设计 参考资料 致谢 基本介绍 newff搭 ...

  4. bp神经网络是什么网络,神经网络和bp神经网络

    1.什么是BP神经网络? BP算法的基本思想是:学习过程由信号正向传播与误差的反向回传两个部分组成:正向传播时,输入样本从输入层传入,经各隐层依次逐层处理,传向输出层,若输出层输出与期望不符,则将误差 ...

  5. 基于bp的神经网络算法,bp神经网络是什么算法

    BP人工神经网络方法 (一)方法原理人工神经网络是由大量的类似人脑神经元的简单处理单元广泛地相互连接而成的复杂的网络系统.理论和实践表明,在信息处理方面,神经网络方法比传统模式识别方法更具有优势. 人 ...

  6. mlp神经网络和bp神经网络,bp神经网络lm算法原理

    MATLAB中训练LM算法的BP神经网络 1.初始权值不一样,如果一样,每次训练结果是相同的 2.是 3.在train之前修改权值,IW,LW,b,使之相同 4.取多次实验的均值 一点浅见,仅供参考 ...

  7. 深度学习(神经网络) —— BP神经网络原理推导及python实现

    深度学习(神经网络) -- BP神经网络原理推导及python实现 摘要 (一)BP神经网络简介 1.神经网络权值调整的一般形式为: 2.BP神经网络中关于学习信号的求取方法: (二)BP神经网络原理 ...

  8. RBF神经网络与BP神经网络优缺点比较

    RBF神经网络与BP神经网络优缺点比较 (2016-05-31 21:37:04)    转载▼ 标签: 神经网络 RBF神经网络与BP神经网络优缺点比较 1.      RBF 的泛化能力在多个方面 ...

  9. RBF神经网络与BP神经网络的比较

    RBF神经网络与BP神经网络的比较 RBF神经网络与BP神经网络都是非线性多层前向网络,它们都是通用逼近器.对于任一个BP神经网络,总存在一个RBF神经网络可以代替它,反之亦然.但是这两个网络也存在着 ...

  10. 机器学习知识点(九)BP神经网络Java实现

    为深入理解机器学习中BP神经网络算法,从网上找到的Java实现代码. 1.BP神经网络结构如下图所示,最左边的是输入层,最右边的是输出层,中间是多个隐含层,隐含层和输出层的每个神经节点,都是由上一层节 ...

最新文章

  1. 互联网圈都是什么人年薪百万?这份报告有真相
  2. OpenCV-Python:模板匹配
  3. python支持什么操作方式_python模拟点击常用的操作方法有哪些?
  4. 实现运动轨迹_【自动驾驶】运动规划丨速度规划丨时间维度
  5. 关于iOS7里的JavaScriptCore framework
  6. 岳阳学计算机软件,岳阳学java专业学校排名
  7. Linux ubuntu 装openCV,Ubuntu Linux下安装OpenCV2.4.1所需包
  8. (72)FPGA模块调用(VHDL调用Verilog)
  9. jsonrpc php使用,利用php怎么编写一个json rpc框架
  10. C 语言实例 - 删除字符串中的特殊字符
  11. linux 登录直接进入系统,Linux登录和推出系统入门教程
  12. 资源分享:一千张高清头像图片免费分享,适用于网站app程序使用!
  13. 各地级市系列环境指标数据(2003-2017年)
  14. 共识算法PBFT和Raft
  15. oa处理会签流程图_关于合同会签OA流程使用说明
  16. pytorch蜜蜂蚂蚁数据集处理python代码
  17. 通过docker安装FastDFS
  18. 使用vue做一个“淘宝“项目(删除原有代码)
  19. 没有了华为,高通任意涨价,缺乏核心技术的国产手机只能任由宰割
  20. QT模型索引使用QModelIndex

热门文章

  1. photoshop插件开发
  2. Java编程——九九乘法表
  3. 电子购物网站导航制作
  4. 手机上做c语言作业的软件下载,c语言编程软件手机版下载-C语言编程 安卓版v1.0.2-PC6安卓网...
  5. 新浪和腾讯微博开放平台比较
  6. 配置管理计划的主要内容有哪些?
  7. 高级语言程序设计(c语言版)课后答案,高级语言程序设计习题与解答(C语言版)/高等院校教材...
  8. SqlDataReader的用法(重点:访问字段的值)
  9. LordPE 查看程序依赖项的好工具
  10. “绿坝—花季护航”使用全攻略