前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >机器学习-10-神经网络python实现

机器学习-10-神经网络python实现

作者头像
用户2225445
发布2024-04-19 08:08:56
2560
发布2024-04-19 08:08:56
举报
文章被收录于专栏:IT从业者张某某
文章目录

  • 总结
  • 参考
  • 本门课程的目标
  • 机器学习定义
  • BP神经网络流程
  • BP神经网络推导
  • Python实现BP神经网络
    • 4.1 激活函数sigmod
    • 4.2 构造三层BP神经网络
    • 4.3 算法检验——预测数据
    • 4.4 图解总结
  • 运行结果
  • 整体总结
  • 总代码

总结

本系列是机器学习课程的系列课程,主要介绍基于python实现神经网络。

参考

BP神经网络及python实现(详细)

本文来源原文链接:https://blog.csdn.net/weixin_66845445/article/details/133828686

用Python从0到1实现一个神经网络(附代码)!

python神经网络编程代码https://gitee.com/iamyoyo/makeyourownneuralnetwork.git

本门课程的目标

完成一个特定行业的算法应用全过程:

懂业务+会选择合适的算法+数据处理+算法训练+算法调优+算法融合 +算法评估+持续调优+工程化接口实现

机器学习定义

关于机器学习的定义,Tom Michael Mitchell的这段话被广泛引用: 对于某类任务T性能度量P,如果一个计算机程序在T上其性能P随着经验E而自我完善,那么我们称这个计算机程序从经验E中学习

在这里插入图片描述
在这里插入图片描述

BP神经网络流程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

BP算法实现流程图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

BP神经网络推导

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Python实现BP神经网络

4.1 激活函数sigmod

激活函数采用双曲正切函数tanh:

代码语言:javascript
复制
#? 激活函数sigmoid(x)、及其导数DS(x)
import numpy as np
 
# 双曲正切函数tanh
def sigmoid(x):
    return np.tanh(x)
def DS(x):
    return 1 - (np.tanh(x)) ** 2
 
# 第90次迭代 误差0.00005
4.2 构造三层BP神经网络

神经网络类架构

代码语言:javascript
复制
#? 构造3层BP神经网络架构
class BP:
    #? 初始化函数:各层结点数、激活结点、权重矩阵、偏差、动量因子
    def __init__(self,num_in,num_hidden,num_out):
        pass
 
    #? 信号正向传播
    def update(self,inputs):
        pass
    
    #? 误差反向传播
    def errorbackpropagate(self,targets,lr,m):  # lr 学习效率
        pass
 
    #? 测试
    def test(self,patterns):
        pass
 
    #? 权值
    def weights(self):
        pass
    
    # 训练
    def train(self,pattern,itera=100,lr=0.2,m=0.1):
        pass

4.2.1 BP神经网络初始化

代码语言:javascript
复制
#? 构造3层BP神经网络架构
class BP:
    #? 初始化函数:各层结点数、激活结点、权重矩阵、偏差、动量因子
    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            # 输出层结点数
        # 激活BP神经网络的所有结点(向量)
        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.weight_in=makematrix(self.num_in,self.num_hidden)      # in*hidden 的0矩阵
        self.weight_out=makematrix(self.num_hidden,self.num_out)    # hidden*out的0矩阵
        # 对权重矩阵weight赋初值
        for i in range(self.num_in):        # 对weight_in矩阵赋初值
            for j in range(self.num_hidden):
                self.weight_in[i][j]=random_number(0.1,0.1)
        for i in range(self.num_hidden):    # 对weight_out矩阵赋初值
            for j in range(self.num_out):
                self.weight_out[i][j]=random_number(0.1,0.1)
        # 偏差
        for j in range(self.num_hidden):
            self.weight_in[0][j]=0.1
        for j in range(self.num_out):
            self.weight_out[0][j]=0.1
        
        # 建立动量因子(矩阵)
        self.ci=makematrix(self.num_in,self.num_hidden)     # num_in*num_hidden 矩阵
        self.co=makematrix(self.num_hidden,self.num_out)    # num_hidden*num_out矩阵

图解:初始化后各个变量的存在形式:

在这里插入图片描述
在这里插入图片描述

4.2.2 前向传播

