(二)神经网络训练基础:激活函数、反向传播与自动求导

本节聚焦「如何训练」:先对齐常用术语,再依次说明激活函数、训练循环、反向传播与自动求导。

机器学习中的关键术语及其含义

神经元及神经网络

一种模仿生物神经网络的结构和功能的数学模型或计算模型,按照一定的规则将多个神经元连接起来的网络。

神经网络是一种运算模型,由大量的节点(或神经元)之间相互联接构成。每个节点代表一种特定的输出函数,称为激活函数。

多层感知机

多个神经元可以组合一起,形成多层感知机。

多层感知器(Multi-Layer Perceptron,MLP):

通过叠加多层全连接层来提升网络的表达能力。相比单层网络,多层感知器有很多中间层的输出并不暴露给最终输出,这些层被称为隐含器(Hidden Layers)。

关键术语

  • 样本[*]:

样本是数据集中的单个实例或数据点,通常由一组特征(自变量)和一个标签(因变量)组成。

举例:房价预测中,一个样本可能包含房屋的面积、位置、房龄等特征,以及对应的房价标签。

  • 标签[*]:

标签是与样本关联的目标值或类别,用于监督学习中指导模型学习。

举例:情感分析中,每条评论文本对应一个情感类别标签(如「正面」「负面」或「中性」),模型学习根据文本预测该标签。

  • 目标函数

是模型训练过程中优化的目标,通常由损失函数构成,用于衡量模型的性能。

举例:在线性回归中,目标函数是最小化均方误差(MSE)。

  • 损失函数 用于量化模型预测值与真实值之间的差异,用来衡量单个样本中计算值与标签值的差异。

举例:在分类问题中,常用的损失函数是交叉熵损失。

  • 特征[*]

通过机器学习算法从数据中学习到的数学表示,用于模型的输入。

通俗来讲:数据经过神经网络运算之后所输出的结果,就是特征。

  • 模型

通过机器学习算法从数据中学习到的数学表示,用于对新数据进行预测。

  • 训练数据[*]

用于训练机器学习模型的数据集,通常包含输入特征和对应的标签。[训练集:验证集:测试集][7:1:2]

  • 测试数据

用于评估模型在未知数据上表现的数据集。

  • 正则化

用于防止模型过度拟合的技术和手段

  • 学习率[*]

学习率是一个超参数,学习率是训练过程中控制参数更新的重要因素。

过大的学习率可能导致模型无法收敛,而过小的学习率则会导致训练过程缓慢。(学习率决定学习速度)

  • Epoch

即轮次,模型训练过程中对整个训练数据进行一次完整的遍历。

  • 超参数 超参数是在训练之前设置的参数,用于控制学习过程和模型结构。

举例:学习率、批量大小、神经网络的层数和每层的神经元数量等都是常见的超参数。

  • 数据分布

训练的过程就是找到一个函数,能够匹配数据的分布的过程。

非线性激活函数

  • 激活函数 人工神经网络中的一个关键组件,负责将神经元的输入信号转换为输出信号,从而引入非线性特性。

说白了,就是给神经网络提供非线性能力的函数,把直线变成一条曲线。

激活函数对模型至关重要:引入非线性、增强表达能力、控制输出范围、促进梯度传播、模拟生物神经元的激活机制。

  • 常见的激活函数
    • Sigmoid函数:将输入映射到 (0,1) 之间,常用于二分类问题,容易导致梯度消失问题。
  • Tanh函数:将输入映射到 (-1,1) 之间,解决了 Sigmoid 的零均值问题,但仍存在梯度消失问题。
  • ReLU函数:将输入为正时输出输入值,输入为负时输出 0,计算简单且能够有效缓解梯度消失问题,但可能导致"神经元死亡"问题。
  • Softmax函数:将输入映射为概率分布,常用于多分类问题的输出层。

模型训练过程

  • Step 1:定义网络结构 确定网络的层数、每层神经元数量、激活函数等。

  • Step 2:初始化模型参数 随机初始化权重 ( W ) 和偏置 ( b )。

  • Step 3:循环训练(直到损失值达标)

