什么是反向传播算法,如何工作?

什么是反向传播算法?

反向传播算法(Backpropagation Algorithm)是一种常用的神经网络训练算法,它用于计算人工神经网络中权重的梯度,并通过梯度下降的方法来更新网络的权重,从而实现网络的训练和学习。通过反向传播算法,神经网络可以根据给定的输入和期望输出来调整权重,以便改进网络的预测能力。

反向传播算法的工作原理

反向传播算法基于链式法则(Chain Rule)来计算网络权重的梯度。在神经网络中,每个神经元都有一个输入和一个输出。输入是由前一层神经元的输出以及与其对应的权重计算得到的,而输出是通过激活函数对输入的加权和进行转换得到的。

反向传播算法的核心思想是通过将网络预测值与实际值之间的误差从输出层开始向前传播,逐层计算每个神经元的梯度,并沿着梯度的方向更新权重。具体步骤如下:

  1. 初始化网络的权重和偏置。
  2. 对于每个训练样本,进行前向传播计算,得到网络的输出值。
  3. 计算输出层的误差,即实际值与预测值之间的差异。
  4. 从输出层开始,利用链式法则计算每个隐藏层和输入层的误差,即将上一层的误差与该层的权重相乘并传递给下一层。
  5. 计算每个神经元的梯度,即误差乘以激活函数的导数。
  6. 更新权重和偏置,即根据梯度下降的原理,按照一定的学习率更新权重和偏置的值。

反向传播算法的公式推导

首先,假设我们有一个具有$L$层的神经网络,$w^{[l]}_{ij}$表示第$l$层第$i$个神经元与第$l+1$层第$j$个神经元之间的权重,$a^{[l]}_i$表示第$l$层第$i$个神经元的输出,$z^{[l+1]}_j$表示第$l+1$层第$j$个神经元的输入,$E$表示网络的误差。通过链式法则,我们可以得到以下公式:

$$\frac{\partial E}{\partial w^{[l]}_{ij}} = \delta^{[l+1]}_j a^{[l]}_i$$

其中,$\delta^{[l+1]}_j$表示第$l+1$层第$j$个神经元的误差,可以通过以下公式计算:

$$\delta^{[l+1]}_j = \frac{\partial E}{\partial z^{[l+1]}_j} = \frac{\partial E}{\partial a^{[l+1]}_j} \cdot \frac{\partial a^{[l+1]}_j}{\partial z^{[l+1]}_j} = \frac{\partial E}{\partial a^{[l+1]}_j} \cdot \sigma'(z^{[l+1]}_j)$$

其中,$\sigma'(z^{[l+1]}_j)$表示第$l+1$层第$j$个神经元的激活函数的导数。根据误差的定义,我们可以将$\frac{\partial E}{\partial a^{[l+1]}_j}$表示为:

$$\frac{\partial E}{\partial a^{[l+1]}j} = \sum_k \frac{\partial E}{\partial z^{[l+2]}_k} \cdot \frac{\partial z^{[l+2]}_k}{\partial a^{[l+1]}_j} = \sum_k \delta^{[l+2]}_k w^{[l+1]}{jk}$$

将其代入$\delta^{[l+1]}_j$的公式中,可以得到:

$$\delta^{[l+1]}j = \sum_k \delta^{[l+2]}_k w^{[l+1]}{jk} \cdot \sigma'(z^{[l+1]}_j)$$

对于输出层和隐藏层的梯度更新公式如下:

$$\frac{\partial E}{\partial w^{[l]}{ij}} = \delta^{[l+1]}_j a^{[l]}_i$$
$$\frac{\partial E}{\partial b^{[l]}
{j}} = \delta^{[l+1]}_j$$

其中,$b^{[l]}_{j}$表示第$l$层第$j$个神经元的偏置。

反向传播算法的计算步骤

  1. 初始化网络的权重和偏置。
  2. 对每个训练样本,进行前向传播计算。
  3. 计算输出层的误差。
  4. 从输出层开始,计算每个隐藏层和输入层的误差,并计算每个神经元的梯度。
  5. 更新权重和偏置。
  6. 重复步骤2-5,直到满足停止条件。

Python代码示例

以下是一个简单的神经网络实现反向传播算法的Python代码示例。

import numpy as np

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

def sigmoid_derivative(x):
    return sigmoid(x) * (1 - sigmoid(x))