代码语言:javascript
复制
#? 构造3层BP神经网络架构
class BP:
    #? 信号正向传播
    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.weight_in.T,self.active_in.reshape(-1,1))   # 叉乘
            # .T操作是对于array操作后的数组进行转置操作
            # .reshape(x,y)操作是对于array操作后的数组进行重新排列成一个x*y的矩阵,参数为负数表示无限制,如(-1,1)转换成一列的矩阵
        self.active_hidden=sigmoid(self.sum_hidden) # active_hidden[]是处理完输入数据之后处理,作为输出层的输入数据
        self.active_hidden[0]=-1
        # 数据在输出层处理
        self.sum_out=np.dot(self.weight_out.T,self.active_hidden)
        self.active_out=sigmoid(self.sum_out)
        # 返回输出层结果
        return self.active_out

图解:正向传播的过程:计算出active_in、active_hidden、active_out:

在这里插入图片描述
在这里插入图片描述

4.2.3 反向传播

代码语言:javascript
复制
#? 构造3层BP神经网络架构
class BP:
    #? 误差反向传播
    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)*DS(self.sum_out) # DS(self.active_out)
        # 隐层 误差信号
        self.error_hidden=np.dot(self.weight_out,self.error_out)*DS(self.sum_hidden)    # DS(self.active_hidden)
 
        # 更新权值
        # 隐层
        self.weight_out=self.weight_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.weight_in=self.weight_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

图解:反向传播计算出error_hidden(即eh)、error_out(即gj):

在这里插入图片描述
在这里插入图片描述

反向传播更新权值,计算出weight_in、weight_out:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.2.4 迭代训练

代码语言:javascript
复制
#? 构造3层BP神经网络架构
class BP:
    def train(self,pattern,itera=100,lr=0.2,m=0.1):
        for i in range(itera):
            error=0.0   # 每一次迭代将error置0
            for j in pattern:   # j为传入数组的第一维数据   #! *2?(1次迭代里面重复两次?)
                inputs=j[0:self.num_in-1]   # 根据输入层结点的个数确定传入结点值的个数
                targets=j[self.num_in-1:]   # 剩下的结点值作为输出层的值
                self.update(inputs) # 正向传播 更新了active_out
                error=error+self.errorbackpropagate(targets,lr,m)   # 误差反向传播 计算总误差
            if i%10==0:
                print("########################误差 %-.5f ######################第%d次迭代" %(error, i))

默认迭代训练100次。

4.3 算法检验——预测数据
代码语言:javascript
复制
#? 算法检验——预测数据D
# X 输入数据;D 目标数据
X = list(np.arange(-1, 1.1, 0.1))   # -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)    # 2*42矩阵
# 创建神经网络,21个输入节点,13个隐藏层节点,21个输出层节点
bp = BP(21, 13, 21)
# 训练神经网络
bp.train(patt)
# 测试神经网络
d = bp.test(patt)
# 查阅权重值
bp.weights()
 

import matplotlib.pyplot as plt
fig,ax=plt.subplots(1,3)
ax[0].plot(X, D, label="source data",color='red')  # D为真实值
# plt.subplots(212)
ax[1].plot(X, d, label="predict data",color='green')  # d为预测值
ax[2].plot(X, D, label="source data",color='red')  # D为真实值
# plt.subplots(212)
ax[2].plot(X, d, label="predict data",color='green')  # d为预测值
plt.legend()
plt.show()

输入数据为X数据集、预测目标数据为D数据集,经过BP网络后输出的预测数据为d数据集。

最后结果输出形式为终端数据呈现、与可视化图像呈现。

4.4 图解总结

综上图解,各个变量的存在形式如下:

1、权值矩阵:

在这里插入图片描述
在这里插入图片描述

2、激活矩阵:

在这里插入图片描述
在这里插入图片描述

3、动量矩阵:

在这里插入图片描述
在这里插入图片描述

运行结果

1、运行后在终端输出的一部分结果:

在这里插入图片描述
在这里插入图片描述

“->”左侧为输入的数据xi,“->”右侧为这些数据经过三层感知机后的输出结果yj;

