53、反向传播计算梯度与Python环境搭建

反向传播计算梯度与Python环境搭建

1. 反向传播计算梯度

1.1 反向传播概述

在神经网络训练中,计算多层感知器(MLP)成本函数的偏导数的过程被称为反向传播。这是因为从最后一层的权重和偏置开始,反向计算更为高效。反向传播可分为四个步骤:计算最后一层权重、最后一层偏置、隐藏层权重和隐藏层偏置的导数。下面将详细介绍如何计算最后一层权重的偏导数。

1.2 计算最后一层权重相关的成本

设MLP最后一层的索引为L,最后一层的权重矩阵由权重 $w_{ij}^L$ 组成,该层的偏置为 $b_j^L$,激活值标记为 $a_j^L$。最后一层第j个神经元的激活值 $a_j^L$ 的计算公式如下:
[a_j^L = \sigma(b_j^L + \sum_{i=1}^{n_{L - 1}} w_{ij}^L a_{i}^{L - 1})]
其中,$\sigma$ 是Sigmoid函数,$n_{L - 1}$ 是第L - 1层的神经元数量。

给定一个实际的训练示例,理想输出向量 $y$ 在正确的位置为1,其他位置为0。成本是激活向量 $a_j^L$ 与理想输出值 $y_j$ 之间的平方距离,即:
[C = \sum_{j = 1}^{n_L} (a_j^L - y_j)^2]

权重 $w_{ij}^L$ 对成本 $C$ 的影响是间接的。它首先与前一层的激活值相乘,加上偏置,通过Sigmoid函数,最后通过二次成本函数。

1.3 使用链式法则计算最后一层权重的偏导数

为了从 $w_{ij}^L$ 计算到 $C$,可以将其分解为三个步骤:
1. 计算要传入Sigmoid函数的值 $z_j^L$:
[z_j^L = b_j^L + \sum_{i = 1}^{n_{L - 1}} w_{ij}^L a_{i}^{L - 1}]
2. 将 $z_j^L$ 传入Sigmoid函数得到激活值 $a_j^L$:
[a_j^L = \sigma(z_j^L)]
3. 计算成本 $C$:
[C = \sum_{j = 1}^{n_L} (a_j^L - y_j)^2]

根据链式法则,$C$ 关于 $w_{ij}^L$ 的偏导数是这三个“组合”表达式的导数的乘积。具体如下:
- $z_j^L$ 关于 $w_{ij}^L$ 的偏导数是 $a_{i}^{L - 1}$,即:
[\frac{\partial z_j^L}{\partial w_{ij}^L} = a_{i}^{L - 1}]
- $a_j^L$ 关于 $z_j^L$ 的导数是Sigmoid函数 $\sigma$ 的导数,$\sigma(x)$ 的导数为 $\sigma(x)(1 - \sigma(x))$,所以:
[\frac{da_j^L}{dz_j^L} = \sigma’(z_j^L) = \sigma(z_j^L)(1 - \sigma(z_j^L))]
- $C$ 关于 $a_j^L$ 的偏导数为:
[\frac{\partial C}{\partial a_j^L} = 2(a_j^L - y_j)]

综合以上结果,$C$ 关于 $w_{ij}^L$ 的偏导数为:
[\frac{\partial C}{\partial w_{ij}^L} = \frac{\partial C}{\partial a_j^L} \frac{da_j^L}{dz_j^L} \frac{\partial z_j^L}{\partial w_{ij}^L} = 2(a_j^L - y_j) \cdot \sigma(z_j^L)(1 - \sigma(z_j^L)) \cdot a_{i}^{L - 1}]

这个公式是计算成本函数 $C$ 整个梯度所需的四个公式之一,它给出了最后一层任何权重的偏导数。

1.4 练习:使用SymPy计算Sigmoid函数的导数

可以使用SymPy自动计算Sigmoid函数的导数,并证明其结果等于 $\sigma(x)(1 - \sigma(x))$。以下是具体代码:

from sympy import *
X = symbols('x')
print(diff(1 / (1 + exp(-X)), X))

输出结果为:
[\frac{e^{-x}}{(1 + e^{-x})^2}]

