bp(back propagation)

定义

反向传播全名是反向传播误差算法(Backpropagation),是一种监督学习方法,用于调整神经网络中权重参数,以最小化模型的预测误差。反向传播通过计算损失函数相对于网络参数的梯度,然后使用梯度下降等优化算法来更新参数,从而提高模型的性能

核心思想是从网络的输出层向输入层传播误差信号,然后根据这些误差信号来更新网络中的权重和偏差,以使模型的输出更接近实际目标

过程

前向传播:将输入数据输入到网络中,通过神经网络的前向传播计算出每个神经元的输出结果,直到输出层输出最终的结果。
计算损失函数:将神经网络输出的结果与真实标签进行比较,计算出损失函数的值。
反向传播误差:从输出层开始,计算每个神经元的误差,然后向前计算每个神经元的误差,直到计算出输入层每个神经元的误差。具体来说,我们首先计算输出层的误差,然后反向传播到前一层隐藏层,计算隐藏层的误差,并将误差反向传播到更早的层,直到计算出输入层的误差。这个过程可以使用链式法则来计算。
计算梯度:根据误差计算每个神经元的梯度,即损失函数对每个神经元权重和偏差的偏导数。
更新参数:使用梯度下降法或其他优化方法来更新每个神经元的权重和偏差,使得损失函数的值最小化。

设置初始值如图:
 目标:给出输入数据i1,i2(0.05和0.10),使输出尽可能与原始输出o1,o2(0.01和0.99)接近

神经网络中信息传递的基本原理:
在神经网络中,前一层神经元的输出通常作为下一层神经元的输入

前向传播计算过程

y=wx+b
例如上图中h1的输入input1 = w1i1+w2i2+b1
假设采用的sigmoid激活函数,则输出output1 = 1/(1+e^-input1)
而这个输出output1又会作为下一层神经元o1、o2的输入
由此我们可以轻松计算出最后的输出

计算损失函数(采用均方误差MSE)

将前向传播计算得到的输出与原始输出比较
MSE = Σ(预测值 - 实际观测值)^2 / 观测值的数量

反向传播误差(链式法则)

从输出层开始,计算每个神经元的误差,然后向前计算每个神经元的误差,直到计算出输入层每个神经元的误差

计算梯度

当前层的梯度 = 当前层输出的梯度 × 当前层输入的梯度
以b站某up主讲解中的一个片段为例:
其中绿色字体代表的是输入值,红色字体为反向传播的梯度

我们以最左上角w0,x0那为例,假设得到的是y0,(再次提醒,上面绿色字体为前向传播计算的值)
则x0的梯度为:y0对x0求导再乘以0.2(当前层输出的梯度),最后得到0.40(至于0.39可能是笔误)
同理w0的梯度:y0对w0求导再乘以0.2,即-1.0*0.2 = 0.20

更新参数

设置一个学习率,根据之前计算的梯度就可以进行参数权重更新了

简单实例

import numpy as np

# 定义 Sigmoid 激活函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

# 定义 Sigmoid 激活函数的导数
def sigmoid_derivative(x):
    return x * (1 - x)

# 创建神经网络类
class NeuralNetwork:
    def __init__(self, input_size, hidden_size, output_size):
        # 初始化权重
        self.weights_input_hidden = np.random.rand(input_size, hidden_size)
        self.weights_hidden_output = np.random.rand(hidden_size, output_size)

    def forward(self, X):
        # 前向传播
        self.hidden_input = np.dot(X, self.weights_input_hidden)
        self.hidden_output = sigmoid(self.hidden_input)
        self.output = np.dot(self.hidden_output, self.weights_hidden_output)
        return self.output

    def backward(self, X, y, output, learning_rate):
        # 反向传播
        error = y - output
        delta_output = error
        error_hidden = delta_output.dot(self.weights_hidden_output.T)
        delta_hidden = error_hidden * sigmoid_derivative(self.hidden_output)

        # 更新权重
        self.weights_hidden_output += self.hidden_output.T.dot(delta_output) * learning_rate
        self.weights_input_hidden += X.T.dot(delta_hidden) * learning_rate

    def train(self, X, y, learning_rate, epochs):
        for i in range(epochs):
            output = self.forward(X)
            self.backward(X, y, output, learning_rate)
            if i % 1000 == 0:
                loss = np.mean(np.square(y - output))
                print(f"Epoch {i}, Loss: {loss}")

# 示例数据
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]])

# 创建神经网络
input_size = 2
hidden_size = 4
output_size = 1
learning_rate = 0.1
epochs = 10000

nn = NeuralNetwork(input_size, hidden_size, output_size)

# 训练神经网络
nn.train(X, y, learning_rate, epochs)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值