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

  • 摘要
  • (一)BP神经网络简介
    • 1、神经网络权值调整的一般形式为:
    • 2、BP神经网络中关于学习信号的求取方法:
  • (二)BP神经网络原理推导
    • 1、变量说明
    • 2、BP算法推导
  • (三)BP神经网络python实现
    • 1、模型所需传参介绍
    • 2、模型具有的主要方法和属性
    • 3、python代码
    • 4、代码运行结果

摘要

本文首先介绍了BP神经网络求取学习信号的方法,其次对BP神经网络在原理上进行了推导,最后在python上进行编程实现,并将其封装,方便读者直接调用。

(一)BP神经网络简介

BP神经网络是整个神经网络体系中的精华,与一般神经网络相比,它调整权值方式为从最后一层开始逐层调整,通过多次迭代,使得代价函数降低至可接受范围。因此,这就是BP神经网络的来源(Back Propagation,误差反向传播)。

1、神经网络权值调整的一般形式为:


(1)其中 η为学习率,可以理解为每次权值调整的步长
(2)其中δ为学习信号,可以理解为每次权值调整的方向,实际上为一个梯度向量。
由上式也可以发现不同神经网络的差异主要体现在学习信号上的差异。

2、BP神经网络中关于学习信号的求取方法:

假设一个神经网络共n层

上式为求取最后一层,即输出层的学习信号,其中t为期望输出,y为模型输出,f(x)为激活函数(对激活函数不了解的可自行先百度或查看我的其他文章)。

上式为求取除最后一层以外其他层的学习信号,i+1表示第i层后面的一层,可以发现求取第i层学习信号时,需要先求取出第i+1层的学习信号,这也是误差反向传播的来源。
具体BP神经网络的学习信号推导过程见以下的原理推导,推导过程有点小复杂,即使不看,根据以上的结论也可以编写自己的BP神经网络程序了。

(二)BP神经网络原理推导

1、变量说明

(1)以三层感知器构成的神经网络为例(实际为两层神经网络)。

(2)定义各层的输入和输出:
输入向量
隐含层输出向量
输出层输出向量
期望输出向量

(3)定义权值矩阵:
输入层到隐含层的权值矩阵
隐含层到输出层的权值矩阵

(4)设定激活函数

2、BP算法推导

(1)构建计算输出层输出的函数

(2)构建计算隐含层输出的函数

(3)定义代价函数

(4)式9中x与d分别为输入与对应的期望输出,皆为已知,所以代价函数则为两个权值矩阵的函数,为了使代价函数减小,权值的调整应往负梯度方向调整,如下:(η为学习率,可以理解为往负梯度方向改变的步长)

(5)将式10和式11按链式求导法则进行展开:

(6)对输出层和隐含层各定义一个误差信号(本质上为负梯度)

(7)将式14和式15代入式12和式13,得:

(8)求解输出层和隐含层的学习信号(需结合式1和式3):

(9)计算式18和19中的偏导:

(10)将式20和式21带回式18和19:

(11)将式22)和式23带回式16和17,得:

(12)将三层感知器推广到任意层数神经网络:
假设神经网络共n层。

(三)BP神经网络python实现

如果读者想自己动手在python上实现BP神经网络的话,可以根据文章给出的关于学习信号的求取方法进行编程,本文给出了自己的实现代码,且将其封装成一个类,基本上的属性和方法都具有,通用性较强,读者既可调用其来训练自己的模型,也可以参考其架构自行编写代码。

1、模型所需传参介绍

layer 为神经网络各层神经元的个数,包括输出层神经元个数,传参形式以列表传入;
activate:为各层的激活函数,传参形式为字符串或列表,若传入一个字符串,则各层激活函数相同,若传入一个列表,则列表元素代表各层激活函数可传参数有:(1)sigmoid:S型函数(2)tanh:双曲正弦函数(3)relu:max(0,x)函数(4)purline:线性函数(5)softsign:平滑函数lr:学习率,默认为0.01
epoch:最大迭代次数 默认为1e4

2、模型具有的主要方法和属性

fit(X,Y):模型拟合方法
predict(X):输出预测方法
predict_label(X):分类标签输出预测方法
activate:激活函数列表
W:权值列表