通过一些代数运算可以证明该表达式等于 $\sigma(x)(1 - \sigma(x))$:
[
\begin{align }
\frac{e^{-x}}{(1 + e^{-x})^2} &= \frac{e^{-x}}{1 + e^{-x}} \cdot \frac{1}{1 + e^{-x}} \
&= \frac{e^{-x}}{1 + e^{-x}} \cdot \sigma(x) \
&= \frac{1}{e^x + 1} \cdot \sigma(x) \
&= \frac{e^{-x}}{e^{-x}} \cdot \frac{1}{e^x + 1} \cdot \sigma(x) \
&= \frac{e^{-x}}{1 + e^{-x}} \cdot \sigma(x) \
&= \left(\frac{1 + e^{-x}}{1 + e^{-x}} - \frac{1}{1 + e^{-x}}\right) \cdot \sigma(x) \
&= \left(1 - \frac{1}{1 + e^{-x}}\right) \cdot \sigma(x) \
&= (1 - \sigma(x)) \cdot \sigma(x)
\end{align
}
]

2. Python环境搭建

2.1 检查现有Python安装

有可能你的计算机上已经安装了Python,即使你没有意识到。要检查现有安装情况,打开终端窗口(在Windows上是CMD或PowerShell)并输入 python 。在全新的Mac上,你应该会看到一个Python 2.7终端。可以按 Ctrl - D 退出终端。

对于后续的示例,建议使用Python 3,特别是Anaconda发行版。如果已经有Python安装,后续步骤可能会比较棘手。如果以下说明有任何不适用的情况,建议使用错误消息在Google或StackOverflow上搜索解决方案。

2.2 下载并安装Anaconda

  1. 访问 Anaconda官网 下载Anaconda Python发行版。
  2. 点击“Download”,选择以3开头的Python版本(撰写本文时为Python 3.7)。
  3. 打开安装程序,它会引导你完成安装过程。安装程序对话框根据操作系统的不同而有所不同。
  4. 安装完成后,打开一个新的终端,输入 python 进入带有Anaconda的Python 3会话。如果没有看到以3开头的Python版本和“Anaconda”字样,可能需要编辑 PATH 环境变量,或者输入 python3 来明确使用Python 3安装。

2.3 使用Python交互模式

在终端窗口中,三个尖括号 >>> 提示你输入一行Python代码。输入 2 + 2 并按回车键,应该会看到Python解释器对该语句的计算结果4。

交互模式也称为REPL(读取 - 评估 - 打印循环)。Python会话读取输入的代码行,评估它,并打印结果,这个过程会根据需要重复多次。按 Ctrl - D 表示输入代码结束,返回终端会话。

Python交互模式通常可以识别多行语句。例如,定义一个新的Python函数 f(x) 时,输入的第一行 def f(x): 后,Python交互会话会显示 ... 表示期望更多输入。可以缩进以扩展函数,然后按两次回车键让Python知道多行代码输入完成并实现该函数。

需要注意的是,在交互会话中编写的任何代码在退出会话时都会消失。因此,如果要编写大量代码,最好将其放在脚本文件或Jupyter笔记本中。

2.4 创建并运行Python脚本文件

可以使用任何喜欢的文本编辑器创建Python文件。建议使用专门为编程设计的文本编辑器,而不是像Microsoft Word这样的富文本编辑器,因为它可能会插入不可见或不需要的格式字符。以下是创建和运行Python脚本文件的步骤:
1. 选择一个文本编辑器,如Visual Studio Code、Atom(跨平台)或Windows上的Notepad++。也可以使用基于终端的文本编辑器,如Emacs或Vim。
2. 创建一个新的文本文件,文件名以 .py 结尾。例如,创建一个名为 first.py 的文件,并输入以下代码:

for i in range(10):
    print(i ** 2)
  1. 打开终端,进入Python文件所在的目录。例如,在Mac上输入 cd ~/Documents 进入 Documents 目录。
  2. 输入 ls first.py 确认Python脚本文件在当前目录中。
  3. 输入 python first.py 执行脚本文件,解释器会打印出0到9的平方。

当解决更复杂的问题时,可能需要将代码拆分成多个文件。例如,将函数 f(x) 放在一个单独的Python文件 function.py 中,并在 first.py 中使用它。具体步骤如下:
1. 创建 function.py 文件,并将 f(x) 的代码复制到其中。
2. 在包含 first.py function.py 的目录中添加一个名为 __init__.py 的空文本文件。在Mac或Linux机器上,可以通过输入 touch __init__.py 快速创建该文件。
3. 在 first.py 的第一行添加 from function import f ,然后再次运行 python first.py ,应该会得到与之前相同的结果。

