0
点赞
收藏
分享

微信扫一扫

tomcat热部署热加载原理剖析

mjjackey 10小时前 阅读 1

文章目录

总结

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

参考

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

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

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

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

本门课程的目标

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

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

机器学习定义

BP神经网络流程

在这里插入图片描述

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

BP算法实现流程图
在这里插入图片描述
在这里插入图片描述

BP神经网络推导

在这里插入图片描述

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

在这里插入图片描述

在这里插入图片描述

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

Python实现BP神经网络

4.1 激活函数sigmod

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

#? 激活函数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神经网络

神经网络类架构

#? 构造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神经网络初始化

#? 构造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 前向传播

#? 构造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 反向传播

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

#? 构造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 算法检验——预测数据

#? 算法检验——预测数据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;

在这里插入图片描述

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

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

4、输出层的权值

5、可视化预测值和真实值的差距:
在这里插入图片描述

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

整体总结

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

总代码

#! 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()
举报

相关推荐

0 条评论