# 定义神经网络类
class NeuralNetwork:
    def __init__(self, sizes):
        self.num_layers = len(sizes)
        self.sizes = sizes
        self.weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])]
        self.biases = [np.random.randn(y, 1) for y in sizes[1:]]

    def feedforward(self, x):
        a = x
        for w, b in zip(self.weights, self.biases):
            a = sigmoid(np.dot(w, a) + b)
        return a

    def backpropagation(self, x, y):
        # 初始化梯度
        delta_weights = [np.zeros(w.shape) for w in self.weights]
        delta_biases = [np.zeros(b.shape) for b in self.biases]

        # 前向传播
        activation = x
        activations = [x]
        zs = []
        for w, b in zip(self.weights, self.biases):
            z = np.dot(w, activation) + b
            zs.append(z)
            activation = sigmoid(z)
            activations.append(activation)

        # 计算输出层的误差
        delta = self.cost_derivative(activations[-1], y) * sigmoid_derivative(zs[-1])
        delta_weights[-1] = np.dot(delta, activations[-2].T)
        delta_biases[-1] = delta

        # 从输出层开始,逐层计算隐藏层和输入层的误差,并计算梯度
        for l in range(2, self.num_layers):
            z = zs[-l]
            sp = sigmoid_derivative(z)
            delta = np.dot(self.weights[-l+1].T, delta) * sp
            delta_weights[-l] = np.dot(delta, activations[-l-1].T)
            delta_biases[-l] = delta

        return (delta_weights, delta_biases)

    def update_weights(self, mini_batch, learning_rate):
        # 初始化梯度
        delta_weights = [np.zeros(w.shape) for w in self.weights]
        delta_biases = [np.zeros(b.shape) for b in self.biases]

        # 对mini batch中的每个样本进行反向传播,并累加梯度
        for x, y in mini_batch:
            delta_delta_weights, delta_delta_biases = self.backpropagation(x, y)
            delta_weights = [dw + ddw for dw, ddw in zip(delta_weights, delta_delta_weights)]
            delta_biases = [db + ddb for db, ddb in zip(delta_biases, delta_delta_biases)]

        # 更新权重和偏置
        self.weights = [w - (learning_rate/len(mini_batch)) * dw for w, dw in zip(self.weights, delta_weights)]
        self.biases = [b - (learning_rate/len(mini_batch)) * db for b, db in zip(self.biases, delta_biases)]

    def train(self, training_data, epochs, mini_batch_size, learning_rate):
        n = len(training_data)
        for epoch in range(epochs):
            np.random.shuffle(training_data)  # 每个epoch前都洗牌
            mini_batches = [training_data[k:k+mini_batch_size] for k in range(0, n, mini_batch_size)]
            for mini_batch in mini_batches:
                self.update_weights(mini_batch, learning_rate)

    def cost_derivative(self, output_activations, y):
        return (output_activations - y)

# 测试数据
training_data = [
    (np.array([[0], [0]]), np.array([[0]])),
    (np.array([[0], [1]]), np.array([[1]])),
    (np.array([[1], [0]]), np.array([[1]])),
    (np.array([[1], [1]]), np.array([[0]]))
]

# 创建神经网络
network = NeuralNetwork([2, 2, 1])
# 训练神经网络
network.train(training_data, epochs=1000, mini_batch_size=4, learning_rate=0.1)
# 测试神经网络
for x, y in training_data:
    print("输入:", x)
    print("预测:", network.feedforward(x))
    print("实际:", y)
    print("--------------")

代码细节解释

  • 在代码示例中,我们使用了numpy库来进行矩阵运算和数学函数的计算。
  • 神经网络的初始化部分定义了网络的结构(每层的神经元个数)并随机初始化权重和偏置。
  • feedforward方法用于计算神经网络的输出值。它采用前向传播的方式,逐层计算每个神经元的输出。
  • backpropagation方法用于计算每个权重和偏置的梯度。它首先进行前向传播得到每层的输出值和输入值,然后根据公式推导计算每层的误差及梯度。
  • update_weights方法用于更新权重和偏置。它接受一个mini batch的数据,并对其中的每个样本进行反向传播计算梯度,最后累加得到梯度平均值并更新权重和偏置。
  • train方法用于训练神经网络。它接受训练数据、迭代次数、mini batch大小和学习率等参数,并按照指定次数进行训练。
  • cost_derivative方法用于计算输出层的梯度。它根据误差的定义计算输出层的误差,用于反向传播的计算。

