十一、机器学习进阶知识:反向传播神经网络(BPNN)的实现(Python,附源码及数据集)

本文介绍了反向传播神经网络(BPNN)的基本理论,包括前向传播、反向传播、激活函数和神经网络结构。在前向传播中,详细阐述了隐含层和输出层的计算公式以及误差计算。反向传播部分讨论了误差项的计算和权重更新。文章还讨论了常用的激活函数,并提供了BP神经网络在数据预测中的实现步骤,包括训练、测试过程以及如何选择实验数据集。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、理论基础

反向传播神经网络(BPNN)是1986年由Rumelhart和McClelland为首的科学家提出的概念,是一种按照误差逆向传播算法训练的多层前馈神经网络,最常见结构为3层。
数据在神经网络中的训练过程可分为前向传播过程与反向传播过程。通过前向传递过程将数据输入网络,数据依次通过隐含层与输出层并进行相关计算,得到输出值与目标值之间的误差;然后在反向进行传递过程进行神经网络权值、阈值的调整,重复此过程,使得神经网络的输出结果不断逼近真实值。
常见的BP神经网络为3层,输入层、隐含层、输出层。其中输入层传入数据,然后在隐含层与输出层分别与权值、阈值进行计算、从而实现非线性变换,最后在输出层与目标值进行比较获取误差。

1、前向传播

前向传播过程中隐含层与输出层的输出公式及误差公式计算如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

其中W与b为隐含层与输出层的权值和阈值,通过初始化生成,x为隐含层与输出层的输入数据,g为激活函数,h为输出,E为误差,y_i为目标值,y ̂_i为实际值。
参数初始化方法参考:
神经网络基础知识之参数初始化

2、反向传播

反向传播过程中输出层的误差项计算公式如下:
在这里插入图片描述
在这里插入图片描述

其中V与b_2为输出层的权值和阈值,E为损失函数。隐含层的误差项的计算公式可以此类推进行计算。
隐含层与输出层的权值和阈值的更新计算公式如下:
在这里插入图片描述
在这里插入图片描述
损失函数原理参考:
机器学习基础知识之损失函数
反向传播原理参考:
神经网络之反向传播算法(梯度、误差反向传播算法BP)

3、激活函数

在前向传播过程中,输入数据除了和隐含层、输出层的权值、阈值进行计算外,还会使用激活函数g对计算结果进行非线性计算。激活函数作为人工神经网络中神经元的核心,其作用在于将非线性因素引入神经元,它在输入传递至输出的过程中进行函数转换,以此将无限范围内的输入非线性变换为有限范围内的输出,一旦人工神经网络缺少激活函数,那么它每一层的数据传递过程就变成了单纯的矩阵计算过程,无论数据传递了多少层,最后的输出都是输入的线性组合。
常见的激活函数如下:
1、sigmod
Sigmod函数是一种常见的S型函数,它能够将输入变量映射到0到1之间,其公式如下:
在这里插入图片描述

2、Tanh
Tanh函数是一种双曲正切函数,它是由双曲正弦函数与双曲余弦函数推导而来,同样将输入处理成0到1之间,与sigmod不同的是它的输出是零中心的,其公式如下:
在这里插入图片描述

3、Relu
Relu函数将输入和零进行比较,输出较大值,其公式如下:
在这里插入图片描述

4、Leaky Relu
Leaky Relu函数和Relu函数不同的是,当输入小于零时,将输入与常量gamma进行计算作为输出,其公式如下:
在这里插入图片描述
激活函数对比及适用场景参考:
神经网络基础知识之激活函数

4、神经网络结构

BP神经网络的输入层和输出层层数通常需要根据实际问题进行确定,而隐含层的层数即节点数的确定,通常没有一个确定的方法,一般通过设置不同的节点数然后比较其网络训练结果来选择最优数量,而节点数的范围可通过以下公式进行确定:
在这里插入图片描述
在这里插入图片描述

其中h为隐含层单元数,n为输入层单元数,m为输出层单元数,a为1到10之间的常数。

二、BP神经网络的实现

以数据预测为例,下面介绍BP神经网络的实现过程。
选用某省市的表层土壤重金属元素数据集作为实验数据,该数据集总共96组,随机选择其中的24组作为测试数据集,72组作为训练数据集。选取重金属Ti的含量作为待预测的输出特征,选取重金属Co、Cr、Mg、Pb作为模型的输入特征。

1、训练过程(BPNN.py)

#库的导入
import numpy as np
import pandas as pd

#激活函数tanh
def tanh(x):
    return (np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))
#激活函数偏导数
def de_tanh(x):
    return (1-x**2)

