神经网络——Python实现BP神经网络算法(理论+例子+程序)

神经网络——Python实现BP神经网络算法(理论+例子+程序)一、基于BP算法的多层感知器模型采用BP算法的多层感知器是至今为止应用最广泛的神经网络,在多层感知器的应用中,以图3-15所示的单隐层网络的应用最为普遍。一般习惯将单隐层前馈网称为三层感知器,所谓三层包括了输入层、隐层和输出层。算法最终结果采用梯度下降法,具体详细过程此处就省略了!二、BP算法的程序实现流程三、标准BP算法的改进——增加动量项标准BP算法在调整权值时,只按t时刻误差的梯度降方向调整,而没有考虑t时刻以前的梯度方向,从而常使训练过程发生振荡,收敛缓慢。为了提

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一、基于BP算法的多层感知器模型

采用BP算法的多层感知器是至今为止应用最广泛的神经网络,在多层感知器的应用中,以图3-15所示的单隐层网络的应用最为普遍。一般习惯将单隐层前馈网称为三层感知器,所谓三层包括了输入层、隐层和输出层。

神经网络——Python实现BP神经网络算法

神经网络——Python实现BP神经网络算法

算法最终结果采用梯度下降法,具体详细过程此处就省略了!

二、BP算法的程序实现流程

神经网络——Python实现BP神经网络算法

三、标准BP算法的改进——增加动量项

标准BP算法在调整权值时,只按t时刻误差的梯度降方向调整,而没有考虑t时刻以前的梯度方向,从而常使训练过程发生振荡,收敛缓慢。为了提高网络的训练速度,可以在权值调整公式中增加一动量项。若用W代表某层权矩阵,X代表某层输入向量,则含有动量项的权值调整向量表达式为

神经网络——Python实现BP神经网络算法

可以看出,增加动量项即从前一次权值调整量中取出一部分迭加到本次权值调整量中,α称为动量系数,一般有a∈ (0,1)。动量项反映了以前积累的调整经验,对于t时刻的调整起阻尼作用。当误差曲面出现骤然起伏时,可减小振荡趋势,提高训练速度。目前,BP算法中都增加了动量项,以致于有动量项的BP算法成为一种新的标准算法。

四、Python实现BP神经网络及其学习算法

这里为了运用算法,简要的举了一个例子(不需归一化或标准化的例子)

输入 X=-1:0.1:1;
输出 D=…..(具体查看代码里面的数据)

为了便于查看结果我们输出把结果绘制为图形,如下:

神经网络——Python实现BP神经网络算法

其中黄线和蓝线代表着训练完成后的输出与输入

五、程序如下:

# -*- coding: utf-8 -*-
import math
import string
import matplotlib as mpl
############################################调用库(根据自己编程情况修改)
import numpy.matlib 
import numpy as np
np.seterr(divide='ignore',invalid='ignore')
import matplotlib.pyplot as plt
from matplotlib import font_manager
import pandas as pd
import random

#生成区间[a,b]内的随机数
def random_number(a,b):
    return (b-a)*random.random()+a
 
#生成一个矩阵,大小为m*n,并且设置默认零矩阵
def makematrix(m, n, fill=0.0):
    a = []
    for i in range(m):
        a.append([fill]*n)
    return np.array(a)
 
#函数sigmoid(),两个函数都可以作为激活函数
def sigmoid(x):
    #return np.tanh(x)
    return (1-np.exp(-1*x))/(1+np.exp(-1*x))
#函数sigmoid的派生函数
def derived_sigmoid(x):
    return 1-(np.tanh(x))**2
    #return (2*np.exp((-1)*x)/((1+np.exp(-1*x)**2)))

