BP神经网络(Back Propagation Neural Network)算法原理推导与Python实现详解

简介: BP神经网络(Back Propagation Neural Network)算法原理推导与Python实现详解

正文


##BP神经网络算法推导

给定训练集:

D={(x1,y1),(x2,y2),...,(xm,ym)},xiRI,yiRO

即数据有D 个特征,标签为O 维实值向量。


因此,我们定义一个拥有I 个输入层神经元、O个输出层神经元的神经网络,且设该网络的隐藏层神经元个数为H。

其中,隐藏层第h 个神经元的阀值用γ h 表示,输出层第o 个神经元的阀值用θ  表示。

输入层第i ii个神经元与隐藏层第h hh个神经元之间的连接权重为ν i h,记隐藏层第h hh个神经元接收到的输入为α h = ∑ i = 1 I ν i h x i  

隐藏层第h hh个神经元与输出层第o oo个神经元之间的连接权重为ω h o ,记输出层第o oo个神经元接收到的输入为β o = ∑ h = 1 H ω h o b h 其中b h 为隐藏层第h 个神经元的输出。

假设隐藏层和输出层都使用Sigmoid函数作为激活函数

Sigmoid函数:

5.png

对于训练集中的一个训练例k :6.png假设神经网络的输出为7.png,则有:

8.png

由此可以得到,神经网络在训练例k kk上的均方误差为:

9.png

BP是一个迭代学习算法,迭代的每一轮都会对权重进行更新,基于梯度下降算法和链式求导法则,我们可以得到:

1、对隐藏层第h hh个神经元与输出层第o oo个神经元之间的连接权重ω h o  的更新估计式为:

10.png

其中

11.png

因此,权重ω h o 的更新估计式为:


12.png

2、对输入层第i ii个神经元与隐藏层第h hh个神经元之间的连接权重ν i h 的更新估计式为:


13.png

其中:

14.png15.png16.png

因此,权重ν i h  的更新估计式为

18.png


##BP神经网络Python实现

该神经网络被设置为三层:一层输入层、一层隐藏层、一层输出层

样本集:

特征一 特征二 标签
0 0 0
0 1 1
1 0 1
1 1 0


可以看出,这就是一个异或样本集,使用这个样本集可以展现出神经网络与感知机在处理非线性可分问题上的差别。

import math
import random
# 用于设置权重矩阵的大小并给定初始权重
def weight_matrix(row, col, weight=0.0):
    weightMat = []
    for _ in range(row):
        weightMat.append([weight] * col)
    return weightMat
# 用于给权重矩阵内的每元素生成一个初始随机权重
def random_weight(parm_1, parm_2):
    return (parm_1 - 1) * random.random() + parm_2
# Sigmoid激活函数
def sigmoid(x):
    return 1.0 / (1.0 + math.exp(-x))
# Sigmoid激活函数的导函数
def sigmoid_derivate(x):
    return x * (1 - x)
