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

文章目录

总结

本系列是机器学习课程的系列课程,主要介绍基于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:

python 复制代码
#? 激活函数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神经网络

神经网络类架构

python 复制代码
#? 构造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神经网络初始化

python 复制代码
#? 构造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 前向传播

python 复制代码
#? 构造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 反向传播

python 复制代码
#? 构造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 迭代训练

python 复制代码
#? 构造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 算法检验------预测数据

python 复制代码
#? 算法检验------预测数据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时刻之前的梯度变化,可以提高训练速度;

总代码

python 复制代码
#! 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()
相关推荐
这里有鱼汤几秒前
给你的DeepSeek装上实时行情,让他帮你炒股
后端·python·mcp
Tomorrow'sThinker34 分钟前
[特殊字符] Excel 读取收件人 + Outlook 批量发送带附件邮件 —— Python 自动化实战
python·excel·outlook
LucianaiB39 分钟前
Chatbox➕知识库➕Mcp = 机器学习私人语音助手
机器学习·知识库·mcp·chatbox
JosieBook41 分钟前
【Java编程动手学】Java常用工具类
java·python·mysql
灵智工坊LingzhiAI3 小时前
人体坐姿检测系统项目教程(YOLO11+PyTorch+可视化)
人工智能·pytorch·python
SHIPKING3934 小时前
【机器学习&深度学习】什么是下游任务模型?
人工智能·深度学习·机器学习
巴伦是只猫4 小时前
【机器学习笔记Ⅰ】11 多项式回归
笔记·机器学习·回归
巴伦是只猫9 小时前
【机器学习笔记Ⅰ】13 正则化代价函数
人工智能·笔记·机器学习
伍哥的传说10 小时前
React 各颜色转换方法、颜色值换算工具HEX、RGB/RGBA、HSL/HSLA、HSV、CMYK
深度学习·神经网络·react.js
大千AI助手10 小时前
DTW模版匹配:弹性对齐的时间序列相似度度量算法
人工智能·算法·机器学习·数据挖掘·模版匹配·dtw模版匹配