[-1.00000000e+00 -9.00000000e-01 -8.00000000e-01 -7.00000000e-01 -6.00000000e-01 -5.00000000e-01 -4.00000000e-01 -3.00000000e-01 -2.00000000e-01 -1.00000000e-01 -2.22044605e-16 1.00000000e-01 2.00000000e-01 3.00000000e-01 4.00000000e-01 5.00000000e-01 6.00000000e-01 7.00000000e-01 8.00000000e-01 9.00000000e-01 1.00000000e+00] -> [[-0.95393255] [-0.57714037] [-0.07292908] [ 0.01697976] [-0.64118266] [-0.66019917] [-0.11003299] [ 0.13359081] [-0.20104368] [-0.43408624] [-0.50010661] [-0.39307616] [-0.16473919] [ 0.09878749] [ 0.30720978] [ 0.39602303] [ 0.34491495] [ 0.18159555] [-0.03122489] [-0.21834595] [-0.32016156]] [-1.00000000e+00 -9.00000000e-01 -8.00000000e-01 -7.00000000e-01 -6.00000000e-01 -5.00000000e-01 -4.00000000e-01 -3.00000000e-01 -2.00000000e-01 -1.00000000e-01 -2.22044605e-16 1.00000000e-01 2.00000000e-01 3.00000000e-01 4.00000000e-01 5.00000000e-01 6.00000000e-01 7.00000000e-01 8.00000000e-01 9.00000000e-01 1.00000000e+00] -> [[-0.95393255] [-0.57714037] [-0.07292908] [ 0.01697976] [-0.64118266] [-0.66019917] [-0.11003299] [ 0.13359081] [-0.20104368] [-0.43408624] [-0.50010661] [-0.39307616] [-0.16473919] [ 0.09878749] [ 0.30720978] [ 0.39602303] [ 0.34491495] [ 0.18159555] [-0.03122489] [-0.21834595] [-0.32016156]]

在这里插入图片描述
在这里插入图片描述

集合D为标准值,可以看到“->”右侧的预测结果和真实值相差很小,说明预测效果较好; 2、下面看一下一些迭代后的误差数据:

########################误差 2.52401 ######################第0次迭代 ########################误差 0.00616 ######################第10次迭代 ########################误差 0.00194 ######################第20次迭代 ########################误差 0.00089 ######################第30次迭代 ########################误差 0.00048 ######################第40次迭代 ########################误差 0.00028 ######################第50次迭代 ########################误差 0.00018 ######################第60次迭代 ########################误差 0.00011 ######################第70次迭代 ########################误差 0.00008 ######################第80次迭代 ########################误差 0.00005 ######################第90次迭代

我们一共迭代训练了100次,可以看到当训练到90次后,误差已经减小到0.00005,误差极小,也说明预测效果较好;比较这些误差数据发现误差减小的速度很快,说明我们使用改进后的BP算法比较不错; 3、输入层的权值