# 定义BP神经网络类
class BPNeuralNetwork:
    def __init__(self):
        # 定义输入层、隐藏层、输出层,所有层的神经元个数都初始化为0
        self.input_num, self.hidden_num, self.output_num = 0, 0, 0
        # 定义输入层、隐藏层、输出层的值矩阵,并在setup函数中初始化
        self.input_values, self.hidden_values, self.output_values = [], [], []
        # 定义输入-隐藏层、隐藏-输出层权重矩阵,并在setup函数中设置大小并初始化
        self.input_hidden_weights, self.hidden_output_weights = [], []
    # 神经网络的初始化函数
    # 四个参数分别代表:对象自身、输入层神经元个数、隐藏层神经元个数、输出层神经元个数
    def setup(self, input_num, hidden_num, output_num):
        # 设置输入层、隐藏层、输出层的神经元个数,其中输入层包含偏置项因此数量+1
        self.input_num, self.hidden_num, self.output_num = input_num + 1, hidden_num, output_num
        # 初始化输入层、隐藏层、输出层的值矩阵,均初始化为1
        self.input_values = [1.0] * self.input_num
        self.hidden_values = [1.0] * self.hidden_num
        self.output_values = [1.0] * self.output_num
        # 设置输入-隐藏层、隐藏-输出层权重矩阵的大小
        self.input_hidden_weights = weight_matrix(self.input_num, self.hidden_num)
        self.hidden_output_weights = weight_matrix(self.hidden_num, self.output_num)
        # 初始化输入-隐藏层、隐藏-输出层的权重矩阵
        for i in range(self.input_num):
            for h in range(self.hidden_num):
                self.input_hidden_weights[i][h] = random_weight(-0.2, 0.2)
        for h in range(self.hidden_num):
            for o in range(self.output_num):
                self.hidden_output_weights[h][0] = random_weight(-0.2, 0.2)
    # 神经网络的前向预测
    # 两个参数分别代表:对象自身、单个数据
    def predict(self, data):
        # 将数据放入输入层,-1是由于输入层中的偏置项不需要接收数据
        for i in range(self.input_num - 1):
            self.input_values[i] = data[i]
        # 隐藏层计算
        for h in range(self.hidden_num):
            # 激活函数的参数
            total = 0.0
            # 激活函数的参数值由输入层权重和输入层的值确定
            for i in range(self.input_num):
                total += self.input_values[i] * self.input_hidden_weights[i][h]
            # 将经过激活函数处理的输入层的值赋给隐藏层
            self.hidden_values[h] = sigmoid(total - 0)
        # 输出层计算
        for o in range(self.output_num):
            total = 0.0
            for h in range(self.hidden_num):
                total += self.hidden_values[h] * self.hidden_output_weights[h][o]
            self.output_values[o] = sigmoid(total - 0)
        return self.output_values[:]
    # 神经网络的反向传播
    # 四个参数分别代表:对象自身、单个数据、数据对应的标签、学习率(步长)
    # 本函数皆为数学推导的实现
    def back_propagate(self, data, label, learn):
        # 反向传播前先进行前向预测
        self.predict(data)
        # 计算输出层的误差
        output_datas = [0.0] * self.output_num
        for o in range(self.output_num):
            error = label[o] - self.output_values[o]
            output_datas[o] = sigmoid_derivate(self.output_values[o]) * error
        # 计算隐藏层的误差
        hidden_datas = [0.0] * self.hidden_num
        for h in range(self.hidden_num):
            error = 0.0
            for o in range(self.output_num):
                error += output_datas[o] * self.hidden_output_weights[h][o]
            hidden_datas[h] = sigmoid_derivate(self.hidden_values[h]) * error
        # 更新隐藏-输出层权重
        for h in range(self.hidden_num):
            for o in range(self.output_num):
                self.hidden_output_weights[h][o] += learn * output_datas[o] * self.hidden_values[h]
        # 更新输入-隐藏层权重
        for i in range(self.input_num):
            for h in range(self.hidden_num):
                self.input_hidden_weights[i][h] += learn * hidden_datas[h] * self.input_values[i]
        # 计算样本的均方误差
        error = 0
        for o in range(len(label)):
            error += 0.5 * (label[o] - self.output_values[o]) ** 2
        return error
    # 神经网络训练函数
    # 四个参数分别代表:对象自身、数据集、标签、最大循环次数、学习率、终止误差
    def train(self, datas, labels, limit=50000, learn=0.05, stop_error=0.02):
        for i in range(limit):
            error = 0
            for i in range(len(datas)):
                data = datas[i]
                label = labels[i]
                error += self.back_propagate(data, label, learn)
            if error <= stop_error:
                break
    # 神经网络验证函数
    def test(self):
        # 数据集及其标签
        datas = [[0, 0], [0, 1], [1, 0], [1, 1]]
        labels = [[0], [1], [1], [0]]
        # 调用神经网络的初始化函数并传入参数作为输入层、隐藏层、输出层的神经元个数
        # 其中输入层的神经元个数应与数据集的特征数保持一致
        self.setup(2, 5, 1)
        self.train(datas, labels)
        for data in datas:
            print(self.predict(data))
# 定义BP神经网络对象并调用其进行预测
if __name__ == '__main__':
    nn = BPNeuralNetwork()
    nn.test()


神经网络训练结果:

[0.018648283776391633]
[0.9754998553712237]
[0.9806999914518663]
[0.02997622156919269]


该结果与真实值labels[0, 1, 1, 0]基本类似,可以认为神经网络在预测异或这类非线性可分问题上是有效的。



