2、深度学习基础回顾(上):神经网络核心概念、前向传播与反向传播、损失函数与优化器(SGD、Adam)

说实话,很多同学一上来就想直接调 YOLO 的代码,结果连 loss 为什么下降、梯度怎么更新都搞不清楚。我个人习惯是,在碰任何检测模型之前,先把这几块地基夯实了。这一章我们只聊最核心的东西:神经网络怎么算、怎么学、怎么调。

深度学习核心知识体系 神经网络 前向传播 反向传播 损失函数 线性变换 + 激活函数 链式法则求梯度 MSE / CrossEntropy 优化器 SGD Adam 前向传播算输出 反向传播算梯度

2.1 神经网络核心概念:从感知机到多层网络

神经网络说白了就是一个函数逼近器。你给它一堆输入,它通过层层计算给你一个输出。我刚开始学的时候,总觉得这东西很玄乎,后来发现核心就三个东西:权重、偏置、激活函数。

2.1.1 神经元的基本结构

一个神经元做的事其实很简单:

  • 加权求和:把每个输入乘上对应的权重,再加一个偏置
  • 非线性变换:把求和结果扔进激活函数

数学上就一行:

z = w1*x1 + w2*x2 + ... + wn*xn + b
a = activation(z)

嗯,这里要注意,如果没有激活函数,多层网络就退化成了线性模型,那跟单层没区别。我在项目里见过有人堆了十几层全连接,结果效果还不如线性回归——就是因为忘了加激活函数。

2.1.2 常见的激活函数

激活函数公式特点适用场景
Sigmoidσ(x) = 1/(1+e⁻ˣ)输出范围(0,1),容易梯度饱和二分类输出层
Tanhtanh(x) = (eˣ-e⁻ˣ)/(eˣ+e⁻ˣ)输出范围(-1,1),零中心RNN 常用
ReLUReLU(x) = max(0,x)计算快,缓解梯度消失CNN 默认选择
Leaky ReLUmax(αx, x), α=0.01解决 ReLU 死亡问题深层网络
我的经验:YOLO 系列里大量使用 ReLU 和 Leaky ReLU。我个人习惯在隐藏层无脑用 ReLU,除非遇到神经元大量死亡(梯度全零)才换 Leaky ReLU。

2.1.3 网络结构:层与连接方式

一个典型的全连接网络长这样:

  • 输入层:接收原始数据,节点数等于特征维度
  • 隐藏层:一层或多层,每层有若干神经元
  • 输出层:输出预测结果,节点数取决于任务

举个例子,一个手写数字识别网络:输入 784 个像素值 → 隐藏层 128 个神经元 → 输出层 10 个类别概率。

2.2 前向传播:数据是怎么流过网络的

前向传播就是数据从输入层一路算到输出层的过程。每一层都做两件事:线性变换 + 激活。

假设我们有一个 3 层网络:

# 伪代码:前向传播
h1 = activation(W1 @ x + b1)   # 输入层 → 隐藏层1
h2 = activation(W2 @ h1 + b2)  # 隐藏层1 → 隐藏层2
y_pred = W3 @ h2 + b3          # 隐藏层2 → 输出层(无激活,回归任务)

你想想看,这个过程其实就是在做特征变换。原始像素经过第一层变成边缘特征,再经过第二层变成纹理特征,最后输出层给出预测。我在做 YOLO 训练时,经常把中间层的特征图可视化出来,看看网络到底学到了什么——这招对调试特别有用。

关键点:前向传播的结果就是模型的预测值。这个预测值会和真实标签一起送入损失函数,计算误差。

2.3 反向传播:神经网络的学习引擎

反向传播是神经网络能学习的根本原因。它的核心思想就是链式法则——从输出层开始,逐层往回计算每个参数对损失的梯度。

2.3.1 链式法则直观理解

假设损失 L 是预测值 ŷ 的函数,ŷ 又是权重 w 的函数:

L = f(ŷ)
ŷ = g(w)
∂L/∂w = (∂L/∂ŷ) * (∂ŷ/∂w)