#输入数据的导入
df = pd.read_csv("train.csv")
df.columns = ["Co", "Cr", "Mg", "Pb", "Ti"]
Co = df["Co"]
Co = np.array(Co)
Cr = df["Cr"]
Cr = np.array(Cr)
Mg=df["Mg"]
Mg=np.array(Mg)
Pb = df["Pb"]
Pb =np.array(Pb)
Ti = df["Ti"]
Ti = np.array(Ti)
samplein = np.mat([Co,Cr,Mg,Pb])
#数据归一化,将输入数据压缩至0到1之间,便于计算,后续通过反归一化恢复原始值
sampleinminmax = np.array([samplein.min(axis=1).T.tolist()[0],samplein.max(axis=1).T.tolist()[0]]).transpose()
sampleout = np.mat([Ti])
sampleoutminmax = np.array([sampleout.min(axis=1).T.tolist()[0],sampleout.max(axis=1).T.tolist(
### 提高BPNN网络精度的方法与技巧 提高BP神经网络(Back Propagation Neural Network, BPNN)的精度可以通过多种方法实现,包括参数调整、优化算法引入以及数据预处理等。以下是详细说明: #### 1. 参数调整 - **隐含层数与节点数**:选择合适的隐含层层数和节点数对网络性能至关重要。过多或过少的节点可能导致欠拟合或过拟合。通常,隐含层节点数可以根据经验公式计算,例如 $ \text{隐含层节点数} = \sqrt{\text{输入节点数} + \text{输出节点数}} + a $,其中 $ a $ 是一个介于 1 到 10 的常数[^3]。 - **学习率**:学习率决定了权重更新的速度。较高的学习率可能导致训练不稳定,而较低的学习率可能使收敛速度变慢。可以采用动态学习率策略,如逐步衰减或自适应学习率调整[^1]。 #### 2. 数据预处理 - **归一化**:将输入数据归一化到 [0, 1] 或 [-1, 1] 区间内,有助于加速收敛并提高精度。 - **去噪**:去除噪声数据,避免网络学习到无效特征。 - **数据增强**:通过生成更多样化的训练样本,增加模型的泛化能力。 #### 3. 引入优化算法 - **PSO-BP 算法**:粒子群优化(Particle Swarm Optimization, PSO)算法可以用于优化 BP 神经网络的初始权重和偏置,从而克服传统 BP 网络容易陷入局部极小值的问题。PSO-BP 模型在许多实际应用中表现出更高的训练速度和精度[^2]。 ```python import numpy as np from pyswarm import pso # 定义目标函数(误差函数) def error_function(x): # x 表示权重和偏置 # 计算神经网络的误差 return mse # 均方误差 # 使用 PSO 优化权重和偏置 lb = np.array([0, 0]) # 下界 ub = np.array([1, 1]) # 上界 xopt, fopt = pso(error_function, lb, ub) ``` #### 4. 正则化技术 - **L1/L2 正则化**:通过在损失函数中添加权重的 L1 或 L2 范数,防止过拟合。 - **Dropout**:随机丢弃部分神经元,减少模型对特定神经元的依赖,提高泛化能力。 #### 5. 其他改进方法 - **动量因子**:在梯度下降过程中引入动量项,帮助网络更快地逃离局部极小值。 - **批量归一化(Batch Normalization)**:在每一层输入前进行归一化,稳定训练过程,加快收敛速度。 --- ### 示例代码:BP 神经网络实现 以下是一个简单的 BP 神经网络实现,包含参数调整和正则化: ```python import numpy as np class BPNeuralNetwork: def __init__(self, input_size, hidden_size, output_size, learning_rate=0.01, regularization_lambda=0.01): self.input_size = input_size self.hidden_size = hidden_size self.output_size = output_size self.learning_rate = learning_rate self.regularization_lambda = regularization_lambda # 初始化权重和偏置 self.W1 = np.random.randn(input_size, hidden_size) * 0.01 self.b1 = np.zeros((1, hidden_size)) self.W2 = np.random.randn(hidden_size, output_size) * 0.01 self.b2 = np.zeros((1, output_size)) def forward(self, X): self.Z1 = np.dot(X, self.W1) + self.b1 self.A1 = np.tanh(self.Z1) self.Z2 = np.dot(self.A1, self.W2) + self.b2 self.A2 = self.softmax(self.Z2) return self.A2 def backward(self, X, Y, output): m = X.shape[0] # 反向传播 dZ2 = output - Y dW2 = (1 / m) * np.dot(self.A1.T, dZ2) + (self.regularization_lambda / m) * self.W2 db2 = (1 / m) * np.sum(dZ2, axis=0, keepdims=True) dA1 = np.dot(dZ2, self.W2.T) dZ1 = dA1 * (1 - np.power(self.A1, 2)) dW1 = (1 / m) * np.dot(X.T, dZ1) + (self.regularization_lambda / m) * self.W1 db1 = (1 / m) * np.sum(dZ1, axis=0, keepdims=True) # 更新参数 self.W1 -= self.learning_rate * dW1 self.b1 -= self.learning_rate * db1 self.W2 -= self.learning_rate * dW2 self.b2 -= self.learning_rate * db2 def softmax(self, Z): exp_Z = np.exp(Z - np.max(Z, axis=1, keepdims=True)) return exp_Z / np.sum(exp_Z, axis=1, keepdims=True) # 示例使用 X = np.random.rand(100, 10) # 输入数据 Y = np.random.randint(0, 2, (100, 1)) # 输出标签 model = BPNeuralNetwork(input_size=10, hidden_size=20, output_size=1) for epoch in range(1000): output = model.forward(X) model.backward(X, Y, output) ``` ---
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七层楼的疯子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值