当前位置: 首页 > article >正文

反向传播算法的算法原理与Python实现

前言

反向传播算法是深度学习中最常用的算法之一,用于训练神经网络。它通过计算网络输出的误差,然后反向传播误差到每个神经元,不断更新网络参数,以使误差最小化。
反向传播算法的原理可以分为两个步骤:前向传播和反向传播。

前向传播

在前向传播过程中,我们首先将输入数据传入神经网络中,然后通过神经元之间的连接和激活函数计算出网络的输出。具体而言,对于一个有 L L L层的神经网络,假设输入层有 n n n个神经元,输出层有 m m m个神经元,第 i i i层的神经元个数为 h i h_i hi,则前向传播的计算公式如下:

z ( i + 1 ) = W ( i ) a ( i ) + b ( i ) z^{(i+1)} = W^{(i)}a^{(i)} + b^{(i)} z(i+1)=W(i)a(i)+b(i)

a ( i + 1 ) = f ( z ( i + 1 ) ) a^{(i+1)} = f(z^{(i+1)}) a(i+1)=f(z(i+1))

其中, a ( 1 ) a^{(1)} a(1)为输入数据, f f f为激活函数, W W W为权重矩阵, b b b为偏置向量, z z z为加权输入。

反向传播

在反向传播过程中,我们首先计算出网络输出与期望输出之间的误差,然后将误差反向传播到每个神经元,根据误差调整每个神经元之间的权重和偏置。具体而言,对于一个有 L L L层的神经网络,假设输出层的误差为 E E E,第 i i i层的误差为 E ( i ) E^{(i)} E(i),则反向传播的计算公式如下:

E = 1 2 ∑ j = 1 m ( y j − y ^ j ) 2 E = \frac{1}{2}\sum_{j=1}^{m}(y_j-\hat{y}_j)^2 E=21j=1m(yjy^j)2

E ( i ) = ∂ E ∂ z ( i ) = ∂ E ∂ a ( i ) ∂ a ( i ) ∂ z ( i ) E^{(i)} = \frac{\partial E}{\partial z^{(i)}} = \frac{\partial E}{\partial a^{(i)}} \frac{\partial a^{(i)}}{\partial z^{(i)}} E(i)=z(i)E=a(i)Ez(i)a(i)

∂ E ∂ W ( i ) = ∂ E ( i ) ∂ W ( i ) = a ( i − 1 ) ( E ( i ) ) T \frac{\partial E}{\partial W^{(i)}} = \frac{\partial E^{(i)}}{\partial W^{(i)}} = a^{(i-1)}(E^{(i)})^T W(i)E=W(i)E(i)=a(i1)(E(i))T

∂ E ∂ b ( i ) = ∂ E ( i ) ∂ b ( i ) = E ( i ) \frac{\partial E}{\partial b^{(i)}} = \frac{\partial E^{(i)}}{\partial b^{(i)}} = E^{(i)} b(i)E=b(i)E(i)=E(i)

其中, y y y为期望输出, y ^ \hat{y} y^为网络输出, ∂ E ∂ z ( i ) \frac{\partial E}{\partial z^{(i)}} z(i)E为第 i i i层的误差, ∂ E ∂ W ( i ) \frac{\partial E}{\partial W^{(i)}} W(i)E为权重矩阵的梯度, ∂ E ∂ b ( i ) \frac{\partial E}{\partial b^{(i)}} b(i)E为偏置向量的梯度。

在得到权重和偏置的梯度之后,我们可以根据梯度下降法,不断更新权重和偏置,以最小化误差函数 E E E

import numpy as np

class NeuralNetwork:
    def __init__(self, input_dim, hidden_dim, output_dim):
        self.input_dim = input_dim
        self.hidden_dim = hidden_dim
        self.output_dim = output_dim
        self.W1 = np.random.randn(input_dim, hidden_dim)
        self.b1 = np.zeros((1, hidden_dim))
        self.W2 = np.random.randn(hidden_dim, output_dim)
        self.b2 = np.zeros((1, output_dim))

    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 = np.tanh(self.z2)

    def backward(self, X, y):
        self.delta2 = self.a2 - y
        self.delta1 = np.dot(self.delta2, self.W2.T) * (1 - np.power(self.a1, 2))
        self.dW2 = np.dot(self.a1.T, self.delta2)
        self.db2 = np.sum(self.delta2, axis=0, keepdims=True)
        self.dW1 = np.dot(X.T, self.delta1)
        self.db1 = np.sum(self.delta1, axis=0)

    def update(self, alpha):
        self.W1 -= alpha * self.dW1
        self.b1 -= alpha * self.db1
        self.W2 -= alpha * self.dW2
        self.b2 -= alpha * self.db2

    def fit(self, X, y, epochs, alpha):
        for i in range(epochs):
            self.forward(X)
            self.backward(X, y)
            self.update(alpha)

    def predict(self, X):
        self.forward(X)
        return self.a2

在以上代码中,我们定义了一个NeuralNetwork类,包含了前向传播、反向传播和权重更新等方法。具体而言,我们使用tanh作为激活函数,使用sum of squares作为误差函数,使用随机梯度下降法更新权重和偏置。在训练完成后,我们可以使用predict方法对新数据进行预测。

以上是一个简单的反向传播算法的Python实现示例,实际应用中,我们可以使用深度学习框架如TensorFlow、PyTorch等来更方便地实现和训练神经网络。


http://www.kler.cn/a/3139.html

相关文章:

  • qt-C++笔记之QLine、QRect、QPainterPath、和自定义QGraphicsPathItem、QGraphicsRectItem的区别
  • 力扣【1049. 最后一块石头的重量 II】Java题解(背包问题)
  • 2025年01月27日Github流行趋势
  • electron typescript运行并设置eslint检测
  • python:洛伦兹变换
  • 有限元分析学习——Anasys Workbanch第一阶段笔记梳理
  • 6.网络爬虫——BeautifulSoup详讲与实战
  • C/C++获取文件名的方法(__FILE__,__builtin_FILE(),__BASE_FILE__)
  • 数据结构中的堆
  • java与Spring的循环依赖
  • 指针进阶(中)
  • 对于并发的学习-AQS
  • JVM学习.04. Java内存模型与线程模型
  • 【数据结构与算法】队列和栈的相互实现以及循环队列
  • 有手就行 -- 搭建图床(PicGo+腾讯云)
  • 交叉编译说明:工具链安装和环境变量配置
  • 如何优雅编写测试用例
  • Linux基本命令
  • MongoDB基本操作+集成SpringBoot+实战案例
  • 宝刀未老?低代码何德何能受大厂们的推崇
  • WebSocket 测试工具
  • Windows中: ‘ssh‘ 不是内部或外部命令 解决办法
  • 【Vue全家桶】详解Vue Router(一)
  • UML类与类之间的关系
  • 内存操作函数
  • Portainer堪称最优秀的容器化管理平台