子步骤 名称 说明
3.1 执行前向传播 输入数据经过网络逐层计算,得到预测输出
3.2 计算损失函数 将预测输出与真实标签对比,计算损失值
3.3 执行反向传播 根据损失值计算各层参数的梯度
3.4 更新权值 使用梯度下降法更新权重和偏置
  • Step 4:模型测试与应用 损失值达标后,进行模型测试,最后投入应用。

反向传播机制

用一个实际例子来理解机器学习和反向传播:

猜数字的游戏。现在我心中确定了一个1到100的数,请你猜猜它是什么?

学习率的影响

  • 梯度下降法 步长太小,迭代次数多,收敛慢。 步长太大,引起震荡,可能无法收敛。

前向计算、反向传播

前向计算(模型推理)

将数据输入到模型,得到输出的过程。

ini 复制代码
x * w + b = h

反向传播(模型训练)

根据模型输出的结果,结合数据对应的标签,得到损失,再通过损失求解正确的参数(w, b)。

ini 复制代码
loss = mean((h - y) ^ 2)

下面是一个最小可运行的"手写前向 + 反向 + 参数更新"示例(两层网络,ReLU激活):

python 复制代码
import numpy as np

batch_size, dim_in, hidden_layer, dim_out = 64, 1000, 100, 10
x = np.random.randn(batch_size, dim_in)
y = np.random.randn(batch_size, dim_out)
w1 = np.random.randn(dim_in, hidden_layer)
w2 = np.random.randn(hidden_layer, dim_out)

learning_rate = 1e-6
for t in range(500):
    # 前向计算
    h = x.dot(w1)
    h_relu = np.maximum(h, 0)
    y_pred = h_relu.dot(w2)

    # 计算损失
    loss = np.square(y_pred - y).sum()
    print(t, loss)

    # 反向传播(手推梯度)
    grad_y_pred = 2.0 * (y_pred - y)
    grad_w2 = h_relu.T.dot(grad_y_pred)
    grad_h_relu = grad_y_pred.dot(w2.T)
    grad_h = grad_h_relu.copy()
    grad_h[h < 0] = 0
    grad_w1 = x.T.dot(grad_h)

    # 参数更新
    w1 -= learning_rate * grad_w1
    w2 -= learning_rate * grad_w2

如果使用 PyTorch,可以把梯度计算交给 autograd 自动完成:

python 复制代码
import torch

batch_size, dim_in, hidden_layer, dim_out = 64, 1000, 100, 10
x = torch.randn(batch_size, dim_in)
y = torch.randn(batch_size, dim_out)
w1 = torch.randn(dim_in, hidden_layer, requires_grad=True)
w2 = torch.randn(hidden_layer, dim_out, requires_grad=True)

learning_rate = 1e-6
for t in range(500):
    y_pred = x.mm(w1).clamp(min=0).mm(w2)  # 前向
    loss = (y_pred - y).pow(2).sum()
    print(t, loss.item())

    loss.backward()  # 反向:自动求导

    with torch.no_grad():
        w1 -= learning_rate * w1.grad
        w2 -= learning_rate * w2.grad
        w1.grad.zero_()
        w2.grad.zero_()

最终目标

模型输出的 h 和 y 非常接近,loss 很小,我们需要求解 loss 最小时对应的参数 w, b。

loss 不能为 0,只能无限逼近于 0。

梯度下降算法(SGD)

Adam 优化器可以自行动态调整学习率。

在工程实践中,常见写法是使用优化器统一管理参数更新:

python 复制代码
import torch

model = torch.nn.Sequential(
    torch.nn.Linear(1000, 100),
    torch.nn.ReLU(),
    torch.nn.Linear(100, 10),
)
loss_fn = torch.nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)

x = torch.randn(64, 1000)
y = torch.randn(64, 10)

for t in range(500):
    y_pred = model(x)
    loss = loss_fn(y_pred, y)
    print(t, loss.item())

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

多层模型的前向计算其实就是复合函数嵌套:

css 复制代码
h * w1 + b1 = (x * w + b) * w1 + b1 = h1

反向求导的时候就是复合函数的求导,遵循链式法则。

