BP神经网络及Python实现

  • BP神经网网络原理
    • BP网络模型
    • BP学习算法
  • Python算法实现
    • 多层感知器基本参数设定

最近刚好在跟着课程一起学TensorFlow,顺道把整个神经网络的理论复习一遍,最后通过Python实现BP算法。

BP神经网网络原理

从个人理解,BP(反向传播)算法主要是一种求解多层“感知器”中连接权重的迭代方法。其基本思想是,学习信号由信号的正向传播和反向传播两个过程组成,输入信号由输入层传入,经过各隐藏层处理后,传出输出层,若输出层的实际输出与期望的输出不符合时,则转入反向传播阶段。误差反穿是将输出误差以某种形式通过隐藏层向输出层主城传递,并将误差分配给各层的所有单元,并以此信号作为修正各单元权值的依据。这个权值调整的过程就是网络学习训练的过程,这个过程可以一直进行到网络输入的误差减少到可接受的程度或者进行到预先设定的学习次数。

BP网络模型

如上图所示的单隐层网络是目前应用最为广泛的多层感知器神经网络。其中包括了最左侧的输入层,中间的隐藏层和最右侧的输出层。

在三层感知器中,输入向量为 X = ( x 1 , x 2 , ⋯   , x i , ⋯   , x n ) T \boldsymbol { X } = \left( x _ { 1 } , x _ { 2 } , \cdots , x _ { i } , \cdots , x _ { n } \right) ^ { \mathrm { T } } X=(x1​,x2​,⋯,xi​,⋯,xn​)T,其中 x 0 = − 1 x_{0} = -1 x0​=−1是为输出层神经元引入阈值而设置;隐藏层的输出向量为 Y = ( y 1 , y 2 , ⋯   , y i , ⋯   , y m ) T \boldsymbol { Y } = \left( y _ { 1 } , y _ { 2 } , \cdots , y _ { i } , \cdots , y _ { m } \right) ^ { \mathrm { T } } Y=(y1​,y2​,⋯,yi​,⋯,ym​)T,其中 y 0 = − 1 y_{0} = -1 y0​=−1 是输出层神经元阈值;输出层向量为 O = ( o 1 , o 2 , ⋯   , o i , ⋯   , o l ) T \boldsymbol { O } = \left( o _ { 1 } , o _ { 2 } , \cdots , o _ { i } , \cdots , o _ { l } \right) ^ { \mathrm { T } } O=(o1​,o2​,⋯,oi​,⋯,ol​)T:;期望输出向量为 D = ( d 1 , d 2 , ⋯   , d i , ⋯   , d m ) T \boldsymbol { D } = \left( d _ { 1 } , d _ { 2 } , \cdots , d _ { i } , \cdots , d _ { m } \right) ^ { \mathrm { T } } D=(d1​,d2​,⋯,di​,⋯,dm​)T。输入层到隐藏层之间的权值矩阵用 V \boldsymbol { V} V表示,其中列向量 V j \mathbf { V } _ { j } Vj​为隐藏层第j个神经元对应的权向量;隐层到输出层之间的权值矩阵用 W \boldsymbol { W} W表示,其中 W k \mathbf { W } _ { k } Wk​表示输出层第 k k k个神经元对应的权向量。下面分析各层输出的数学关系。

对于输出层,有:

o k = f ( net  k ) k = 1 , 2 , ⋯   , l o _ { k } = f \left( \text { net } _ { k } \right) \quad k = 1,2 , \cdots , l ok​=f( net k​)k=1,2,⋯,l
net  k = ∑ j = 0 m w j k y j k = 1 , 2 , ⋯   , l \text { net } _ { k } = \sum _ { j = 0 } ^ { m } w _ { j k } y _ { j } \quad k = 1,2 , \cdots , l  net k​=∑j=0m​wjk​yj​k=1,2,⋯,l