相关文章
基于Python深度学习的【害虫识别】系统~卷积神经网络+TensorFlow+图像识别+人工智能
害虫识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了12种常见的害虫种类数据集【"蚂蚁(ants)", "蜜蜂(bees)", "甲虫(beetle)", "毛虫(catterpillar)", "蚯蚓(earthworms)", "蜚蠊(earwig)", "蚱蜢(grasshopper)", "飞蛾(moth)", "鼻涕虫(slug)", "蜗牛(snail)", "黄蜂(wasp)", "象鼻虫(weevil)"】 再使用通过搭建的算法模型对数据集进行训练得到一个识别精度较高的模型,然后保存为为本地h5格式文件。最后使用Djan
42 1
基于Python深度学习的【害虫识别】系统~卷积神经网络+TensorFlow+图像识别+人工智能
基于Python深度学习的【蘑菇识别】系统~卷积神经网络+TensorFlow+图像识别+人工智能
蘑菇识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了9种常见的蘑菇种类数据集【"香菇(Agaricus)", "毒鹅膏菌(Amanita)", "牛肝菌(Boletus)", "网状菌(Cortinarius)", "毒镰孢(Entoloma)", "湿孢菌(Hygrocybe)", "乳菇(Lactarius)", "红菇(Russula)", "松茸(Suillus)"】 再使用通过搭建的算法模型对数据集进行训练得到一个识别精度较高的模型,然后保存为为本地h5格式文件。最后使用Django框架搭建了一个Web网页平台可视化操作界面,
95 11
基于Python深度学习的【蘑菇识别】系统~卷积神经网络+TensorFlow+图像识别+人工智能
基于改进遗传优化的BP神经网络金融序列预测算法matlab仿真
本项目基于改进遗传优化的BP神经网络进行金融序列预测,使用MATLAB2022A实现。通过对比BP神经网络、遗传优化BP神经网络及改进遗传优化BP神经网络,展示了三者的误差和预测曲线差异。核心程序结合遗传算法(GA)与BP神经网络,利用GA优化BP网络的初始权重和阈值,提高预测精度。GA通过选择、交叉、变异操作迭代优化,防止局部收敛,增强模型对金融市场复杂性和不确定性的适应能力。
233 80
基于机器学习的人脸识别算法matlab仿真,对比GRNN,PNN,DNN以及BP四种网络
本项目展示了人脸识别算法的运行效果(无水印),基于MATLAB2022A开发。核心程序包含详细中文注释及操作视频。理论部分介绍了广义回归神经网络(GRNN)、概率神经网络(PNN)、深度神经网络(DNN)和反向传播(BP)神经网络在人脸识别中的应用,涵盖各算法的结构特点与性能比较。
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
宠物识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了37种常见的猫狗宠物种类数据集【'阿比西尼亚猫(Abyssinian)', '孟加拉猫(Bengal)', '暹罗猫(Birman)', '孟买猫(Bombay)', '英国短毛猫(British Shorthair)', '埃及猫(Egyptian Mau)', '缅因猫(Maine Coon)', '波斯猫(Persian)', '布偶猫(Ragdoll)', '俄罗斯蓝猫(Russian Blue)', '暹罗猫(Siamese)', '斯芬克斯猫(Sphynx)', '美国斗牛犬
240 29
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
基于CNN卷积神经网络的金融数据预测matlab仿真,对比BP,RBF,LSTM
本项目基于MATLAB2022A,利用CNN卷积神经网络对金融数据进行预测,并与BP、RBF和LSTM网络对比。核心程序通过处理历史价格数据,训练并测试各模型,展示预测结果及误差分析。CNN通过卷积层捕捉局部特征,BP网络学习非线性映射,RBF网络进行局部逼近,LSTM解决长序列预测中的梯度问题。实验结果表明各模型在金融数据预测中的表现差异。
197 10
基于遗传优化的双BP神经网络金融序列预测算法matlab仿真
本项目基于遗传优化的双BP神经网络实现金融序列预测,使用MATLAB2022A进行仿真。算法通过两个初始学习率不同的BP神经网络(e1, e2)协同工作,结合遗传算法优化,提高预测精度。实验展示了三个算法的误差对比结果,验证了该方法的有效性。
基于WOA-SVM的乳腺癌数据分类识别算法matlab仿真,对比BP神经网络和SVM
本项目利用鲸鱼优化算法(WOA)优化支持向量机(SVM)参数,针对乳腺癌早期诊断问题,通过MATLAB 2022a实现。核心代码包括参数初始化、目标函数计算、位置更新等步骤,并附有详细中文注释及操作视频。实验结果显示,WOA-SVM在提高分类精度和泛化能力方面表现出色,为乳腺癌的早期诊断提供了有效的技术支持。
基于BP神经网络的金融序列预测matlab仿真
本项目基于BP神经网络实现金融序列预测,使用MATLAB2022A版本进行开发与测试。通过构建多层前馈神经网络模型,利用历史金融数据训练模型,实现对未来金融时间序列如股票价格、汇率等的预测,并展示了预测误差及训练曲线。
102 12
深度学习入门:用Python构建你的第一个神经网络
在人工智能的海洋中,深度学习是那艘能够带你远航的船。本文将作为你的航标,引导你搭建第一个神经网络模型,让你领略深度学习的魅力。通过简单直观的语言和实例,我们将一起探索隐藏在数据背后的模式,体验从零开始创造智能系统的快感。准备好了吗?让我们启航吧!
130 3

热门文章

最新文章

目录
目录