自动求导

自动求导不仅能处理固定结构的网络,也能处理"每次前向结构都可能变化"的动态计算图。

常见的计算机程序求导方法可以归纳为四种:数值微分、符号求导、前向模式自动求导(Forward Mode AD)、反向模式自动求导(Reverse Mode AD)。

深度学习训练中最常用的是反向模式自动求导,也就是我们常说的反向传播。

自动求导的进阶:动态图与参数共享

下面通过一个例子说明:输入层和输出层固定,但中间层会随机重复 0~3 次;同一个中间层参数会被重复使用(参数共享)。

python 复制代码
import random
import torch


class DynamicNet(torch.nn.Module):
    def __init__(self, n_in, n_hidden, n_out):
        super().__init__()
        self.input_linear = torch.nn.Linear(n_in, n_hidden)
        self.middle_linear = torch.nn.Linear(n_hidden, n_hidden)  # 参数共享层
        self.output_linear = torch.nn.Linear(n_hidden, n_out)

    def forward(self, x):
        # 固定的输入变换
        h_relu = self.input_linear(x).clamp(min=0)
        y_pred = self.output_linear(h_relu)

        # 每次前向随机决定中间层重复次数(动态图)
        for _ in range(random.randint(0, 3)):
            h_relu = self.middle_linear(h_relu).clamp(min=0)
            y_pred = self.output_linear(h_relu)
        return y_pred


batch_size, dim_in, hidden_layer, dim_out = 64, 1000, 83, 10
x = torch.randn(batch_size, dim_in)
y = torch.randn(batch_size, dim_out)

model = DynamicNet(dim_in, hidden_layer, dim_out)
criterion = torch.nn.MSELoss(reduction="sum")
optimizer = torch.optim.SGD(model.parameters(), lr=1e-4, momentum=0.9)

for t in range(500):
    y_pred = model(x)
    loss = criterion(y_pred, y)
    print(t, loss.item())

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

这个例子说明:在 PyTorch 中,计算图是在前向过程中动态构建的,因此可以直接使用 Python 的循环和条件语句来控制网络结构。

讨论

为什么模型的效果一直停滞不前?

  • 优化器选择不合适:参数更新方向或步长控制不佳,导致收敛慢或训练不稳定。
  • 损失函数选择不合适:与任务目标不匹配,模型即使在优化,也难以朝正确方向改进。

神经元越多,网络深度越大,效果越好吗?

不一定。更大的模型通常拥有更强表达能力,但效果取决于数据规模与质量、正则化策略、优化方法和计算资源。

当数据不足或训练策略不当时,盲目增大网络反而更容易过拟合、训练不稳定,甚至导致效果下降。

文中部分图片来自于网络。

相关推荐
LLM精进之路1 小时前
IEEE 26 | 参数量不是关键:4B模型VeriGround在匿名化电路生成任务上性能超越GPT-5.4
人工智能·gpt·深度学习·机器学习
源码之家1 小时前
计算机毕业设计:Python医疗数据可视化系统 Flask框架 数据分析 可视化 医疗大数据 用户画像(建议收藏)✅
python·深度学习·信息可视化·数据分析·django·flask·课程设计
盼小辉丶1 小时前
PyTorch强化学习实战(8)——Q学习详解与实现
pytorch·深度学习·强化学习
云上码厂1 小时前
卫星和航空影像的深度学习技术
人工智能·深度学习
渡我白衣1 小时前
定时器与时间轮思想
linux·开发语言·前端·c++·人工智能·深度学习·神经网络
web守墓人2 小时前
【神经网络】js版本的Pytorch,estorch重磅发布
前端·javascript·人工智能·pytorch·深度学习·神经网络
人工智能培训2 小时前
知识图谱与检索增强的实战结合
人工智能·深度学习·神经网络·机器学习·生成对抗网络
星座5282 小时前
驾驭AI 2.0时代:Transformer、扩散模型与物理信息神经网络核心技术解析
人工智能·深度学习·神经网络·transformer·强化学习·目标检测算法
栈溢出了2 小时前
GIN学习笔记
人工智能·神经网络·算法·机器学习·gin