3、python代码

import numpy as np
import time
class Cyrus_BP(object):"""layer 为神经网络各层神经元的个数,包括输出层神经元个数,传参形式以列表传入;activate:为各层的激活函数,传参形式为字符串或列表,若传入一个字符串,则各层激活函数相同,若传入一个列表,则列表元素代表各层激活函数可传参数有:(1)sigmoid:S型函数(2)tanh:双曲正弦函数(3)relu:max(0,x)函数(4)purline:线性函数(5)softsign:平滑函数lr:学习率,默认为0.01epoch:最大迭代次数 默认为1e4该模型具有的主要方法和属性如下:fit(X,Y):模型拟合方法predict(X):输出预测方法predict_label(X):分类标签输出预测方法activate:激活函数列表W:权值列表"""def __init__(self,layer,**kargs):self.layer = np.array(layer).reshape(1,-1)if 'activate' in kargs.keys():if str(type(kargs["activate"])) == "<class 'str'>":    self.activate = [kargs["activate"]]*int(len(layer))else:self.activate = kargs["activate"]else:self.activate = ["sigmoid"]*int(len(layer))self.diff_activate = []if 'lr' in kargs.keys():self.lr = kargs["lr"]else:self.lr = 0.01if 'epoch' in kargs.keys():self.epoch = kargs["epoch"]else:self.epoch = int(1e4)self.X = Noneself.Y = Noneself.W = Noneself.output = []self.delta = []self.sum_input = []# 1、选择激活函数def activation_func(self):temp_func = []for i in range(len(self.activate)):if self.activate[i] == "sigmoid":temp_func.append(lambda x:1/(1+np.exp(-x)))self.diff_activate.append(lambda x:(1/(1+np.exp(-x)))*(1-(1/(1+np.exp(-x)))))if self.activate[i] == "tanh":temp_func.append(lambda x:(np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x)))self.diff_activate.append(lambda x:((-np.exp(x) + np.exp(-x))*(np.exp(x) - np.exp(-x))/(np.exp(x) + np.exp(-x))**2 + 1))if self.activate[i] == "softsign":temp_func.append(lambda x:x/(1+np.abs(x)))self.diff_activate.append(lambda x:1/((1+x/np.abs(x)*x)**2))if self.activate[i] == "relu":temp_func.append(lambda x:(x+np.abs(x))/(2*np.abs(x))*x)self.diff_activate.append(lambda x:(x+np.abs(x))/(2*np.abs(x)))if self.activate[i] == "purline":temp_func.append(lambda x:x)self.diff_activate.append(lambda x:1+x-x)self.activate = temp_func# 2、权值初始化函数def init_w(self):self.W = []for i in range(self.layer.shape[1]):if i == 0:w = np.random.random([self.X.shape[1]+1,self.layer[0,i]])*2-1else:w = np.random.random([self.layer[0,i-1]+1,self.layer[0,i]])*2-1self.W.append(w)# 3、权值调整函数def update_w(self):# 1 计算各层输出值self.output = []self.sum_input = []for i in range(self.layer.shape[1]):if i == 0:temp = np.dot(np.hstack((np.ones((self.X.shape[0],1)),self.X)),self.W[i])self.sum_input.append(temp)self.output.append(self.activate[i](temp))else:temp = np.dot(np.hstack((np.ones((self.output[i-1].shape[0],1)),self.output[i-1])),self.W[i])self.sum_input.append(temp)self.output.append(self.activate[i](temp))# 2 求每层的学习信号self.delta = [0 for i in range(len(self.output))]for i in range(len(self.output)):if i == 0:self.delta [-i-1] = ((self.Y-self.output[-i-1])*self.diff_activate[-i-1](self.sum_input[-i-1]))else:self.delta [-i-1] = ((self.delta[-i].dot(self.W[-i][1:,:].T))*self.diff_activate[-i-1](self.sum_input[-i-1]))# 3 更新权值for i in range(len(self.W)):if i == 0 :self.W[i] += self.lr * np.hstack((np.ones((self.X.shape[0],1)),self.X)).T.dot(self.delta[i])else:self.W[i] += self.lr * np.hstack((np.ones((self.output[i-1].shape[0],1)),self.output[i-1])).T.dot(self.delta[i])def fit(self,X,Y):self.X = np.array(X)self.Y = np.array(Y)# 1 权值初始化self.init_w()# 2 选择激活函数self.activation_func()# 3 更新权值start_time = time.time()for i in range(int(self.epoch)):self.update_w()end_time = time.time()if end_time - start_time >= 5:print("Epoch%d:"%(i+1),np.mean(np.square(self.Y-self.output[-1])))print("\n")start_time = time.time()def predict(self,x):x = np.array(x)result = []for i in range(self.layer.shape[1]):if i == 0:result.append(self.activate[i](np.dot(np.hstack((np.ones((x.shape[0],1)),x)),self.W[i])))else:result.append(self.activate[i](np.dot(np.hstack((np.ones((result[i-1].shape[0],1)),result[i-1])),self.W[i])))return result[-1]def predict_label(self,x):x = np.array(x)result = []for i in range(self.layer.shape[1]):if i == 0:result.append(self.activate[i](np.dot(np.hstack((np.ones((x.shape[0],1)),x)),self.W[i])))else:result.append(self.activate[i](np.dot(np.hstack((np.ones((result[i-1].shape[0],1)),result[i-1])),self.W[i])))result = result[-1]   return np.array([result[i].argmax() for i in range(result.shape[0])]).reshape(-1,1)if __name__ == "__main__":bp = Cyrus_BP([50,10,3],lr=0.01,epoch = 2e5,activate = ["softsign","softsign","softsign"])from sklearn.datasets import load_irisfrom sklearn.metrics import accuracy_scoredata = load_iris()X = data["data"]Y = data["target"]import pandas as pd# 用神经网络进行分类时,需把输出先进行独热编码Y1 = pd.get_dummies(Y1) # 进行独热编码或将期望输出转换为哑变量bp.fit(X,Y1)Y_pre = bp.predict_label(X)print("准确率为:",accuracy_score(Y,Y_pre))