通过以上的代码实现和解释,我们可以看到反向传播算法在神经网络的训练中起着重要的作用。它通过梯度下降的方式不断调整权重和偏置,使得网络逐渐优化,并能够更准确地进行预测和分类。

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/825579/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 如何使用注意力机制来提升模型性能?

    如何使用注意力机制来提升模型性能? 在机器学习领域,注意力机制(Attention Mechanism)已经成为提升模型性能的重要技术之一。它是一种模拟人类视觉注意力机制的方法,能…

    Neural 2024年4月16日
    026
  • 什么是迁移学习,如何运用?

    什么是迁移学习 在机器学习中,迁移学习(Transfer Learning)指的是将一个训练好的模型或者知识从一个任务或领域应用到另一个任务或领域的过程。迁移学习能够通过利用源领域…

    Neural 2024年4月16日
    030
  • 什么是中间层特征可视化,如何理解?

    什么是中间层特征可视化,如何理解? 在进行深度学习任务时,神经网络中的每一层会学习到一些特征,这些特征在输入数据上进行了抽象。中间层特征可视化是指通过可视化的方式来理解和解释神经网…

    Neural 2024年4月16日
    028
  • 什么是循环神经网络,如何优化?

    什么是循环神经网络? 循环神经网络(Recurrent Neural Network,RNN)是一种特殊的神经网络,主要用于处理序列数据。与其他神经网络不同的是,RNN在处理输入时…

    Neural 2024年4月16日
    026
  • 什么是迁移学习中的特征提取和微调?

    什么是迁移学习中的特征提取和微调? 在机器学习中,迁移学习是指通过将一个领域中已经训练好的模型使用在另一个相关领域中的技术。在实践中,通常只有少量的标记样本可用于训练,迁移学习可以…

    Neural 2024年4月16日
    017
  • Neural网络是什么?它们是如何工作的?

    Neural网络是什么? 神经网络(Neural Network)是一种机器学习算法,它模拟了人类的神经系统,通过一系列的神经元(neurons)和它们之间的连接进行计算和学习。它…

    Neural 2024年4月16日
    021
  • 为什么要进行数据预处理?

    为什么要进行数据预处理? 数据预处理在机器学习中扮演着重要的角色。它是一个数据科学家或机器学习工程师需要经历的必要步骤。数据预处理的主要目的是使原始数据更加适合应用于机器学习算法的…

    Neural 2024年4月16日
    024
  • 什么是模型集成,如何应用?

    什么是模型集成? 模型集成是指将多个单一模型的预测结果结合起来,以提高整体预测的准确性和鲁棒性的技术。通过结合不同的模型,各个模型之间的优势互补,可以降低模型的方差、提高模型的泛化…

    Neural 2024年4月16日
    028
  • 什么是正则化,如何应用?

    什么是正则化 正则化(Regularization)是机器学习中常用的一种技术,用于解决过拟合(Overfitting)的问题。过拟合是指在训练集上表现良好,但在未知数据集上表现差…

    Neural 2024年4月16日
    031
  • 为何我们需要使用Neural网络来解决问题?

    为何我们需要使用神经网络来解决问题 在机器学习领域,神经网络是一种强大的工具,用于解决各种问题。它模仿人脑的结构和功能,并且已经在许多领域取得了卓越的成果,如图像识别、自然语言处理…

    Neural 2024年4月16日
    027
  • 什么是梯度消失问题,如何解决?

    什么是梯度消失问题? 梯度消失问题(Gradient Vanishing Problem)是机器学习中一种常见的问题,特别是在使用深层神经网络时。当神经网络的层数增加时,梯度很容易…

    Neural 2024年4月16日
    023
  • 什么是对抗训练,如何应用?

    什么是对抗训练?如何应用? 对抗训练(Adversarial Training)是一种机器学习算法,用于提高模型对抗特定输入样本的能力。在现实世界中存在各种扰动、干扰和攻击,对模型…

    Neural 2024年4月16日
    019
  • 如何使用生成对抗网络生成新的数据?

    如何使用生成对抗网络生成新的数据? 介绍 生成对抗网络(Generative Adversarial Networks,简称GAN)是一种用于生成新样本的机器学习模型。它由两个主要…

    Neural 2024年4月16日
    026
  • 什么是卷积神经网络,如何构建?

    什么是卷积神经网络? 卷积神经网络(Convolutional Neural Network,CNN)是一种深度学习算法,广泛应用于计算机视觉领域。与传统的全连接神经网络相比,CN…

    Neural 2024年4月16日
    023
  • 如何使用自监督学习进行预训练?

    如何使用自监督学习进行预训练? 在机器学习领域,预训练是指在大规模无标签数据上对模型进行初始化训练,然后使用有标签数据进行微调,以提高模型的性能。自监督学习是一种无监督学习的方法,…

    Neural 2024年4月16日
    027
  • 什么是序列到序列学习,如何应用?

    什么是序列到序列学习 序列到序列学习(Sequence-to-Sequence Learning)是指一类机器学习任务,其目标是将一个序列作为输入,并将其映射到另一个序列作为输出。…

    Neural 2024年4月16日
    025
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球