神经网络——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)
上一篇 2025年9月16日 下午4:43
下一篇 2025年9月16日 下午5:15


相关推荐

  • java字符串按照特定字符分割_java 字符串分割

    java字符串按照特定字符分割_java 字符串分割问题描述://把字符串”192.168.1.1″按照小圆点进行分割,分割成”192″,”168″,”1″,”1″四个字符串。StringpreStr=”192.168.1.1″;String[]string=preStr.split(“.”);//错误写法。这种写法得到的字符串组长度为0String[]string=preStr.split(“\\.”);//正确写法。对…

    2026年4月15日
    7
  • 通义千问1.5-1.8B-Chat-GPTQ-Int4在网络安全领域的应用:威胁情报分析

    通义千问1.5-1.8B-Chat-GPTQ-Int4在网络安全领域的应用:威胁情报分析

    2026年3月12日
    3
  • SPU和SKU概念

    SPU和SKU概念SPU 介绍 SPU StandardProd 标准产品单位 概念 SPU 是商品信息聚合的最小单位 是一组可复用 易检索的标准化信息的集合 该集合描述了一个产品的特性 通俗点讲就是属性值 特性相同的货品就可以称为一个 SPU 举例 例如绿色的 IPhone12 就是一个 SPU 与商家 颜色 款式 套餐等都无关 SKU 介绍 SKU stockkeeping 库存量单位 概念 SKU 即库存进出计量的单位 可以是以件 盒 托盘等为单位 SKU 是物理上不可分割的最小

    2026年3月26日
    2
  • Spring获取request对象的几种方式[通俗易懂]

    Spring获取request对象的几种方式[通俗易懂]参考文章:在SpringMVC中获取request对象的几种方式Springboot获取request和response使用Springboot,我们很多时候直接使用@PathVariable、@RequestParam、@Param来获取参数,但是偶尔还是要用到request和response,怎么获取呢?也很方便,有三种方式可以获取,任选其一就行。1、通过静态方法…

    2022年5月18日
    56
  • eclipse设置中没有server选项[通俗易懂]

    用eclipse准备配置tomcat,发现配置中没有server选项,参考各种解决方法之后成功解决。准备工作:1.查看eclipse版本号;在eclipse中点Help,现在AboutEclipseIDE;2.添加server插件;eclipse中点Help,选择InstallNewSoftware…;点Add,Name输入上面查询的eclipse版本号,Location…

    2022年4月17日
    351
  • IDEA删除当前一行 快捷键

    IDEA删除当前一行 快捷键IDEA 删除当前一行快捷键默认是 Ctrl Y 但是有时候会和反撤销键冲突 所以还是自己设置一下也可以自定义双击选中输入框 在键盘上按下 ctrl y 就可以了 然后点击 OK 就可以了当然你也可以直接使用 Ctrl X 剪切的快捷键 也是可以充当删除当前行的快捷键

    2026年3月18日
    3

发表回复

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

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