输入层的权值: [[ 0.31234583 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135] [ 0.31234583 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135 0.13989135] [ 0.29111125 0.13590221 0.13590221 0.13590221 0.13590221 0.13590221 0.13590221 0.13590221 0.13590221 0.13590221 0.13590221 0.13590221 0.13590221 0.13590221] [ 0.26987666 0.13191308 0.13191308 0.13191308 0.13191308 0.13191308 0.13191308 0.13191308 0.13191308 0.13191308 0.13191308 0.13191308 0.13191308 0.13191308] [ 0.24864208 0.12792394 0.12792394 0.12792394 0.12792394 0.12792394 0.12792394 0.12792394 0.12792394 0.12792394 0.12792394 0.12792394 0.12792394 0.12792394] [ 0.2274075 0.12393481 0.12393481 0.12393481 0.12393481 0.12393481 0.12393481 0.12393481 0.12393481 0.12393481 0.12393481 0.12393481 0.12393481 0.12393481] [ 0.20617292 0.11994567 0.11994567 0.11994567 0.11994567 0.11994567 0.11994567 0.11994567 0.11994567 0.11994567 0.11994567 0.11994567 0.11994567 0.11994567] [ 0.18493833 0.11595654 0.11595654 0.11595654 0.11595654 0.11595654 0.11595654 0.11595654 0.11595654 0.11595654 0.11595654 0.11595654 0.11595654 0.11595654] [ 0.16370375 0.1119674 0.1119674 0.1119674 0.1119674 0.1119674 0.1119674 0.1119674 0.1119674 0.1119674 0.1119674 0.1119674 0.1119674 0.1119674 ] [ 0.14246917 0.10797827 0.10797827 0.10797827 0.10797827 0.10797827 0.10797827 0.10797827 0.10797827 0.10797827 0.10797827 0.10797827 0.10797827 0.10797827] [ 0.12123458 0.10398913 0.10398913 0.10398913 0.10398913 0.10398913 0.10398913 0.10398913 0.10398913 0.10398913 0.10398913 0.10398913 0.10398913 0.10398913] [ 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 ] [ 0.07876542 0.09601087 0.09601087 0.09601087 0.09601087 0.09601087 0.09601087 0.09601087 0.09601087 0.09601087 0.09601087 0.09601087 0.09601087 0.09601087] [ 0.05753083 0.09202173 0.09202173 0.09202173 0.09202173 0.09202173 0.09202173 0.09202173 0.09202173 0.09202173 0.09202173 0.09202173 0.09202173 0.09202173] [ 0.03629625 0.0880326 0.0880326 0.0880326 0.0880326 0.0880326 0.0880326 0.0880326 0.0880326 0.0880326 0.0880326 0.0880326 0.0880326 0.0880326 ] [ 0.01506167 0.08404346 0.08404346 0.08404346 0.08404346 0.08404346 0.08404346 0.08404346 0.08404346 0.08404346 0.08404346 0.08404346 0.08404346 0.08404346] [-0.00617292 0.08005433 0.08005433 0.08005433 0.08005433 0.08005433 0.08005433 0.08005433 0.08005433 0.08005433 0.08005433 0.08005433 0.08005433 0.08005433] [-0.0274075 0.07606519 0.07606519 0.07606519 0.07606519 0.07606519 0.07606519 0.07606519 0.07606519 0.07606519 0.07606519 0.07606519 0.07606519 0.07606519] [-0.04864208 0.07207606 0.07207606 0.07207606 0.07207606 0.07207606 0.07207606 0.07207606 0.07207606 0.07207606 0.07207606 0.07207606 0.07207606 0.07207606] [-0.06987666 0.06808692 0.06808692 0.06808692 0.06808692 0.06808692 0.06808692 0.06808692 0.06808692 0.06808692 0.06808692 0.06808692 0.06808692 0.06808692] [-0.09111125 0.06409779 0.06409779 0.06409779 0.06409779 0.06409779 0.06409779 0.06409779 0.06409779 0.06409779 0.06409779 0.06409779 0.06409779 0.06409779] [-0.11234583 0.06010865 0.06010865 0.06010865 0.06010865 0.06010865 0.06010865 0.06010865 0.06010865 0.06010865 0.06010865 0.06010865 0.06010865 0.06010865]]

4、输出层的权值