#构造三层BP网络架构
class BPNN:
    def __init__(self, num_in, num_hidden, num_out):
        #输入层,隐藏层,输出层的节点数
        self.num_in = num_in + 1  #增加一个偏置结点
        self.num_hidden = num_hidden + 1   #增加一个偏置结点
        self.num_out = num_out
        
        #激活神经网络的所有节点(向量)
        self.active_in = np.array([-1.0]*self.num_in)
        self.active_hidden = np.array([-1.0]*self.num_hidden)
        self.active_out = np.array([1.0]*self.num_out)
        
        #创建权重矩阵
        self.wight_in = makematrix(self.num_in, self.num_hidden)
        self.wight_out = makematrix(self.num_hidden, self.num_out)
        
        #对权值矩阵赋初值
        for i in range(self.num_in):
            for j in range(self.num_hidden):
                self.wight_in[i][j] = random_number(0.1, 0.1)
        for i in range(self.num_hidden):
            for j in range(self.num_out):
                self.wight_out[i][j] = random_number(0.1, 0.1)
        #偏差
        for j in range(self.num_hidden):
            self.wight_in[0][j] = 0.1
        for j in range(self.num_out):
            self.wight_in[0][j] = 0.1

    
        #最后建立动量因子(矩阵)
        self.ci = makematrix(self.num_in, self.num_hidden)
        self.co = makematrix(self.num_hidden, self.num_out)      
        

    #信号正向传播
    def update(self, inputs):
        if len(inputs) != self.num_in-1:
            raise ValueError('与输入层节点数不符')
        #数据输入输入层
        self.active_in[1:self.num_in]=inputs
        
        #数据在隐藏层的处理
        self.sum_hidden=np.dot(self.wight_in.T,self.active_in.reshape(-1,1)) #点乘
        self.active_hidden=sigmoid(self.sum_hidden)   #active_hidden[]是处理完输入数据之后存储,作为输出层的输入数据
        self.active_hidden[0]=-1
            
        #数据在输出层的处理
        self.sum_out=np.dot(self.wight_out.T,self.active_hidden) #点乘
        self.active_out = sigmoid(self.sum_out)   #与上同理
        return self.active_out

 
    #误差反向传播
    def errorbackpropagate(self, targets, lr,m):   #lr是学习率
        if self.num_out==1:
            targets=[targets]
        if len(targets) != self.num_out:
            raise ValueError('与输出层节点数不符!')
        #误差
        error=(1/2)*np.dot((targets.reshape(-1,1)-self.active_out).T,(targets.reshape(-1,1)-self.active_out))
        
        #输出误差信号
        self.error_out=(targets.reshape(-1,1)-self.active_out)*derived_sigmoid(self.sum_out)
        #隐层误差信号
        #self.error_hidden=np.dot(self.wight_out.reshape(-1,1),self.error_out.reshape(-1,1))*self.active_hidden*(1-self.active_hidden)
        self.error_hidden=np.dot(self.wight_out,self.error_out)*derived_sigmoid(self.sum_hidden)

        #更新权值
        #隐藏
        self.wight_out=self.wight_out+lr*np.dot(self.error_out,self.active_hidden.reshape(1,-1)).T+m*self.co
        self.co=lr*np.dot(self.error_out,self.active_hidden.reshape(1,-1)).T
        #输入
        self.wight_in=self.wight_in+lr*np.dot(self.error_hidden,self.active_in.reshape(1,-1)).T+m*self.ci
        self.ci=lr*np.dot(self.error_hidden,self.active_in.reshape(1,-1)).T
        return error

    #测试
    def test(self, patterns):
        for i in patterns:
            print(i[0:self.num_in-1], '->', self.update(i[0:self.num_in-1]))
        return self.update(i[0:self.num_in-1])

    #权值
    def weights(self):
        print("输入层权重")
        print(self.wight_in)
        print("输出层权重")
        print(self.wight_out)
            
    def train(self, pattern, itera=100, lr = 0.2, m=0.1):
        for i in range(itera):
            error = 0.0
            for j in pattern:
                inputs = j[0:self.num_in-1]
                targets = j[self.num_in-1:]
                self.update(inputs)
                error = error+self.errorbackpropagate(targets, lr,m)
            if i % 10 == 0:
                print('########################误差 %-.5f######################第%d次迭代' %(error,i))

#实例
X=list(np.arange(-1,1.1,0.1))
D=[-0.96, -0.577, -0.0729, 0.017, -0.641, -0.66, -0.11, 0.1336, -0.201, -0.434, -0.5, -0.393, -0.1647, 0.0988, 0.3072, 0.396, 0.3449, 0.1816, -0.0312, -0.2183, -0.3201]
A=X+D
patt=np.array([A]*2)
    #创建神经网络,21个输入节点,21个隐藏层节点,1个输出层节点
n = BPNN(21, 21, 21)
    #训练神经网络
n.train(patt)
    #测试神经网络
d=n.test(patt)
    #查阅权重值
n.weights() 

plt.plot(X,D)
plt.plot(X,d)
plt.show()

来源:小凌のBlog—Good Times|一个不咋地的博客

[1]   韩力群,人工神经网络理论及应用 [M]. 北京:机械工业出版社,2016.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196966.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • latex中双引号和单引号的正确应用[通俗易懂]

    latex中双引号和单引号的正确应用[通俗易懂]用输入法中的中文模式键入的双引号和单引号并不是LaTeX的正确输入方式。正确的输入方法如下:使用键盘的Tab键上侧的连续键入两个“然后输入键盘的双引号’’。单引号输入类似。示例如下:演示代码:\documentclass{article}\setlength\textwidth{150pt}\begin{document}\largePumasare“large,cat-likeanimals’’whichare`foundinAmerica’.Whenr

    2022年6月25日
    29
  • 时间序列大数据平台建设经验谈

    时间序列大数据平台建设经验谈版权声明:本文由本人撰写并发表于2018年1月刊的《程序员》杂志,本文版权归《程序员》杂志所有,未经许可不得转载。引言在大数据的生态系统里,时间序列数据(TimeSeriesData,简称TSD)是很常见也是所占比例最大的一类数据,几乎出现在科学和工程的各个领域,一些常见的时间序列数据有:描述服务器运行状况的Metrics数据、各种IoT系统的终端数据、脑电图、汇率、股价、气象和天

    2022年6月11日
    31
  • Java 字符串包含_实现字符串的复制

    Java 字符串包含_实现字符串的复制1问题描述给定一长字符串A和一短字符串B。请问,如何最快地判断出短字符串B中的所有字符是否都在长字符串A中?请编写一个判断函数实现此功能。为简单起见,假设输入的字符串只包含小写英文字母。下面举几个例子。(1)如果字符串A是”abcd”,字符串B是”bad”,答案是包含,因为字符串B中的字母都在字符串A中,或者说B是A的真子集。(2)如果字符串A是”abcd”,字符串B是”bce”,答案是…

    2022年10月9日
    3
  • 表复制:SELECT INTO 和 INSERT INTO SELECT

    表复制:SELECT INTO 和 INSERT INTO SELECTINSERTINTOSELECT语句语句形式为:InsertintoTable2(field1,field2,…)selectvalue1,value2,…fromTable1要求目标表Table2必须存在,由于目标表Table2已经存在,所以我们除了插入源表Table1的字段外,还可以插入常量注意(1)要求目标表Tabl

    2022年7月16日
    20
  • Trie 树内存消耗问题

    Trie 树内存消耗问题

    2021年5月25日
    131
  • Delegates and Events in C# .NET

    Delegates and Events in C# .NETOverView Allofushavebeenexposedtoeventdrivenprogrammingofsomesortortheother.C#addsonvaluetotheoftenmentionedworldofeventdrivenprogrammingbyaddingsupportthrou

    2025年6月19日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号