2.5 使用Jupyter笔记本

Jupyter Notebook是一个用于Python(以及其他语言)编码的图形界面。与Python交互会话类似,在Jupyter笔记本中输入代码行,它会打印结果。不同之处在于,Jupyter界面比终端更美观,并且可以保存会话以便稍后恢复或重新运行。

Jupyter Notebook应该会随Anaconda自动安装。如果使用的是其他Python发行版,也可以使用pip安装Jupyter。要打开Jupyter Notebook界面,在想要工作的目录中输入 jupyter notebook python -m notebook 。终端会显示大量文本,默认的Web浏览器会打开显示Jupyter Notebook界面。

在浏览器中打开的第一个屏幕上,可以看到工作目录中的所有文件。要创建一个新的笔记本,点击左上角的Jupyter徽标返回主视图,然后点击右侧的“New”下拉菜单,选择“Python 3”。

在新的笔记本中,输入一个Python表达式,然后按 Shift - Enter 进行评估。每个输入显示在一个框中,相应的输出显示在其下方。如果只按回车键而不是 Shift - Enter ,可以在输入框内添加新行。在界面中,上面框中定义的变量和函数可以被下面的框使用。

为了确保所有文件都被保存,应该通过点击“Quit”退出Jupyter,而不是仅仅关闭浏览器标签或停止交互过程。

2.6 总结

  • 人工神经网络是一种数学函数,其计算过程模拟了人类大脑中信号的流动。它以向量作为输入,返回另一个向量作为输出。
  • 神经网络可用于对向量数据进行分类,例如将图像转换为灰度像素值向量。神经网络的输出是一个数字向量,表示输入向量属于各个可能类别的置信度。
  • 多层感知器(MLP)是一种特定类型的人工神经网络,由多个有序的神经元层组成,每层的神经元与前一层的神经元相连并受其影响。
  • 训练神经网络意味着调整所有权重和偏置的值,以使网络能够最优地执行任务。可以使用成本函数来衡量神经网络的预测误差,梯度下降法可以帮助找到使成本函数最小化的权重和偏置值。
  • 神经网络可以高效地训练,因为存在简单、精确的公式来计算成本函数关于权重和偏置的偏导数,这些公式通过反向传播算法和微积分中的链式法则得到。
  • Python的scikit - learn库有一个内置的MLPClassifier类,可以自动对分类向量数据进行训练。

2.7 流程图

graph LR
    A[检查现有Python安装] --> B{是否安装Python 3}
    B -- 是 --> C[使用Anaconda安装Python 3]
    B -- 否 --> D[下载并安装Anaconda]
    D --> E[打开终端输入python]
    E --> F{是否显示Python 3和Anaconda}
    F -- 是 --> G[使用Python交互模式]
    F -- 否 --> H[编辑PATH环境变量或输入python3]
    G --> I[创建并运行Python脚本文件]
    I --> J[使用Jupyter笔记本]

2.8 表格

操作 步骤
检查现有Python安装 打开终端,输入 python ,按 Ctrl - D 退出
下载并安装Anaconda 访问官网,选择Python 3版本下载,打开安装程序完成安装
使用Python交互模式 在终端输入代码,按 Shift - Enter 执行,按 Ctrl - D 退出
创建并运行Python脚本文件 使用文本编辑器创建 .py 文件,在终端进入文件目录,输入 python 文件名.py 执行
使用Jupyter笔记本 在目录中输入 jupyter notebook 打开界面,创建新笔记本,输入代码按 Shift - Enter 执行

3. 反向传播计算梯度的深入理解

3.1 反向传播的重要性

反向传播在神经网络的训练中起着至关重要的作用。它使得我们能够高效地计算成本函数关于权重和偏置的偏导数,从而可以使用梯度下降等优化算法来调整这些参数,使得神经网络的预测结果更加准确。通过从最后一层开始反向计算偏导数,避免了重复计算,大大提高了计算效率。

3.2 与链式法则的紧密联系