4、代码运行结果

Epoch9314: 0.02853577904298399Epoch19691: 0.02145897246261971Epoch31495: 0.01784770845276102Epoch42539: 0.01415043927077651Epoch53434: 0.015407038745481208Epoch64893: 0.016390764988851683Epoch76186: 0.015016316993973523Epoch86931: 0.013693150044879728Epoch97390: 0.013706384360315056Epoch108511: 0.012193768543380657Epoch118993: 0.010314480349340294Epoch128337: 0.009862103298377766Epoch138193: 0.01057658278951552Epoch147889: 0.009652582210903272Epoch157632: 0.009137051214565095Epoch165815: 0.009407398018203143Epoch175037: 0.009429640020604707Epoch185229: 0.00991562156191445Epoch194220: 0.009801710064963167
准确率为: 0.9933333333333333

可见模型训练结果还是不错的

by CyrusMay 2020 05 11

晚风吻尽 荷花叶
任我醉倒在池边
等你清楚看见我的美
月光晒干眼泪

——五月天(拥抱)——

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

  1. bp 神经网络 优点 不足_深度学习之BP神经网络--Stata和R同步实现(附Stata数据和代码)

    说明:本文原发于"计量经济圈"公众号,在此仅展示Stata的部分.R部分请移步至本人主页的"R语言与机器学习--经济学视角"专栏,或点击下方链接卡跳转. 盲区行 ...

  2. [深度学习-实践]BP神经网络的Helloworld(手写体识别和Fashion_mnist)

    前言 原理部分请看这里 [深度学习-原理]BP神经网络 Tensorflow2 实现一个简单的识别衣服的例子 数据集Fashion_mnist, 此数据集包含10类型的衣服 ('T-shirt/top ...

  3. 深度学习之BP神经网络

    前言 bp神经网络是模拟人体中神经元结构而设计出来的:   神经元大致可以分为树突.突触.细胞体和轴突.树突为神经元的输入通道,其功能是将其它神经元的动作电位传递至细胞体.其它神经元的动作电位借由位于 ...

  4. 深度学习基础: BP神经网络训练MNIST数据集

    BP 神经网络训练MNIST数据集 不用任何深度学习框架,一起写一个神经网络训练MNIST数据集 本文试图让您通过手写一个简单的demo来讨论 1. 导包 import numpy as np imp ...

  5. 解析深度学习:卷积神经网络原理与视觉实践

    解析深度学习:卷积神经网络原理与视觉实践 魏秀参 著 ISBN:9787121345289 包装:平装 开本:16开 正文语种:中文 出版社: 电子工业出版社 出版时间:2018-11-01

  6. 深度学习之循环神经网络(2)循环神经网络原理

    深度学习之循环神经网络(2)循环神经网络原理 1. 全连接层 2. 共享权值 3. 全局语义 4. 循环神经网络  现在我们来考虑如何吃力序列信号,以文本序列为例,考虑一个句子: "I di ...

  7. 零基础入门深度学习(5) - 循环神经网络

    往期回顾 在前面的文章系列文章中,我们介绍了全连接神经网络和卷积神经网络,以及它们的训练和使用.他们都只能单独的取处理一个个的输入,前一个输入和后一个输入是完全没有关系的.但是,某些任务需要能够更好的 ...

  8. 零基础入门深度学习(5) - 循环神经网络【转】

    本文转载自:https://zybuluo.com/hanbingtao/note/541458 在前面的文章系列文章中,我们介绍了全连接神经网络和卷积神经网络,以及它们的训练和使用.他们都只能单独的 ...

  9. 深度学习之卷积神经网络(11)卷积层变种

    深度学习之卷积神经网络(11)卷积层变种 1. 空洞卷积 2. 转置卷积 矩阵角度 转置卷积实现 3. 分离卷积 卷积神经网络的研究产生了各种各样优秀的网络模型,还提出了各种卷积层的变种,本节将重点介 ...

最新文章

  1. 6行Python代码实现进度条效果(Progress、tqdm、alive-progress​​​​​​​和PySimpleGUI库)
  2. 一套基于 SpringBoot 的完整高并发电商系统,拿去面试简直不要太好用!
  3. 整理对应_JSP第二版课后习题答案【侵权联系我删除】
  4. 推荐算法实现之BMF(pymc3+MovieLen)
  5. 带入gRPC:gRPC Streaming, Client and Server
  6. 李松南:智能全真时代的多媒体技术——关于8K、沉浸式和人工智能的思考
  7. Linux带给了我什么?
  8. 微信不再提供小程序打开App?借助H5为App引流的方式你必须知道!
  9. python的类是什么_Python类(class)
  10. VO中的Long类型数据通过注解的方式直接转换为String,防止数据失真
  11. 【模版】求单个/多个欧拉函数值
  12. SmartSens在ISSCC 2019 图像传感器技术领域报告会作开场报告,收录论文抢先披露
  13. android笔画输入法的字库,献给爱好笔画输入的机友们 速度才是王道之大众码新笔画输入法...
  14. 计算机考研复试-《数据库》篇
  15. 高老师的架构设计_隽语集(CC_1051)
  16. for (char c : s)这种循环方式的使用
  17. leetcode 1103分糖果II
  18. 数据分析方法-描述性统计分析
  19. Java实现蓝桥杯勾股定理
  20. cmd导入导出mysql中的数据库为sql文件

热门文章

  1. Spring Boot 配置加载顺序详解
  2. 如何实现一个Java Class解析器
  3. 框架:Mybatis开发规范及输入输出映射配置时注意事件
  4. Java 大数类BigInteger与BigDecimal详细介绍(配蓝桥杯例题讲解)
  5. 微型计算机只能使用机器语言,道计算机等级考试精选题全.doc
  6. 正在CPU上运行的进程_进程的概念,系统资源分配的单元
  7. android的动态注册,Android应用开发之BroadcastReceiver(广播)的静态注册和动态注册 --Android开发...
  8. 数据中心日常维护工作有哪些?
  9. ML之分类预测:分类预测评估指标之AUC计算的的两种函数具体代码案例实现
  10. 成功解决AttributeError: module 'tensorflow.python.ops.nn' has no attribute '_seq2seq'