BP神经网络前向传播与反向传播原理详解及动画演示

1次阅读
没有评论

共计 2277 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

神经网络基础概念

BP 神经网络(Backpropagation Neural Network)是一种多层前馈神经网络,通过反向传播算法来调整权重。它通常由输入层、隐藏层和输出层组成,每一层都包含若干个神经元。

BP 神经网络前向传播与反向传播原理详解及动画演示

前向传播计算输出

前向传播是指输入数据从输入层经过隐藏层到输出层的计算过程。具体步骤如下:

  1. 输入层接收外部输入数据。
  2. 每个神经元将输入与对应的权重相乘,再加上偏置项。
  3. 通过激活函数(如 sigmoid)对加权和进行非线性变换,得到神经元的输出。
  4. 输出层的输出即为网络的预测结果。

反向传播原理

反向传播的核心思想是通过链式法则计算损失函数对每个权重的梯度,然后利用梯度下降法更新权重。

数学推导

  1. 计算输出层的误差:
  2. 误差 = 预测值 – 真实值
  3. 输出层梯度 = 误差 * 激活函数的导数

  4. 计算隐藏层的误差:

  5. 隐藏层梯度 = 输出层梯度 * 权重 * 激活函数的导数

  6. 更新权重:

  7. 权重更新量 = 学习率 * 梯度 * 输入
  8. 新权重 = 旧权重 – 权重更新量

伪代码

# 反向传播伪代码
for each training sample:
    # 前向传播
    calculate output

    # 反向传播
    calculate output layer error
    calculate hidden layer error

    # 更新权重
    update weights and biases

Python 实现

网络初始化

import numpy as np

class NeuralNetwork:
    def __init__(self, input_size, hidden_size, output_size):
        self.weights1 = np.random.randn(input_size, hidden_size)
        self.weights2 = np.random.randn(hidden_size, output_size)
        self.bias1 = np.zeros((1, hidden_size))
        self.bias2 = np.zeros((1, output_size))

Sigmoid 激活函数及其导数

    def sigmoid(self, x):
        return 1 / (1 + np.exp(-x))

    def sigmoid_derivative(self, x):
        return x * (1 - x)

前向传播实现

    def forward(self, X):
        self.hidden = self.sigmoid(np.dot(X, self.weights1) + self.bias1)
        self.output = self.sigmoid(np.dot(self.hidden, self.weights2) + self.bias2)
        return self.output

反向传播实现

    def backward(self, X, y, output, learning_rate):
        # 计算输出层误差
        output_error = y - output
        output_delta = output_error * self.sigmoid_derivative(output)

        # 计算隐藏层误差
        hidden_error = np.dot(output_delta, self.weights2.T)
        hidden_delta = hidden_error * self.sigmoid_derivative(self.hidden)

        # 更新权重和偏置
        self.weights2 += learning_rate * np.dot(self.hidden.T, output_delta)
        self.bias2 += learning_rate * np.sum(output_delta, axis=0, keepdims=True)
        self.weights1 += learning_rate * np.dot(X.T, hidden_delta)
        self.bias1 += learning_rate * np.sum(hidden_delta, axis=0, keepdims=True)

可视化制作权重更新动画

使用 matplotlib 制作动画可以直观展示权重更新的过程。

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

fig, ax = plt.subplots()

def update(frame):
    # 训练一步
    output = nn.forward(X)
    nn.backward(X, y, output, learning_rate)

    # 更新图像
    ax.clear()
    ax.plot(X, y, 'bo', label='True data')
    ax.plot(X, nn.forward(X), 'r-', label='Prediction')
    ax.legend()

ani = FuncAnimation(fig, update, frames=100, interval=100)
plt.show()

避坑指南

学习率选择

  • 学习率过大会导致震荡或发散
  • 学习率过小会导致收敛缓慢
  • 建议从 0.01 开始尝试,逐步调整

梯度消失问题

  • 深层网络容易出现梯度消失
  • 解决方法:使用 ReLU 等激活函数、批归一化

初始化注意事项

  • 避免全零初始化
  • 推荐使用 Xavier 或 He 初始化

总结与尝试建议

通过本文的学习,你应该已经掌握了 BP 神经网络的前向传播和反向传播原理,并能够用 Python 实现一个简单的神经网络。

建议尝试以下操作来加深理解:

  1. 修改网络结构(如增加隐藏层数量),观察收敛性的变化。
  2. 可视化不同层的权重更新过程,理解信息是如何在网络中流动的。
  3. 尝试不同的激活函数(如 ReLU、tanh),比较它们的表现。

希望这篇博客能帮助你更好地理解 BP 神经网络的工作原理!

正文完
 0
评论(没有评论)