机器学习-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()
相关推荐
sp_fyf_20241 分钟前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-05
人工智能·深度学习·神经网络·算法·机器学习·语言模型·自然语言处理
EterNity_TiMe_1 分钟前
【机器学习】智驭未来:探索机器学习在食品生产中的革新之路
人工智能·python·机器学习·性能优化·学习方法
Mopes__40 分钟前
Python | Leetcode Python题解之第452题用最少数量的箭引爆气球
python·leetcode·题解
AI视觉网奇1 小时前
pymeshlab 学习笔记
开发语言·python
纪伊路上盛名在1 小时前
如何初步部署自己的服务器,达到生信分析的及格线
linux·运维·服务器·python·学习·r语言·github
吃什么芹菜卷1 小时前
深度学习:词嵌入embedding和Word2Vec
人工智能·算法·机器学习
计算机源码社1 小时前
分享一个餐饮连锁店点餐系统 餐馆食材采购系统Java、python、php三个版本(源码、调试、LW、开题、PPT)
java·python·php·毕业设计项目·计算机课程设计·计算机毕业设计源码·计算机毕业设计选题
汤兰月1 小时前
Python中的观察者模式:从基础到实战
开发语言·python·观察者模式
邓某人的父亲1 小时前
【EcoNAS: Finding Proxies for Economical Neural Architecture Search】读后感
神经网络·神经网络结构搜索
lan人啊1 小时前
脉冲神经网络(SNN)论文阅读(六)-----ECCV-2024 脉冲驱动的SNN目标检测框架:SpikeYOLO
论文阅读·神经网络·目标检测