PyTorch - 神经网络基础
PyTorch - 神经网络基础
Section titled “PyTorch - 神经网络基础”本质上,神经网络是由称为人工神经元或感知器的互连处理单元组成的集合。每个神经元接收多个输入 (x1, x2, …, xn),计算这些输入的加权和,加上一个偏置,然后将这个和通过一个激活函数来产生输出。
概念上,单个神经元可以表示如下:
输入:x_1, x_2, ..., x_n
权重:w_1, w_2, ..., w_n(与每个输入相关联)
偏置:b
加权和计算如下:z = (w_1*x_1 + w_2*x_2 + ... + w_n*x_n) + b
然后将这个和 z 通过激活函数 f 来产生神经元的输出:output = f(z)。
用数学符号表示,这通常表达为:
$$Output = f(\sum_{j} w_j x_j + Bias)$$
其中 f 是激活函数。
激活函数为网络引入非线性,使其能够学习复杂的模式。常见的激活函数包括:
- Sigmoid:将输入映射到 0 到 1 之间的范围。常用于二分类的输出层。
f(z) = 1 / (1 + e^-z) - ReLU (修正线性单元):如果输入为正,则直接输出该值;否则,输出零。因其高效性而广泛用于隐藏层。
f(z) = max(0, z) - Tanh (双曲正切):将输入映射到 -1 到 1 之间的范围。
f(z) = (e^z - e^-z) / (e^z + e^-z) - Softmax:用于多分类的输出层,因为它将原始分数向量转换为概率分布。
典型的神经网络架构由多层这样的神经元组成:
-
输入层:接收初始数据(特征)。该层中的神经元数量对应于输入数据中的特征数量。
-
隐藏层:这些层位于输入层和输出层之间。它们执行中间计算和特征提取。一个网络可以有零个或多个隐藏层。‘深度学习’中的’深度’指的就是拥有多个隐藏层。
-
输出层:产生网络的最终结果(例如,类别预测、连续值)。该层中的神经元数量和激活函数取决于具体的任务。
相邻层神经元之间的连接具有关联的权重。神经网络的学习过程包括调整这些权重(和偏置),以最小化网络预测与实际目标值之间的差异。
连接可以是全连接(Dense),即一层中的每个神经元都连接到下一层中的每个神经元,也可以是稀疏的(例如,在卷积神经网络中,神经元仅连接到输入中的局部区域)。
神经网络类型
Section titled “神经网络类型”前馈神经网络 (FNNs)
Section titled “前馈神经网络 (FNNs)”前馈神经网络是最基本的类型。数据沿一个方向流动:从输入层,经过任何隐藏层,到达输出层。网络中没有循环或回路。每一层处理前一层的输出。简单的 FNNs 也被称为多层感知器(Multi-Layer Perceptrons,MLPs)。
想象数据通过一系列处理阶段,每个阶段根据其学习到的权重转换数据,然后将其传递给下一个阶段,而无需回顾。
循环神经网络 (RNNs)
Section titled “循环神经网络 (RNNs)”循环神经网络旨在处理序列数据,其中信息的顺序很重要(例如,时间序列、文本、语音)。RNNs 的连接形成有向循环,使其能够保持对过去输入的内部状态或’记忆’。这种记忆会影响后续输入的处理。
将 RNN 想象成逐字阅读一个句子,它对当前词的理解受到它已经看过的词的影响。
其他重要的类型包括主要用于图像和空间数据的卷积神经网络(CNNs),以及已成为许多序列处理任务领域最先进模型的 Transformer。
在 PyTorch 中构建神经网络
Section titled “在 PyTorch 中构建神经网络”PyTorch 提供了 torch.nn 包,其中包含构建神经网络所需的所有构建块。这包括各种层类型(例如,nn.Linear、nn.Conv2d)、激活函数(例如,nn.ReLU、nn.Sigmoid)、损失函数(例如,nn.MSELoss、nn.CrossEntropyLoss)以及 nn.Sequential 等容器。
PyTorch 中神经网络的典型训练流程包括以下步骤:
- 定义神经网络:创建一个继承自
nn.Module的类。在__init__方法中定义层及其连接,并在forward方法中指定数据如何流经网络。网络将拥有可学习的参数(权重和偏置)。 - 准备数据:加载并预处理数据,通常使用 PyTorch 的
Dataset和DataLoader类按批量迭代数据。 - 迭代并处理输入:遍历数据集。在每次迭代(或步骤)中:
- 反向传播梯度:计算损失相对于网络参数的梯度。这通过调用
loss.backward()完成。 - 更新权重:沿着最小化损失的方向调整网络的参数(权重和偏置)。这通常使用优化器(例如,SGD、Adam)完成。
optimizer.step() - 清零梯度:在下一次迭代之前,使用
optimizer.zero_grad()清除累积的梯度。
更新权重的核心思想通常可以通过以下规则简化:new_weight = old_weight - learning_rate * gradient。优化器实现了这个规则,通常还包含更复杂的改进以提高收敛性和稳定性。
这种前向传播、损失计算、反向传播和权重更新的迭代过程会重复多个轮次(epochs,即对整个数据集遍历多次),直到模型的性能令人满意。