对于隐藏层,有:
y j = f ( net  j ) j = 1 , 2 , ⋯   , m y _ { j } = f \left( \text { net } _ { j } \right) \quad j = 1,2 , \cdots , m yj​=f( net j​)j=1,2,⋯,m
net  j = ∑ i = 0 n ν i j x i j = 1 , 2 , ⋯   , m \text { net } _ { j } = \sum _ { i = 0 } ^ { n } \nu _ { i j } x _ { i } \quad j = 1,2 , \cdots , m  net j​=∑i=0n​νij​xi​j=1,2,⋯,m
以上两式中,转移 f ( x ) f(x) f(x)函数采用单极性函数Sigmoid函数:
f ( x ) = 1 1 + e − x f ( x ) = \frac { 1 } { 1 + e ^ { - x } } f(x)=1+e−x1​
由于 f ( x ) f(x) f(x)具有连续,可导的特点,且有:
f ( x ) = f ( x ) [ 1 − f ( x ) ] f(x)=f(x)[1-f(x)] f(x)=f(x)[1−f(x)]

BP学习算法

当网络输出与期望输出不等时,存在输出误差E,定义如下:
E = 1 2 ( d − O ) 2 = 1 2 ∑ k = 1 l ( d k − o k ) 2 E = \frac { 1 } { 2 } ( d - O ) ^ { 2 } = \frac { 1 } { 2 } \sum _ { k = 1 } ^ { l } \left( d _ { k } - o _ { k } \right) ^ { 2 } E=21​(d−O)2=21​∑k=1l​(dk​−ok​)2
将上述误差定义展开至隐藏层,有:
E = 1 2 ∑ k = 1 l [ d k − f ( net  k ) ] 2 = 1 2 ∑ k = 1 l [ d k − f ( ∑ j = 0 m w j k y j ) ] 2 = 1 2 ∑ k = 1 l { d k − f [ ∑ j = 0 m w j k f ( n e t j ) ] } 2 = 1 2 ∑ k = 1 l { d k − f [ ∑ j = 0 m w j k f ( ∑ i = 0 n v i j x i ) ] } 2 E = \frac { 1 } { 2 } \sum _ { k = 1 } ^ { l } \left[ d _ { k } - f \left( \text { net } _ { k } \right) \right] ^ { 2 }= \frac { 1 } { 2 } \sum _ { k = 1 } ^ { l } \left[ d _ { k } - f \left( \sum _ { j = 0 } ^ { m } w _ { j k } y _ { j } \right) \right] ^ { 2 }=\frac { 1 } { 2 } \sum _ { k = 1 } ^ { l } \left\{ d _ { k } - f \left[ \sum _ { j = 0 } ^ { m } w _ { j k } f \left( \mathrm { net } _ { j } \right) \right] \right\} ^ { 2 }= \frac { 1 } { 2 } \sum _ { k = 1 } ^ { l } \left\{ d _ { k } - f \left[ \sum _ { j = 0 } ^ { m } w _ { j k } f \left( \sum _ { i = 0 } ^ { n } v _ { i j } x _ { i } \right) \right] \right\} ^ { 2 } E=21​∑k=1l​[dk​−f( net k​)]2=21​∑k=1l​[dk​−f(∑j=0m​wjk​yj​)]2=21​∑k=1l​{dk​−f[∑j=0m​wjk​f(netj​)]}2=21​∑k=1l​{dk​−f[∑j=0m​wjk​f(∑i=0n​vij​xi​)]}2
因此,网络误差是各层权值 w j k , v i j w _ { j k } , v _ { i j } wjk​,vij​的函数,因此调整权值可以改变误差。因此,调整权值的原则是使得误差不断地减小,采用最小梯度下降算法,则权值的调整量为:
Δ w j k = − η ∂ E ∂ w j k = − η ∂ E ∂ n e t k ∂ n e t k ∂ w j k \Delta w _ { j k } = - \eta \frac { \partial E } { \partial w _ { j k } }= - \eta \frac { \partial E } { \partial \mathrm { net } _ { k } } \frac { \partial \mathrm { net } _ { k } } { \partial w _ { j k } } Δwjk​=−η∂wjk​∂E​=−η∂netk​∂E​∂wjk​∂netk​​
Δ v i j = − η ∂ E ∂ v i j = − η ∂ E ∂ net  j ∂ net  j ∂ v i j \Delta v _ { i j } = - \eta \frac { \partial E } { \partial v _ { i j } } =- \eta \frac { \partial E } { \partial \text { net } _ { j } } \frac { \partial \text { net } _ { j } } { \partial v _ { i j } } Δvij​=−η∂vij​∂E​=−η∂ net j​∂E​∂vij​∂ net j​​
在推导过程中,对于输出层,均有 j = 0 , 1 , 2 , ⋯   , m , k = 1 , 2 , ⋯   , l j = 0,1,2 , \cdots , m , k = 1,2 , \cdots , l j=0,1,2,⋯,m,k=1,2,⋯,l,对隐藏层具有 i = 0 , 1 , 2 , ⋯   , n , j = 1 , 2 , ⋯   , m i = 0,1,2 , \cdots , n , j = 1,2 , \cdots , m i=0,1,2,⋯,n,j=1,2,⋯,m
对于输出层和隐藏层定义一个误差信号,令:
δ k ∘ = − ∂ E ∂ n e t k = − ∂ E ∂ o k ∂ o k ∂ n e t k = − ∂ E ∂ o k f ′ ( n e t k ) \delta _ { k } ^ { \circ } = - \frac { \partial E } { \partial \mathrm { net } _ { k } } = - \frac { \partial E } { \partial o _ { k } } \frac { \partial o _ { k } } { \partial \mathrm { net } _ { k } } = - \frac { \partial E } { \partial o _ { k } } f ^ { \prime } \left( \mathrm { net } _ { k } \right) δk∘​=−∂netk​∂E​=−∂ok​∂E​∂netk​∂ok​​=−∂ok​∂E​f′(netk​)
δ j y = − ∂ E ∂ n e t j = − ∂ E ∂ y j ∂ y j ∂ n e t j = − ∂ E ∂ y j f ′ ( n e t j ) \delta _ { j } ^ { y } = - \frac { \partial E } { \partial \mathrm { net } _ { j } } = - \frac { \partial E } { \partial y _ { j } } \frac { \partial y _ { j } } { \partial \mathrm { net } _ { j } } = - \frac { \partial E } { \partial y _ { j } } f ^ { \prime } \left( \mathrm { net } _ { j } \right) δjy​=−∂netj​∂E​=−∂yj​∂E​∂netj​∂yj​​=−∂yj​∂E​f′(netj​)
则,可以将权值调制为:
Δ w j k = η δ k o y j \Delta w _ { j k } = \eta \delta _ { k } ^ { o } y _ { j } Δwjk​=ηδko​yj​
Δ v i j = η δ j y x i \Delta v _ { i j } = \eta \delta _ {j } ^ { y } x _ { i } Δvij​=ηδjy​xi​
对于输出层,有:
∂ E ∂ o k = − ( d k − o k ) \frac { \partial E } { \partial o _ { k } } = - \left( d _ { k } - o _ { k } \right) ∂ok​∂E​=−(dk​−ok​)
对于隐藏层,有:
∂ E ∂ y j = − ∑ k = 1 l ( d k − o k ) f ′ ( net  k ) w j k \frac { \partial E } { \partial y _ { j } } = - \sum _ { k = 1 } ^ { l } \left( d _ { k } - o _ { k } \right) f ^ { \prime } \left( \text { net } _ { k } \right) w _ { j k } ∂yj​∂E​=−∑k=1l​(dk​−ok​)f′( net k​)wjk​
将结果带入上式得:
δ k ∘ = ( d k − o k ) o k ( 1 − o k ) \delta _ { k } ^ { \circ } = \left( d _ { k } - o _ { k } \right) o _ { k } \left( 1 - o _ { k } \right) δk∘​=(dk​−ok​)ok​(1−ok​)
δ j k = [ ∑ k = 1 t ( d k − o k ) f ′ ( net  k ) w j k ] f ′ ( net  j ) = ( ∑ k = 1 l δ k ∘ w j k ) y j ( 1 − y j ) \begin{aligned} \delta _ { j } ^ {k } & = \left[ \sum _ { k = 1 } ^ { t } \left( d _ { k } - o _ { k } \right) f ^ { \prime } \left( \text { net } _ { k } \right) w _ { j k } \right] f ^ { \prime } \left( \text { net } _ { j } \right) \\ & = \left( \sum _ { k = 1 } ^ { l } \delta _ { k } ^ { \circ } w _ { j k } \right) y _ { j } \left( 1 - y _ { j } \right) \end{aligned} δjk​​=[k=1∑t​(dk​−ok​)f′( net k​)wjk​]f′( net j​)=(k=1∑l​δk∘​wjk​)yj​(1−yj​)​
因此三层感知器的BP学习算法调整权值公式为:
{ Δ w j k = η δ k o y j = η ( d k − o k ) o k ( 1 − o k ) y j Δ v i j = η δ y ; x i = η ( ∑ k = 1 l δ k ∘ w j k ) y j ( 1 − y j ) x i \left\{ \begin{array} { l } { \Delta w _ { j k } = \eta \delta _ { k } ^ { o } y _ { j } = \eta \left( d _ { k } - o _ { k } \right) o _ { k } \left( 1 - o _ { k } \right) y _ { j } } \\ { \Delta v _ { i j } = \eta \delta ^ { y } ; x _ { i } = \eta \left( \sum _ { k = 1 } ^ { l } \delta _ { k } ^ { \circ } w _ { j k } \right) y _ { j } \left( 1 - y _ { j } \right) x _ { i } } \end{array} \right. {Δwjk​=ηδko​yj​=η(dk​−ok​)ok​(1−ok​)yj​Δvij​=ηδy;xi​=η(∑k=1l​δk∘​wjk​)yj​(1−yj​)xi​​

Python算法实现

多层感知器基本参数设定

Python采用Python3.6版本,分析数据采用sklearn库中的car数据集。该数据集共有6个特征,共被分成4类。故n=6,l=4,为防止模型过于复杂,训练时间太长,选定隐藏层的神经元数量m=5.

需要注意的是此代码可以成功运行,但准确率并不是很高,整体代码逻辑需要修改

import numpy as np
import sklearn.preprocessing as preprocessing
from sklearn.utils import shuffle
from sklearn.model_selection import  train_test_splitdef sigmoid(x):  # 激活函数return 1 / (1 + np.exp(-x))
def dsigmoid(x):#sigmoid的倒数return x*(1-x)class NeuralNetwork:def __init__(self,layers):self.v=np.ones((layers[1],layers[0]+1))self.w=np.ones((layers[2],layers[1]+1))def train(self,x,y,lr=0.1,epochs=10000):xtrain=np.ones((x.shape[0],x.shape[1]+1))#进行权值更新训练for n in range(epochs+1):i=np.random.randint(x_train.shape[0])xtrain=np.atleast_2d(x_train[i]).Tytrain=np.atleast_2d(y_train[i]).TL1=sigmoid(np.dot(self.v,xtrain))L1_hat=np.ones((L1.shape[0]+1,1))L1_hat[0:-1]=L1L2=sigmoid(np.dot(self.w,L1_hat))Delta=(ytrain-L2)*L2*(1-L2)delW=np.dot(Delta,L1_hat.T)delV=np.dot(np.dot(Delta.T,self.w[:,0:-1]).T*L1*(1-L1),xtrain.T)self.w+=delWself.v+=delVif n%1000==0:prediction=[]for j in range(x_test.shape[0]):out=self.predict(x_test[j])prediction.append(np.argmax(out))accuracy=np.mean(np.equal(prediction,y_test))print("epoch:",n,"accurayc",accuracy)def predict(self,x):x=np.atleast_2d(x)L1 = sigmoid(np.dot(self.v, x.T))L1_hat = np.ones((L1.shape[0]+1, 1))L1_hat[0:-1] = L1L2 = sigmoid(np.dot(self.w, L1_hat))return L2data=open("J:\研究生生活\课件\华为云TensorFlow\华为TensorFlow代码及教学文件\day1_exercise\homework\data\car.data")
datas=data.readlines()
x=[]
y=[]
for line in datas:line_list=line.strip().split(',')x.append(line_list[:-1])y.append(line_list[-1])
x=np.array(x)label_encoder=preprocessing.LabelBinarizer()
label_encoder.fit(['unacc','acc','good','vgood'])
y_endoded=label_encoder.transform(y)
x_encoded=np.empty(x.shape)
xlabeltrans=[]
for i,item in enumerate(x[0]):xlabeltrans.append(preprocessing.LabelEncoder())x_encoded[:,i]=xlabeltrans[-1].fit_transform(x[:,i])
x_encoded=np.hstack((x_encoded,np.ones((x_encoded.shape[0],1))))
x=x_encoded[:,:-1].astype(int)
x,y=shuffle(x,y,random_state=0)
x_train,x_test,y_train,y_test=train_test_split(x_encoded,y_endoded,test_size=0.25)
y_test=[np.argmax(i) for i in y_test]nm=NeuralNetwork([6,5,4])
nm.train(x_train,y_train,epochs=20000)

BP神经网络原理及Python实现相关推荐

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

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

  2. 【机器学习】RBF神经网络原理与Python实现

    [机器学习]RBF神经网络原理与Python实现 一.RBF神经网络原理 1. RBF神经网络结构与RBF神经元 2. RBF神经网络求解 2.1 正向传播:计算误差 2.2 反向传播:调整参数 二. ...

  3. BP神经网络原理及实现

    BP神经网络原理 经典的BP神经网络通常由三层组成: 输入层, 隐含层与输出层.通常输入层神经元的个数与特征数相关,输出层的个数与类别数相同, 隐含层的层数与神经元数均可以自定义. 每个神经元代表对数 ...

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

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

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

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

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

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

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

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

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

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

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

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

最新文章

  1. java 使用正则表达式从网页上提取网站标题
  2. PHP复杂度,php 算法复杂度 时间复杂度 空间复杂度
  3. 题目1493:公约数
  4. 成功解决Runtime Error Selected KDE bandwidth is 0. Cannot estiam
  5. 到底什么是P问题,NP问题,NPC问题,NP-hard问题?什么是规约(或约化)?
  6. .Net中DataTable的保存
  7. Web前端开发规范手册
  8. Spring Web MVC 支持最新的API
  9. 分布式缓存——缓存与数据库数据一致性
  10. 从程序员角度看ELF
  11. Eureka自我保护机制
  12. Sql为什么连接不上服务器上的数据库
  13. Router.use() requires a middleware function but got a Object
  14. 易语言 html替换,易语言教程文本替换和子文本替换
  15. VMware虚拟机通过光盘PE安装GHOSTxp
  16. 计算机硬件 - 主板
  17. 看_那人好像一个产品狗_对_这就是产品狗
  18. m4a怎么转换成mp3,m4a转mp3方法
  19. Nginx+Tomcat负载均衡、动静分离
  20. Depix:还原马赛克工具的试用及总结

热门文章

  1. 快速了解 Java 线上问题快速诊断神器 Arthas
  2. 基于OpenCV的音频频谱优化(仿酷狗频谱)
  3. HTML5+app开发学习之调试篇
  4. 删除文件后,磁盘可用空间并没有释放怎么办?
  5. Motorola和Borland结成联盟,以帮助开发者为Motorola下一代无线电话创建应用程序 (转)...
  6. ping主机时显示 Request Time Out Destination Unreachable TTL Expired in transit
  7. Vue网易云播放器开发
  8. Sql语句中的DDL、DML、DCL的介绍
  9. Unity程序框架总结归置系列(2)——对象池
  10. Object.assign()的使用和注意