[[ 0.84862336 0.32002838 -0.03326946 -0.09136811 0.37524535 0.39260519 -0.0092981 -0.16755761 0.0498955 0.20946782 0.25873617 0.18002566 0.02618395 -0.14465799 -0.28499839 -0.34794328 -0.31142901 -0.19944158 -0.06019286 0.06126102 0.12937757] [ 0.18798645 0.06200714 0.01949841 0.01364099 0.07058899 0.07345472 0.02196489 0.0060815 0.02822658 0.04684481 0.05331062 0.04316889 0.025686 0.00835243 -0.00595306 -0.01301628 -0.00884466 0.00289912 0.016766 0.02946129 0.03712508] [ 0.18798645 0.06200714 0.01949841 0.01364099 0.07058899 0.07345472 0.02196489 0.0060815 0.02822658 0.04684481 0.05331062 0.04316889 0.025686 0.00835243 -0.00595306 -0.01301628 -0.00884466 0.00289912 0.016766 0.02946129 0.03712508] [ 0.18798645 0.06200714 0.01949841 0.01364099 0.07058899 0.07345472 0.02196489 0.0060815 0.02822658 0.04684481 0.05331062 0.04316889 0.025686 0.00835243 -0.00595306 -0.01301628 -0.00884466 0.00289912 0.016766 0.02946129 0.03712508] [ 0.18798645 0.06200714 0.01949841 0.01364099 0.07058899 0.07345472 0.02196489 0.0060815 0.02822658 0.04684481 0.05331062 0.04316889 0.025686 0.00835243 -0.00595306 -0.01301628 -0.00884466 0.00289912 0.016766 0.02946129 0.03712508] [ 0.18798645 0.06200714 0.01949841 0.01364099 0.07058899 0.07345472 0.02196489 0.0060815 0.02822658 0.04684481 0.05331062 0.04316889 0.025686 0.00835243 -0.00595306 -0.01301628 -0.00884466 0.00289912 0.016766 0.02946129 0.03712508] [ 0.18798645 0.06200714 0.01949841 0.01364099 0.07058899 0.07345472 0.02196489 0.0060815 0.02822658 0.04684481 0.05331062 0.04316889 0.025686 0.00835243 -0.00595306 -0.01301628 -0.00884466 0.00289912 0.016766 0.02946129 0.03712508] [ 0.18798645 0.06200714 0.01949841 0.01364099 0.07058899 0.07345472 0.02196489 0.0060815 0.02822658 0.04684481 0.05331062 0.04316889 0.025686 0.00835243 -0.00595306 -0.01301628 -0.00884466 0.00289912 0.016766 0.02946129 0.03712508] [ 0.18798645 0.06200714 0.01949841 0.01364099 0.07058899 0.07345472 0.02196489 0.0060815 0.02822658 0.04684481 0.05331062 0.04316889 0.025686 0.00835243 -0.00595306 -0.01301628 -0.00884466 0.00289912 0.016766 0.02946129 0.03712508] [ 0.18798645 0.06200714 0.01949841 0.01364099 0.07058899 0.07345472 0.02196489 0.0060815 0.02822658 0.04684481 0.05331062 0.04316889 0.025686 0.00835243 -0.00595306 -0.01301628 -0.00884466 0.00289912 0.016766 0.02946129 0.03712508] [ 0.18798645 0.06200714 0.01949841 0.01364099 0.07058899 0.07345472 0.02196489 0.0060815 0.02822658 0.04684481 0.05331062 0.04316889 0.025686 0.00835243 -0.00595306 -0.01301628 -0.00884466 0.00289912 0.016766 0.02946129 0.03712508] [ 0.18798645 0.06200714 0.01949841 0.01364099 0.07058899 0.07345472 0.02196489 0.0060815 0.02822658 0.04684481 0.05331062 0.04316889 0.025686 0.00835243 -0.00595306 -0.01301628 -0.00884466 0.00289912 0.016766 0.02946129 0.03712508] [ 0.18798645 0.06200714 0.01949841 0.01364099 0.07058899 0.07345472 0.02196489 0.0060815 0.02822658 0.04684481 0.05331062 0.04316889 0.025686 0.00835243 -0.00595306 -0.01301628 -0.00884466 0.00289912 0.016766 0.02946129 0.03712508] [ 0.18798645 0.06200714 0.01949841 0.01364099 0.07058899 0.07345472 0.02196489 0.0060815 0.02822658 0.04684481 0.05331062 0.04316889 0.025686 0.00835243 -0.00595306 -0.01301628 -0.00884466 0.00289912 0.016766 0.02946129 0.03712508]]

5、可视化预测值和真实值的差距:

在这里插入图片描述
在这里插入图片描述

图中其实有两根线,分别为黄线和蓝线,因为预测效果较好导致蓝线不太明显;黄线代表经过三层感知机预测出的数据,蓝线代表真实值,两条曲线拟合度很高说明三层感知机训练效果较好;

整体总结

1、上述为三层的BP神经网络,即三层感知机; 2、此BP网络对标准BP网络进行改进:

(1)标准BP网络属于单样本训练,训练速度满;改进后可以进行批训练,将所有样本输入后计算网络的总误差,并根据总误差调整权值,这样训练时的收敛速度很快; (2)标准BP网络在调整权值时只按t时刻误差的梯度降方向调整,而没有考虑t时刻之前的梯度方向,在训练过程中可能会出现振荡,收敛速度慢;改进后添加了动量因子考虑了t时刻之前的梯度变化,可以提高训练速度;

总代码

代码语言:javascript
复制
#! BP神经网络(误差逆传播算法)
#! 三层BP神经网络/三层感知机
 
#? 激活函数sigmoid(x)、及其导数DS(x)
import numpy as np
 
# 双曲正切函数tanh
def sigmoid(x):
    return np.tanh(x)
def DS(x):
    return 1 - (np.tanh(x)) ** 2
# 第90次迭代 误差0.00005
 
#? 生成区间[a,b]内的随机数
import random
def random_number(a,b):
    return (b-a)*random.random()+a  # random.random()随机生成[0,1)内浮点数
 
#? 生成一个m*n矩阵,并且设置默认零矩阵
def makematrix(m,n,fill=0.0):
    a = []
    for i in range(m):
        a.append([fill]*n)    # 列表1*n会得到一个新列表,新列表元素为列表1元素重复n次。[fill]*3==[fill fill fill]
    return np.array(a)
 
