个人博客文章链接: http://www.huqj.top/article?id=166

BP神经网络,即“反向传播”神经网络,是一种被广泛运用的人工神经网络,它的思想就是通过反向传播不断调整模型权重,最终使得模型输出与预期输出的误差控制在一个小范围内。其中反向传播的算法(BP算法)是核心。

  一、模型架构

一个普通的神经网络模型大致如下图:

其中第一层称为“输入层”,最后一层称为“输出层”,其他层都是“隐含层”,每一层由若干个神经元(也就是图中的小圆圈)组成,输入层的神经元数目就是训练数据每个X的维度值,或者说是特征数目,输出层的神经元数目就是数据集的因变量维度。隐含层的数目和每层的神经元个数是随意的,一般根据模型需要调节。相邻层之间通过权重相连,每一层的每个神经元都与下一层的每个神经元相连。

BP神经网络训练的计算过程分为两种:前向传播反向传播

前向传播就是从数据数据前向计算出最终结果的过程,这也是模型训练好之后应用的方式。反向传播是一种参数调节方法,它从前向传播计算出的最终结果与实际数据相比计算误差,并根据数学公式逆向推导各个神经元和权重的误差,然后更新权重,重复前向传播的过程。在前向传播的过程中,除了第一层,每个神经元都接受上一层的输入,然后使用一个 激励函数 输出值到下一层。

二、数学原理以下公式都为矩阵表示形式

BP神经网络,本质上也是一个参数调优的模型,其中参数就是各个权重。

使用 a 表示每个神经元的输出, z 表示每个神经元的输入, W 表示权重, g(z) 表示神经元的激励函数,则前向传播的计算公式如下:

  a(1) = Xi 

    i 表示是第i组训练数据

z(2) = W(1) * a(1)  Add(a0 = 1)

    W 是一个 Sl+1 * (Sl  + 1) 的矩阵, Sk 表示是第 层神经元的数目,这里添加了一个值为1的偏置单元

a(2) = g(z(2))

g是激励函数,在分类问题中,通常使用sigmoid函数

以此类推,即可完成前向传播的过程,直到计算到输出层。

而对于反向传播(BP)的过程,实际就是求代价函数偏导数的过程,神经网络模型的代价函数如下:

为了计算这个代价函数的偏导数,我们定义了两个矩阵变量:δ 和 Δ,分别是二维和三维矩阵,δ 用来存储每个神经元的偏差,Δ 用来存储每个权重的偏差。

反向传播的计算公式如下:

  δ(end) = a(end) - yi

输出层的偏差就是预测值与实际值的插值, i 表示是第 i  组训练数据

δ(j) = (W(j))T * δ(j+1) * g'(z(j))

即上一层的误差是由下一层的误差和两层之间的连接权重,以及该层神经元的激励函数导数值决定的。对于激励函数为sigmoid函数的模型而言,可以通过导数计算得到如下公式:

δ(j) = (W(j))T * δ(j+1) * a(j) * (1 - a(j))

    这样依次从后往前计算,就可以得到所有神经元的δ值。

对于Δ值的计算,有如下公式:

Δ(j) = Δ(j) + δ(j+i) * (a(j))T

    注意 Δ 是累加值,累加的是每组训练数据。当累加完所有训练数据之后,就可以计算出代价函数的导数了:

D = Δ / m + lambda * W / m

可以从数学上证明,此时D就是代价函数的导数(加上了正则化参数),然后要做的就是应用梯度下降法调整权重W,再重复此过程。

  三、matlab实现

有了上面的数学原理和公式推导,我们可以使用Matlab很快的实现一个BP神经网络模型:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

%% 主函数

function [W, delta, iterNum] = BPNN(size_, alpha, lambda, threshold, maxIter, X, y)

    %BP神经网络实现

    %参数含义:

    %size - 一维数组,表示神经网络架构(不包含偏置单元)

    %alpha - 学习率α

    %lambda - 正则化参数

    %threshold - 误差阈值

    %maxIter - 最大迭代次数

    %X,y - 训练数据

    

    %判断参数合法性

    if size(X, 2) ~= size_(1) || size(y, 2) ~= size_(end) || size(y, 1) ~= size(X, 1)

       fprintf('训练数据集与模型结构不符\n'); 

    end

    %初始化一些参数

    layerNum = length(size_);

    maxUnitNum = max(size_);

    m = size(X, 1);

    iterNum = 0;

    

    %每个神经元的输出

    a = zeros(layerNum, maxUnitNum);

    %每个神经元的误差

    d = zeros(layerNum, maxUnitNum);

    %初始随机权重

    W = rand(layerNum - 1, maxUnitNum + 1, maxUnitNum + 1);

    

    %迭代训练

    while iterNum < maxIter

       iterNum = iterNum + 1;

       D = zeros(layerNum - 1, maxUnitNum + 1, maxUnitNum + 1);

       delta = 0;

       for i = 1 : m

           %前向传播

           [out, a] = forwardPropagation(size_, W, X(i, :), a);

           d(end, 1 : length(out)) = out - y(i, :);

           delta = delta + sum(abs(out - y(i, :)));

           %反向传播

           [d, D] = backPropagation(size_, W, d, D, a);

       end

       delta = delta / m;

       if delta <= threshold

           fprintf('误差小于阈值,训练结束');

           break;

       end

       %调整权重

       W = adjustWeight(size_, W, D, alpha, lambda, m);

    end