链式法则是反向传播算法的核心数学原理。在计算多层感知器(MLP)中成本函数关于权重和偏置的偏导数时,由于成本函数是通过多个函数的复合得到的,所以需要使用链式法则将这些复合函数的导数相乘。例如,在计算最后一层权重的偏导数时,将 $C$ 关于 $a_j^L$ 的偏导数、$a_j^L$ 关于 $z_j^L$ 的导数以及 $z_j^L$ 关于 $w_{ij}^L$ 的偏导数相乘,得到最终的偏导数。这种方法使得我们能够将复杂的导数计算分解为多个简单的步骤,从而更容易实现和理解。

3.3 后续权重导数计算的复杂性

虽然已经介绍了最后一层权重的偏导数计算方法,但其他层权重的导数计算需要更复杂的链式法则应用。因为一个神经元的激活值会影响神经网络中后续的所有激活值,所以每个权重都会对后续的激活值产生影响。这意味着在计算其他层权重的偏导数时,需要考虑更多的因素和路径。不过,这并不是无法完成的任务,有很多优秀的在线资源可以详细地介绍反向传播的每一个步骤。

3.4 流程图

graph LR
    A[输入训练数据] --> B[前向传播计算激活值]
    B --> C[计算成本函数]
    C --> D[反向传播计算偏导数]
    D --> E[使用梯度下降更新权重和偏置]
    E --> F{是否达到收敛条件}
    F -- 否 --> B
    F -- 是 --> G[完成训练]

3.5 表格

步骤 说明
前向传播 根据输入数据和当前的权重、偏置计算各层的激活值
计算成本函数 衡量神经网络的预测结果与实际结果之间的误差
反向传播 从最后一层开始,使用链式法则计算成本函数关于权重和偏置的偏导数
梯度下降 根据计算得到的偏导数更新权重和偏置,使得成本函数减小
收敛判断 判断是否达到收敛条件,如成本函数的变化小于某个阈值

4. Python环境搭建的注意事项

4.1 环境变量的重要性

在安装Anaconda后,如果没有正确配置 PATH 环境变量,可能会导致在终端输入 python 时无法进入带有Anaconda的Python 3会话。这是因为系统无法找到正确的Python解释器路径。因此,当遇到这种问题时,需要编辑 PATH 环境变量,确保终端能够找到Anaconda安装的Python 3解释器。

4.2 文本编辑器的选择

在创建Python脚本文件时,选择合适的文本编辑器非常重要。专门为编程设计的文本编辑器,如Visual Studio Code、Atom等,具有语法高亮、代码提示等功能,可以大大提高编程效率。而像Microsoft Word这样的富文本编辑器,会插入一些不可见的格式字符,可能会导致Python代码无法正常运行。

4.3 Jupyter Notebook的优势与使用技巧

Jupyter Notebook不仅提供了一个美观的界面,还可以方便地保存和分享代码。在使用Jupyter Notebook时,建议在定义变量和函数后立即进行测试,确保其正确性。同时,为了保证代码的可重复性,建议按照从上到下的顺序依次运行每个代码块。如果需要重新运行某个代码块,要注意之前定义的变量和函数可能已经被修改。

4.4 表格

注意事项 说明
环境变量配置 确保 PATH 环境变量指向Anaconda安装的Python 3解释器
文本编辑器选择 选择专门为编程设计的文本编辑器,避免使用富文本编辑器
Jupyter Notebook使用 按顺序运行代码块,定义变量和函数后及时测试,注意变量和函数的修改

5. 总结与展望

5.1 知识总结

本文详细介绍了反向传播计算梯度的方法和Python环境的搭建过程。反向传播通过链式法则高效地计算成本函数关于权重和偏置的偏导数,为神经网络的训练提供了关键支持。Python环境的搭建则为我们实现和测试神经网络提供了基础。我们学习了如何使用Anaconda安装Python 3,如何在交互模式、脚本文件和Jupyter Notebook中编写和运行Python代码。

5.2 未来展望

随着人工智能和机器学习的不断发展,神经网络的应用越来越广泛。反向传播算法和Python编程将在更多的领域发挥重要作用。未来,我们可以进一步探索更复杂的神经网络结构,如卷积神经网络(CNN)、循环神经网络(RNN)等,以及更高效的训练算法,如自适应学习率算法、随机梯度下降的变种等。同时,掌握Python的更多高级特性和相关库,如NumPy、Matplotlib等,将有助于我们更好地实现和优化神经网络。