说白了,就是「误差从输出层一层层传回来,告诉每个参数:你该往哪个方向调,调多少」。

2.3.2 反向传播的四个步骤

  1. 前向传播:计算每层输出,缓存中间结果
  2. 计算损失:比较预测值和真实值
  3. 反向传播梯度:从输出层开始,逐层计算 ∂L/∂w 和 ∂L/∂b
  4. 更新参数:用梯度下降法更新权重
我曾经踩过的坑:有一次训练 loss 死活不降,查了两天才发现是反向传播时梯度传错了层——我把某一层的梯度传给了上一层的偏置。记住:每个参数的梯度只跟它自己的输出有关,别搞混了。

2.4 损失函数:衡量模型的好坏

损失函数就是一把尺子,量一量模型预测得怎么样。不同的任务用不同的损失函数。

2.4.1 回归任务的损失函数

损失函数公式特点
均方误差 (MSE)L = (y - ŷ)²对大误差惩罚大,对异常值敏感
平均误差 (MAE)L = |y - ŷ|对异常值更鲁棒
Huber LossMSE 当 |y-ŷ|<δ, 否则 MAE结合两者优点

2.4.2 分类任务的损失函数

分类任务最常用的是交叉熵损失(Cross-Entropy Loss)。对于二分类:

L = -[y * log(ŷ) + (1-y) * log(1-ŷ)]

对于多分类(比如 YOLO 的类别预测):

L = -Σ y_i * log(ŷ_i)
我的建议:YOLO 的损失函数其实是一个组合损失——包含定位损失(CIoU)、置信度损失(BCE)、分类损失(BCE)。别想着自己从头写,直接用框架封装好的就行。

2.5 优化器:梯度下降的进化史

有了梯度,怎么更新参数?这就是优化器干的事。最朴素的想法就是:沿着梯度的反方向走一步。

2.5.1 随机梯度下降 (SGD)

SGD 的更新公式很简单:

w = w - lr * ∇w

其中 lr 是学习率,∇w 是梯度。SGD 的问题也很明显:

  • 学习率固定,不好调
  • 容易陷入局部最优或鞍点
  • 收敛速度慢

我记得刚开始做项目时,调 SGD 的学习率调到头秃。设大了 loss 爆炸,设小了半天不动。

2.5.2 带动量的 SGD (SGD with Momentum)

动量法引入了「惯性」概念:

v = β * v + (1-β) * ∇w
w = w - lr * v

这样做的好处是:梯度方向一致时加速,方向变化时减速。说白了就是让更新更平滑,不容易卡在局部极小点。

2.5.3 Adam 优化器

Adam 是目前最常用的优化器,它结合了动量和自适应学习率:

  • 动量:记录梯度的一阶矩(均值)
  • 自适应学习率:记录梯度的二阶矩(方差)
  • 偏差校正:解决初始阶段估计不准的问题

Adam 的默认参数(lr=0.001, β₁=0.9, β₂=0.999)在大多数任务上表现都不错。我个人习惯:先用 Adam 快速找到一个好的区域,再换 SGD + Momentum 精调。

优化器优点缺点YOLO 常用吗?
SGD简单,泛化性好调参困难,收敛慢YOLOv5 默认
SGD+Momentum收敛更快,更稳定仍需要调学习率YOLOv8 可选
Adam自适应,几乎不用调参有时泛化不如 SGDYOLOv9 可选
AdamW改进了权重衰减比 Adam 稍复杂越来越多项目在用
一句话总结:前向传播算输出,损失函数量误差,反向传播算梯度,优化器更新参数。这四个环节构成了深度学习训练的核心循环。

2.6 本章小结

这一章我们聊了神经网络最核心的几个概念:

  • 神经元的结构:加权求和 + 激活函数
  • 前向传播:数据从输入到输出的计算过程
  • 反向传播:用链式法则计算梯度
  • 损失函数:衡量预测和真实的差距
  • 优化器:SGD、Momentum、Adam 的进化路线