#? 构造3层BP神经网络架构
class BP:
    #? 初始化函数:各层结点数、激活结点、权重矩阵、偏差、动量因子
    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            # 输出层结点数
        # 激活BP神经网络的所有结点(向量)
        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.weight_in=makematrix(self.num_in,self.num_hidden)      # in*hidden 的0矩阵
        self.weight_out=makematrix(self.num_hidden,self.num_out)    # hidden*out的0矩阵
        # 对权重矩阵weight赋初值
        for i in range(self.num_in):        # 对weight_in矩阵赋初值
            for j in range(self.num_hidden):
                self.weight_in[i][j]=random_number(0.1,0.1)
        for i in range(self.num_hidden):    # 对weight_out矩阵赋初值
            for j in range(self.num_out):
                self.weight_out[i][j]=random_number(0.1,0.1)
        # 偏差
        for j in range(self.num_hidden):
            self.weight_in[0][j]=0.1
        for j in range(self.num_out):
            self.weight_out[0][j]=0.1
        
        # 建立动量因子(矩阵)
        self.ci=makematrix(self.num_in,self.num_hidden)     # num_in*num_hidden 矩阵
        self.co=makematrix(self.num_hidden,self.num_out)    # num_hidden*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.weight_in.T,self.active_in.reshape(-1,1))   # 叉乘
            # .T操作是对于array操作后的数组进行转置操作
            # .reshape(x,y)操作是对于array操作后的数组进行重新排列成一个x*y的矩阵,参数为负数表示无限制,如(-1,1)转换成一列的矩阵
        self.active_hidden=sigmoid(self.sum_hidden) # active_hidden[]是处理完输入数据之后处理,作为输出层的输入数据
        self.active_hidden[0]=-1
        # 数据在输出层处理
        self.sum_out=np.dot(self.weight_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)*DS(self.sum_out) # DS(self.active_out)
        # 隐层 误差信号
        self.error_hidden=np.dot(self.weight_out,self.error_out)*DS(self.sum_hidden)    # DS(self.active_hidden)
 
        # 更新权值
        # 隐层
        self.weight_out=self.weight_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.weight_in=self.weight_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:  # i为传入数组的第一维数据
            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.weight_in)
        print("输出层的权值:")
        print(self.weight_out)
    
    def train(self,pattern,itera=100,lr=0.2,m=0.1):
        for i in range(itera):
            error=0.0   # 每一次迭代将error置0
            for j in pattern:   # j为传入数组的第一维数据
                inputs=j[0:self.num_in-1]   # 根据输入层结点的个数确定传入结点值的个数
                targets=j[self.num_in-1:]   # 剩下的结点值作为输出层的值
                self.update(inputs) # 正向传播 更新了active_out
                error=error+self.errorbackpropagate(targets,lr,m)   # 误差反向传播 计算总误差
            if i%10==0:
                print("########################误差 %-.5f ######################第%d次迭代" %(error, i))
 
 
#? 算法检验——预测数据D
# X 输入数据;D 目标数据
X = list(np.arange(-1, 1.1, 0.1))   # -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)    # 2*42矩阵
# 创建神经网络,21个输入节点,13个隐藏层节点,21个输出层节点
bp = BP(21, 13, 21)
# 训练神经网络
bp.train(patt)
# 测试神经网络
d = bp.test(patt)
# 查阅权重值
bp.weights()
 

import matplotlib.pyplot as plt
fig,ax=plt.subplots(1,3)
ax[0].plot(X, D, label="source data",color='red')  # D为真实值
# plt.subplots(212)
ax[1].plot(X, d, label="predict data",color='green')  # d为预测值
ax[2].plot(X, D, label="source data",color='red')  # D为真实值
# plt.subplots(212)
ax[2].plot(X, d, label="predict data",color='green')  # d为预测值
plt.legend()
plt.show()
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-04-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 总结
  • 参考
  • 本门课程的目标
  • 机器学习定义
  • BP神经网络流程
  • BP神经网络推导
  • Python实现BP神经网络
    • 4.1 激活函数sigmod
      • 4.2 构造三层BP神经网络
        • 4.3 算法检验——预测数据
          • 4.4 图解总结
          • 运行结果
          • 整体总结
          • 总代码
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档