5.3 流程图

graph LR
    A[掌握反向传播和Python环境搭建] --> B[探索复杂神经网络结构]
    B --> C[研究高效训练算法]
    C --> D[应用于更多领域]

5.4 表格

阶段 目标
基础学习 掌握反向传播计算梯度和Python环境搭建
深入探索 学习复杂神经网络结构和高效训练算法
应用实践 将知识应用于更多实际领域
### Python反向传播神经网络的实现及原理 #### 1. 反向传播算法的核心概念 反向传播算法(Backpropagation, BP)是深度学习领域中一种重要的监督学习方法,主要用于训练多层神经网络。其核心思想在于通过计算损失函数相对于各层权重的梯度,并利用这些梯度调整权重,从而使网络输出更接近目标值。 该算法主要分为两部分: - **前向传播**:输入数据经过每一层神经元处理后得到最终输出。此阶段的主要目的是计算当前网络的状态以及对应的预测误差[^1]。 - **反向传播**:从输出层开始逐层向前传递误差信号,同时依据链式法则计算每层权重的梯度并更新它们[^4]。 #### 2. 数学推导中的关键公式 为了更好地理解反向传播的工作机制,以下是几个重要公式的概述: 假设我们有一个简单的全连接神经网络,其中第 \( l \) 层的激活值表示为 \( a^{(l)} \),权重量化矩阵记作 \( W^{(l)} \),偏置项为 \( b^{(l)} \),则有如下关系: \[ z^{(l)} = W^{(l)}a^{(l-1)} + b^{(l)} \] \[ a^{(l)} = f(z^{(l)}) \] 对于给定的目标值 \( y \) 和实际输出 \( \hat{y} \),定义均方误差作为损失函数: \[ L(y,\hat{y}) = \frac{1}{2}(y-\hat{y})^2 \] 在反向传播过程中,我们需要求解以下梯度: - 针对某一层权重的梯度:\( \frac{\partial L}{\partial W^{(l)}} \) - 对应于偏置的梯度:\( \frac{\partial L}{\partial b^{(l)}} \) 具体而言,可以通过链式法则逐步展开上述表达式,从而获得精确的数值估计[^3]。 #### 3. 使用 Python 的简单实现 下面展示了一个基于 NumPy 库的小型 BP 网络框架实例代码片段: ```python import numpy as np class NeuralNetwork: def __init__(self, input_size, hidden_size, output_size): self.W1 = np.random.randn(input_size, hidden_size) self.b1 = np.zeros(hidden_size) self.W2 = np.random.randn(hidden_size, output_size) self.b2 = np.zeros(output_size) def sigmoid(self, x): return 1 / (1 + np.exp(-x)) def forward(self, X): self.z1 = np.dot(X, self.W1) + self.b1 self.a1 = self.sigmoid(self.z1) self.z2 = np.dot(self.a1, self.W2) + self.b2 self.y_hat = self.sigmoid(self.z2) return self.y_hat def backward(self, X, Y, learning_rate=0.1): m = X.shape[0] delta_output = (self.y_hat - Y) * self.y_hat * (1 - self.y_hat) dW2 = np.dot(self.a1.T, delta_output) / m db2 = np.sum(delta_output, axis=0) / m delta_hidden = np.dot(delta_output, self.W2.T) * self.a1 * (1 - self.a1) dW1 = np.dot(X.T, delta_hidden) / m db1 = np.sum(delta_hidden, axis=0) / m # 更新参数 self.W2 -= learning_rate * dW2 self.b2 -= learning_rate * db2 self.W1 -= learning_rate * dW1 self.b1 -= learning_rate * db1 # 测试用例 X_train = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) Y_train = np.array([[0], [1], [1], [0]]) nn = NeuralNetwork(2, 2, 1) for epoch in range(10000): nn.forward(X_train) nn.backward(X_train, Y_train) print(nn.forward(X_train)) ``` 以上代码构建了一种简易版本的双隐藏节点 XOR 解决方案演示如何运用正向逆向流程完成一次完整的迭代操作[^5]。 #### 4. 总结说明 综上所述,Python 提供了强大的工具支持开发者轻松搭建自己的人工神经网络模型并通过反向传播技术对其进行高效调优。无论是理论层面还是实践环节都体现了这一经典算法的强大适应性和灵活性[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值