end

%% 一次前向传播

function [out, a] = forwardPropagation(size_, W, x, a)

    out = x;

    a(1, 1 : size_(1)) = x;

    for i = 1 : length(size_) - 1

        out = reshape(W(i, 2 : size_(i + 1) + 1, 1 : size_(i) + 1), size_(i + 1), size_(i) + 1) * [1, out]';

        out = sigmoid(out');

        a(i + 1, 1 : size_(i + 1)) = out;

    end

end

%% 一次反向传播

function [d, D] = backPropagation(size_, W, d, D, a)

    for i = length(size_) - 1 : -1 : 1

        %调节每个神经元的误差值

        d(i, 1 : size_(i)) = d(i + 1, 1 : size_(i + 1)) * ...

            reshape(W(i, 2 : size_(i + 1) + 1, 2 : size_(i) + 1), size_(i + 1), size_(i))...

            .* (a(i, 1 : size_(i)) .* (1 - a(i, 1 : size_(i))));

        % 累加调节每个权重的误差

        D(i, 2 : size_(i + 1) + 1, 1 : size_(i) + 1) = D(i, 2 : size_(i + 1) + 1, 1 : size_(i) + 1) + ...

            reshape(([1; a(i, 1 : size_(i))'] * d(i + 1, 1 : size_(i + 1)))', 1, size_(i + 1), size_(i) + 1);

    end

end

%% 调整权重

function W = adjustWeight(size_, W, D, alpha, lambda, m)

    D = D / m;

    for i2 = 1 : length(size_) - 1

        %非常数项系数加上正则化参数

        D(i2, 2 : size_(i2 + 1) + 1, 2 : size_(i2) + 1) = D(i2, 2 : size_(i2 + 1) + 1, 2 : size_(i2) + 1) + ...

           lambda * W(i2, 2 : size_(i2 + 1) + 1, 2 : size_(i2) + 1) / m;

       %梯度下降调整权重

       W(i2, 1 : size_(i2 + 1) + 1, 1 : size_(i2) + 1) = W(i2, 1 : size_(i2 + 1) + 1, 1 : size_(i2) + 1) -...

           alpha * D(i2, 1 : size_(i2 + 1) + 1, 1 : size_(i2) + 1);

    end

end

使用这个函数进行一次神经网络训练实验的测试代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

% 测试BP神经网络函数

%% 读取数据

clc;

clear;

data = load('machine-learning-ex2\ex2\ex2data2.txt');

%% 初始化参数

m = size(data, 1);

X = data(:,[1, 2]);

y = data(:, 3);

size_ = [2, 4, 1];

lambda = 0;

alpha = 2;

threshold = 0.1;

%% 画出点集

hold on

LogisticPlotData([ones(m, 1), X], y);

%% 开始训练

[W, delta, times] = BPNN(size_, alpha, lambda, threshold, 2000, X, y);

%% 测试准确度

[~, precious] = BPNNPredict(size_, W, X, y)

%% 画出决策边界

u = min(X(:, 1)) - 0.5: 0.1: max(X(:, 1)) + 0.5;

v = min(X(:, 2)) - 0.5: 0.1: max(X(:, 2)) + 0.5;

z = zeros(length(u), length(v));

for i = 1 : length(u)

   for j = 1 : length(v)

      [z(i, j), precious] = BPNNPredict(size_, W, [u(i), v(j)], 0); 

   end

end

z = z';

contour(u, v, z, [0.5, 0.5], 'LineWidth', 2);

hold off;

这是一个分类问题,可以使用逻辑回归的方法实现,可以参考博客:http://www.huqj.top/article?id=165  ,这里使用BP神经网络实现,最终决策边界如下。

在训练集上的准确度可以达到87%.BP神经网络相对于逻辑回归的优势就在于它不需要手动选择模型,而是通过训练可以自动选择一个合适的模型来模拟。

BP神经网络原理与matlab实现相关推荐

  1. BP神经网络原理及Matlab实现(Back Propagation Neural Networks,BPNN)

    BP神经网络原理及matlab实现 一.简介 1.BP 神经网络的信息处理方式的特点 2.BP神经网络的主要功能 二.神经网络的训练 1.神经网络拓扑结构(隐含层)的确定 2.网络的初始连接权值 3. ...

  2. BP神经网络原理简单介绍以及公式推导(矩阵形式和分量形式)

    BP神经网络原理简单介绍以及公式推导 标签(空格分隔): 神经网络 \def\net(#1){net^{(#1)}} \def\Y(#1){Y^{(#1)}} \def\part(#1){\parti ...

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

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

  4. bp神经网络原理 实现过程,BP神经网络的实现包括

    1.BP神经网络原理 人工神经网络有很多模型,但是日前应用最广.基本思想最直观.最容易被理解的是多层前馈神经网络及误差逆传播学习算法(Error Back-Prooaeation),简称为BP网络. ...

  5. BP神经网络原理分析及c++代码实现(下)

    本部分主要是BP神经网络的C++代码部分,在这里简单的介绍下代码的头文件,具体代码的实现以及测试数据,请在csdn资源里下载:http://download.csdn.net/detail/hjkhj ...

  6. BP神经网络预测回归MATLAB代码(代码完整可直接用,注释详细,可供学习)

    BP神经网络预测回归MATLAB代码(代码完整可直接用,注释详细,可供学习) 一.前言 二.代码部分 2.1 初始化 2.2 读取数据 2.3 设置训练集和测试集 2.4 数据归一化 2.5 求解最佳 ...

  7. BP神经网络原理及其应用,bp神经网络的工作原理

    1.BP神经网络的工作原理 人工神经网络就是模拟人思维的第二种方式.这是一个非线性动力学系统,其特色在于信息的分布式存储和并行协同处理.虽然单个神经元的结构极其简单,功能有限,但大量神经元构成的网络系 ...

  8. BP神经网络原理与异或实例分析

    文章目录 BP神经网络原理介绍 一.BP神经网络算法原理是什么? 二.激活函数 1.激活函数作用 三.BP神经网络异或实例分析 1.问题: 2.分析: 3.代码 总结 BP神经网络原理介绍 BP神经网 ...

  9. bp学习函数matlab代码,小范学数量经济学之四:BP神经网络预测的MATLAB模拟代码

    股票价格预测神器:BP神经网络预测的matlab模拟代码: 自动优选神经元个数: 自动迭代15000次,精度0.001: 代码运行效果图: 原始代码自此处开始: % 本代码由重庆科技学院范巧副教授于2 ...

最新文章

  1. 大盘点 | 2020年21篇医学影像算法最佳综述
  2. metasploit快速入门(一)安装部署
  3. C++中基类的析构函数为什么要用virtual虚析构函数
  4. C++实现深度优先搜索DFS(附完整源码)
  5. QT的QHash类的使用
  6. springboot+mybatis集成自定义缓存ehcache用法笔记
  7. .Net微服务实战之技术架构分层篇
  8. iOS开发内购图文教程
  9. mysql 8.0 一条insert语句的具体执行流程分析(三)
  10. 系统吞吐量评估方法 冯凌圣
  11. java webservice 客户端_Java Webservice客户端(最佳方法)
  12. Java实现将阿拉伯数字转换为中文数字123=》一二三
  13. 小猫钓鱼纸牌游戏 python
  14. Linux下解决qtcreator中不能输入中文的问题
  15. 【方便的Opencv】实现图片合成视频+附带图片生成gif
  16. Python beautifulsoup爬取小说
  17. 如何在Windows10下安装ubuntu双系统(无U盘)
  18. k8s报警 FailedCreatePodSandBox
  19. 南工程信通院—18年信号与系统试卷(有答案与解析)
  20. sql常用操作(含指定位置添加字段、修改到指定位置后等)

热门文章

  1. FlexiTimer2库下载 无偿 分享 仅供学习
  2. 朴树 vs. Lunar少女组,ET选的人你究竟爱谁?
  3. mysql 所有字符集_mysql字符集
  4. 浙里办前端H5对接小结(复盘自用)
  5. 设立分公司,还是子公司更省税
  6. R语言在图上标出点坐标_R语言绘制平行坐标图(PCP)示例
  7. UVA 1646 Edge Case
  8. java ssh免密登录_SSH免密登录(单信)
  9. 数据库操作之导入导出dmp
  10. oracle锁资源不够,Oracle解锁,解决“ora00054:资源正忙”错误