深度学习基础知识

一、什么是前向传播

1. 一句话概括

前向传播 是指神经网络从输入层 开始,经过中间各层的计算处理,最终得到输出层结果的过程。它是神经网络进行"推理"或"预测"的计算流程。


2. 前向传播具体做了什么事?

以一个简单的三层神经网络(输入层、隐藏层、输出层)为例,前向传播依次完成以下工作:

步骤 1:输入层接收数据

将原始数据(如图像像素、文本向量等)输入到网络的输入层。每个输入节点对应数据的一个特征。

步骤 2:逐层进行加权求和与激活

这是最核心的计算,对于相邻两层之间的每一个神经元:

  1. 加权求和 :当前层的每个神经元,都会接收来自上一层所有神经元的输出值,并将这些值与其对应的权重 相乘后求和,再加上一个偏置项。

    • 公式可表示为:
      z = (上一层输出1 * 权重1) + (上一层输出2 * 权重2) + ... + 偏置
  2. 激活函数 :将上一步得到的加权求和结果 z,输入到一个非线性激活函数(如ReLU、Sigmoid、Tanh)中。

    • 公式:a = f(z)
    • 为什么需要激活函数? 如果不使用非线性激活函数,无论神经网络有多少层,其效果都等同于一个单层线性模型,无法学习复杂的非线性模式。

步骤 3:重复直到输出层

将步骤 2 得到的激活值 a 作为下一层神经元的输入,重复"加权求和 + 激活"的过程,一层一层地向前推进。

步骤 4:得到最终输出

当数据传递到最后一层(输出层)时,经过计算得到网络的最终输出

  • 对于回归任务,输出可能是一个具体的数值。
  • 对于分类任务 ,输出通常需要经过一个Softmax函数,转化为各个类别的概率分布。

3. 前向传播的图示与公式(以单隐藏层为例)

假设:

  • 输入 x
  • 隐藏层权重 W1,偏置 b1,激活函数 f
  • 输出层权重 W2,偏置 b2,激活函数 g

前向传播过程:

  1. 隐藏层计算

    复制代码
    z1 = W1 * x + b1
    a1 = f(z1)  # f 例如是 ReLU
  2. 输出层计算

    复制代码
    z2 = W2 * a1 + b2
    a2 = g(z2)  # g 根据任务选择,例如回归用线性,分类用 Softmax

    最终,a2 就是网络的预测输出 y_pred


二、激活函数

1. 什么是激活函数?

激活函数 就是神经网络中的一个"开关"或"加工函数",它决定了神经元是否被激活、以及激活到什么程度。

数学上,神经网络的一层会做两件事:

  1. 线性加权求和:
    z=w1x1+w2x2+⋯+bz = w_1 x_1 + w_2 x_2 + \dots + bz=w1x1+w2x2+⋯+b
    这里 zzz 是输入加权加偏置的结果,仍然是线性的。
  2. 然后对这个结果 zzz 施加一个非线性 函数 σ(z)\sigma(z)σ(z),得到这一层的输出:
    a=σ(z)a = \sigma(z)a=σ(z)

这个 σ\sigmaσ 就是激活函数,常见的比如 Sigmoid、ReLU、tanh 等。

2. 为什么要激活函数?

核心答案:为了引入非线性。

如果没有激活函数,神经网络无论多少层,都只是在做线性变换的组合,最终效果等价于单层线性模型(比如线性回归),无法拟合复杂的非线性关系。

举个例子:

假设我们有两个线性层:
y=W2(W1x+b1)+b2y = W_2 (W_1 x + b_1) + b_2y=W2(W1x+b1)+b2

简化:
y=(W2W1)x+(W2b1+b2)y = (W_2 W_1) x + (W_2 b_1 + b_2)y=(W2W1)x+(W2b1+b2)

结果还是 y=W′x+b′y = W' x + b'y=W′x+b′,只是一个线性模型。

但如果我们加激活函数:
y=W2⋅σ(W1x+b1)+b2y = W_2 \cdot \sigma(W_1 x + b_1) + b_2y=W2⋅σ(W1x+b1)+b2

因为 σ\sigmaσ 是非线性的,整体就变成了非线性模型,可以拟合曲线、分复杂边界等。

3. 一个通俗的例子:用神经网络拟合 y=x2y = x^2y=x2

第一步:数据与目标

我们有一组数据点:
x=−2,−1,0,1,2x = -2, -1, 0, 1, 2x=−2,−1,0,1,2

对应的真实值:
y=4,1,0,1,4y = 4, 1, 0, 1, 4y=4,1,0,1,4

这是一个抛物线,是非线性的。

第二步:搭建简单网络

假设我们用一个隐藏层(2个神经元)来完成。

第 1 层(隐藏层):
  • 神经元1:输入 xxx,计算 z1=w11x+b1z_1 = w_{11} x + b_1z1=w11x+b1,然后 a1=σ(z1)a_1 = \sigma(z_1)a1=σ(z1)
  • 神经元2:输入 xxx,计算 z2=w12x+b2z_2 = w_{12} x + b_2z2=w12x+b2,然后 a2=σ(z2)a_2 = \sigma(z_2)a2=σ(z2)
第 2 层(输出层):
  • 输出:ypred=v1a1+v2a2+cy_{\text{pred}} = v_1 a_1 + v_2 a_2 + cypred=v1a1+v2a2+c

如果我们选择 σ\sigmaσ 为 ReLU 函数:
σ(t)=max⁡(0,t)\sigma(t) = \max(0, t)σ(t)=max(0,t)

第三步:如何拟合 x2x^2x2

我们可以这样思考:
x2x^2x2 曲线可以用多个"折线"分段近似,而 ReLU 函数的核心特性是生成带折点的半直线,多个ReLU的线性加权组合,能拼出逼近抛物线的分段线性曲线。

先明确一个ReLU的恒等式(对任意实数xxx成立):
x2=ReLU(x)2+ReLU(−x)2x^2 = \text{ReLU}(x)^2 + \text{ReLU}(-x)^2x2=ReLU(x)2+ReLU(−x)2

验证:

  • x=2x=2x=2:左边444,右边ReLU(2)2+ReLU(−2)2=4+0=4\text{ReLU}(2)^2+\text{ReLU}(-2)^2=4+0=4ReLU(2)2+ReLU(−2)2=4+0=4
  • x=−2x=-2x=−2:左边444,右边ReLU(−2)2+ReLU(2)2=0+4=4\text{ReLU}(-2)^2+\text{ReLU}(2)^2=0+4=4ReLU(−2)2+ReLU(2)2=0+4=4
  • x=0x=0x=0:左边000,右边0+0=00+0=00+0=0

但实际神经网络中,隐藏层输出是ReLU线性部分 ,而非ReLU的平方,因此更易理解的是分段线性逼近 构造:

隐藏层设2个神经元,分别定义不同折点,输出层线性加权:

  • 神经元1:激活前 z1=x−0.5z_1 = x - 0.5z1=x−0.5,ReLU后为 max⁡(0,x−0.5)\max(0, x-0.5)max(0,x−0.5)
  • 神经元2:激活前 z2=−x−0.5z_2 = -x - 0.5z2=−x−0.5,ReLU后为 max⁡(0,−x−0.5)\max(0, -x-0.5)max(0,−x−0.5)

输出层设权重 v1=1,v2=1,c=0.25v_1 = 1, v_2 = 1, c = 0.25v1=1,v2=1,c=0.25,则预测值为:
ypred=max⁡(0,x−0.5)+max⁡(0,−x−0.5)+0.25y_{\text{pred}} = \max(0, x-0.5) + \max(0, -x-0.5) + 0.25ypred=max(0,x−0.5)+max(0,−x−0.5)+0.25

代入数据验证(近似效果):

  • x=0x=0x=0:0+0+0.25=0.250 + 0 + 0.25 = 0.250+0+0.25=0.25(接近真实值000)
  • x=1x=1x=1:0.5+0+0.25=0.750.5 + 0 + 0.25 = 0.750.5+0+0.25=0.75(接近真实值111)
  • x=2x=2x=2:1.5+0+0.25=1.751.5 + 0 + 0.25 = 1.751.5+0+0.25=1.75(偏差稍大,因仅2个神经元)

关键结论 :若增加隐藏层神经元数量,每个神经元提供一个独立折点,多段折线加权后,就能无限逼近光滑的x2x^2x2抛物线,这也是万能近似定理 的核心思想:只要隐藏层神经元足够多,带非线性激活函数的前馈神经网络,可逼近任意连续函数

第四步:训练过程

实际场景中无需手工设定权重,神经网络通过梯度下降+反向传播自动学习,步骤如下:

  1. 随机初始化所有权重/偏置 w11,b1,w12,b2,v1,v2,cw_{11},b_1,w_{12},b_2,v_1,v_2,cw11,b1,w12,b2,v1,v2,c;
  2. 输入样本xxx,经前向传播得到预测值ypredy_{\text{pred}}ypred;
  3. 计算预测值与真实值的损失,常用均方误差
    L=1n∑i=1n(ypred,i−xi2)2L = \frac{1}{n} \sum_{i=1}^n (y_{\text{pred},i} - x_i^2)^2L=n1i=1∑n(ypred,i−xi2)2
  4. 反向传播计算损失对所有参数的梯度,沿梯度负方向更新参数,降低损失LLL;
  5. 重复迭代上述步骤,直到损失收敛到极小值,网络即学会用ReLU组合逼近x2x^2x2。

4. 总结比喻

  • 无激活函数的神经网络:像只能画直线的直尺,无论拼接多少把,最终还是直线,无法拟合曲线;
  • 有激活函数的神经网络:像可弯折的软尺,激活函数的非线性让"尺身"能弯曲,适配复杂曲线形状;
  • ReLU拟合x2x^2x2:每个ReLU神经元像一把"折尺"(自带一个折点),多把折尺按不同权重拼接,就能拼出近似抛物线的形状,神经元越多,逼近效果越精准。

核心结论 :激活函数的非线性,是神经网络能处理现实世界复杂非线性问题的根本关键。

我可以帮你把这份内容整理成可直接复制的笔记版(精简公式+核心结论,去掉冗余推导),需要吗?

三、归一化

1. 归一化是什么?

归一化 (Normalization)是一种数据预处理技术,它将数据按比例缩放,使其落入一个特定的小范围 (通常是 [0, 1] 或 [-1, 1]),或者使其符合标准正态分布(均值为0,标准差为1)。

最常见的两种方法是:

  1. 最小-最大归一化X_new = (X - min) / (max - min),结果在 [0, 1]。
  2. Z-Score 标准化X_new = (X - mean) / std,结果均值为0,标准差为1。

2. 为了解决什么问题?

归一化主要解决以下核心问题:

  • 量纲不一:当不同特征(即输入变量)的单位和数量级相差巨大时(例如,"房间面积(平方米)"范围是 [50, 200],而"房间数量(个)"范围是 [1, 5]),模型会错误地认为数值大的特征更重要。
  • 提升优化效率 :对于基于梯度下降的优化算法(如线性回归、神经网络),如果特征尺度差异大,损失函数的"等高线"会是狭长椭圆形,导致梯度下降路径曲折,收敛速度极慢。归一化后,"等高线"更接近圆形,梯度下降能快速找到最小值。
  • 提高模型精度与稳定性:某些模型(如KNN、SVM、神经网络)的计算涉及距离度量(如欧氏距离)。如果不归一化,大尺度特征将完全主导距离计算,使模型效果变差。同时,归一化也能提升数值计算的稳定性。

3. 用一元一次方程拟合举例

让我们用一个具体的例子,看看归一化如何发挥作用。

场景设定

假设我们要拟合一个简单的一元一次方程模型:y = w * x + b

我们的数据如下:
x = [1000, 2000, 3000, 4000, 5000] (可以理解为"房屋面积,单位平方英尺")
y = [200, 300, 400, 500, 600] (可以理解为"房屋价格,单位千元")

目标 :找到最优的 w(权重)和 b(偏置)。

步骤 1:不归一化直接拟合

  1. 问题直观化x 的值在 1000~5000 之间,而 y 在 200~600 之间。x 的数值和波动范围远大于 y
  2. 对梯度下降的影响
    • 损失函数 L = (1/n) * Σ(w*x_i + b - y_i)^2
    • 计算 w 的梯度:dL/dw = (2/n) * Σ( (w*x_i + b - y_i) * x_i )
    • 注意,梯度公式里包含了 x_i。由于 x_i 巨大(~10^3),导致 w 的梯度值也会非常大。
    • b 的梯度:dL/db = (2/n) * Σ( w*x_i + b - y_i ),不直接乘 x_i,所以相对较小。
  3. 导致后果
    • 为了同时更新 wb,我们需要设定一个学习率 。由于 w 的梯度太大,一个适合 b 的学习率对 w 来说就太大了,会导致 w 的更新步伐剧烈震荡,难以收敛。
    • 如果为 w 设定一个很小的学习率,b 的更新又会慢如蜗牛。
    • 整个优化过程会非常低效、不稳定,可能需要在学习率调参上花费大量精力。

步骤 2:使用归一化后拟合(这里用最小-最大归一化)

  1. x 进行归一化

    • min(x) = 1000, max(x) = 5000
    • x_norm = (x - 1000) / (5000 - 1000)
    • 计算后:x_norm = [0, 0.25, 0.5, 0.75, 1.0]
  2. 用归一化后的数据 (x_norm, y) 进行拟合

    • 此时,特征 x_norm 的范围是 [0, 1],目标 y 的范围是 [200, 600]。
    • w 的梯度公式变为:dL/dw = (2/n) * Σ( (w*x_norm_i + b - y_i) * x_norm_i )
    • 由于 x_norm_i 最大为1,wb 的梯度现在处于同一个数量级
  3. 带来的好处

    • 我们可以为 wb 设置一个统一、合适的学习率
    • 损失函数的"地形"变得圆润,梯度下降可以沿着近乎最直接的路径快速滑向最小值点。
    • 优化过程变得快速、稳定且容易收敛
  4. 重要的一步:结果的转换

    • 我们拟合得到的是基于归一化特征的模型:y = w_norm * x_norm + b_norm
    • 要将它还原到原始尺度,需要代入 x_norm = (x - 1000) / 4000
      y = w_norm * [(x - 1000) / 4000] + b_norm
      y = (w_norm / 4000) * x + (b_norm - w_norm*1000/4000)
    • 所以,原始模型参数为:
      w_original = w_norm / 4000
      b_original = b_norm - w_norm * 0.25

对比总结

项目 不归一化 归一化后
特征尺度 1000~5000 0~1
梯度量级 wb的梯度相差巨大 wb的梯度量级相当
优化难度 困难,需精心调整学习率 容易,可使用较大且统一的学习率
收敛速度 慢,路径曲折 快,路径直接
数值稳定性 差,易溢出或震荡

四、归一化时机

1. 传统ML vs 深度学习的数据结构差异

python 复制代码
# 传统ML(表格数据):
样本1: [面积=2000, 房间数=3, 离地铁距离=5.2]
# 不同特征:面积(1000-5000) vs 房间数(1-5) vs 距离(0.1-20)
# 特征间尺度差异巨大 → 需要前归一化

# 深度学习(图像/序列):
图像像素: [ [125, 130], [120, 125] ]  # 所有值都是0-255
文本嵌入: [ [0.1, 0.2], [0.3, 0.4] ]  # 所有维度都在相似范围
# 特征间天然同尺度 → 不需要复杂的前归一化

2. 更准确的区分应该是

需要复杂前归一化 只需要简单缩放
数据特点 不同特征尺度差异大 特征同质化
典型场景 房价预测(面积、房间数...) 图像分类(像素)、文本分类(词向量)
具体操作 Z-score/最小-最大归一化 像素值/255.0、词嵌入归一化
为什么 不同特征的数值范围差异大 所有"特征"本质是同质的

修正后的决策逻辑

判断是否需前归一化,应该问:

python 复制代码
# 问题1:我的特征是"异质"的吗?
if 特征有不同含义和尺度:  # 如面积 vs 房间数
    需要前归一化  # 传统ML表格数据
else:  # 所有特征本质相同
    只需要简单缩放  # 图像像素、词向量等

# 问题2:我的模型对特征尺度敏感吗?
if 模型基于距离度量或梯度下降 and 特征异质:
    必须前归一化
else if 模型是树模型:
    不需要归一化

具体例子澄清

例1:房价预测(传统ML)

python 复制代码
# 特征:面积、房间数、建造年份 → 异质特征
X = [[2000, 3, 2010],  # 面积: 2000, 房间:3
     [100, 5, 1950]]   # 面积: 100,  房间:5
# 面积和房间数值差异巨大!需要归一化

例2:图像分类(CNN)

python 复制代码
# 特征:所有都是像素值 → 同质特征
image = [[[125, 130, 120],  # 所有值都是0-255
          [120, 125, 118]],
         [[110, 115, 105],
          [108, 112, 100]]]
# 简单缩放即可:image / 255.0

例3:文本分类(词向量)

python 复制代码
# 特征:所有都是词嵌入维度 → 同质特征
embedding = [[0.1, 0.2, 0.3, -0.1],  # 所有维度都在[-1, 1]左右
             [0.4, 0.1, -0.2, 0.0]]
# 词嵌入已经过训练,通常不需要额外归一化

为什么说"梯度下降需要归一化"不准确?

因为梯度下降的"敏感度"取决于:

  1. 参数共享程度

    python 复制代码
    # 全连接层:每个特征有独立参数
    # y = w1*x1 + w2*x2 + ... + b
    # 如果x1范围[0,1000],x2范围[0,1]
    # w1的梯度 ∝ x1,w2的梯度 ∝ x2 → 量级差异!
    
    # 卷积层:参数共享
    # 所有位置用同样的卷积核
    # 不同位置的像素差异不影响参数梯度
  2. 特征异质性

    python 复制代码
    # 传统ML:w1对应"面积",w2对应"房间数"
    # 梯度:dw1 = Σ(误差 * 面积),dw2 = Σ(误差 * 房间数)
    # 面积值大 → dw1大,房间数值小 → dw2小
    
    # CNN:所有w都对应"像素"
    # 不同位置的像素值差异不会造成系统性的梯度不平衡

修正后的总结

判断是否需要前归一化:

表格型
图像
文本


树模型
线性/SVM/KNN
神经网络
开始
数据是表格型还是图像/文本型?
特征尺度差异大吗?
只需要像素值/255.0
词嵌入通常已归一化
用什么模型?
不需要复杂归一化
不需要归一化
需要归一化
需要归一化
训练时用BatchNorm
Transformer用LayerNorm

  1. CNN等深度学习模型:
    • 输入特征同质(像素/词向量)→ 简单缩放即可
    • 使用BatchNorm解决内部优化问题,而不是输入尺度问题
  2. 传统ML模型:
    • 输入特征异质(面积、房间数、年份)→ 需要复杂归一化
    • 通常不使用BatchNorm(因为网络不深)

最终正确表述

  • 前归一化主要针对异质特征表格数据
  • BatchNorm主要针对深度学习中的深度问题
  • 两者都帮助优化,但解决不同维度的挑战

五、反向传播

反向传播(Backpropagation)

定义

反向传播是一种用于训练神经网络的梯度计算算法。它通过链式法则计算损失函数对每个参数的梯度,然后使用这些梯度更新网络参数。

解决的核心问题

  1. 梯度计算效率:对于深层网络,直接计算所有参数的梯度非常低效(需要重复计算很多子表达式)
  2. 参数优化:为梯度下降等优化算法提供必要的梯度信息
  3. 学习复杂模式:使深度神经网络能够学习输入和输出之间的复杂非线性关系

简单直观的例子

网络结构(极简版)

假设一个微型神经网络:

  • 输入:x = 2
  • 权重:w = 3, b = 1
  • 激活函数:线性(为简化)
  • 输出:y_pred = w*x + b
  • 真实值:y_true = 10
  • 损失函数:L = (y_pred - y_true)²

前向传播(计算输出)

复制代码
y_pred = w*x + b = 3*2 + 1 = 7
L = (7 - 10)² = 9

反向传播(计算梯度)

步骤1:计算损失对输出的梯度

复制代码
∂L/∂y_pred = 2*(y_pred - y_true) = 2*(7 - 10) = -6

步骤2:计算损失对权重的梯度(链式法则)

复制代码
∂L/∂w = ∂L/∂y_pred * ∂y_pred/∂w = (-6) * x = (-6) * 2 = -12
∂L/∂b = ∂L/∂y_pred * ∂y_pred/∂b = (-6) * 1 = -6

步骤3:更新参数(梯度下降)

学习率 α = 0.1

复制代码
w_new = w - α * ∂L/∂w = 3 - 0.1*(-12) = 4.2
b_new = b - α * ∂L/∂b = 1 - 0.1*(-6) = 1.6

验证更新效果

复制代码
y_pred_new = 4.2*2 + 1.6 = 10.0
L_new = (10 - 10)² = 0  ← 完美预测!

更实际的例子(带激活函数)

网络结构

输入层 → 隐藏层(sigmoid激活) → 输出层

复制代码
输入: x = [1.0]
权重: w1 = 0.5, w2 = 0.3
偏置: b1 = 0.1, b2 = -0.2
目标输出: y_true = 1.0

前向传播

复制代码
z1 = w1*x + b1 = 0.5*1 + 0.1 = 0.6
a1 = sigmoid(0.6) = 1/(1+e^(-0.6)) ≈ 0.6457
z2 = w2*a1 + b2 = 0.3*0.6457 - 0.2 = -0.0063
a2 = sigmoid(-0.0063) ≈ 0.4984
损失 L = (0.4984 - 1)² ≈ 0.2516

反向传播(关键步骤)

复制代码
∂L/∂a2 = 2*(a2 - y_true) ≈ -1.0032
∂a2/∂z2 = a2*(1-a2) ≈ 0.25
∂L/∂z2 = ∂L/∂a2 * ∂a2/∂z2 ≈ -0.2508

∂z2/∂w2 = a1 ≈ 0.6457
∂L/∂w2 = ∂L/∂z2 * ∂z2/∂w2 ≈ -0.1620

...继续反向传播到第一层...

核心价值总结

方面 说明
自动微分 无需手动推导梯度公式
计算效率 避免重复计算,复杂度 O(网络规模)
模块化 每层只需实现前向/反向传播
支持深度学习 使训练深层网络成为可能

历史意义

反向传播(1986年由Rumelhart等人普及)是神经网络发展的关键突破:

  • 解决了多层感知机的训练问题
  • 开启了第一次神经网络研究热潮
  • 是现代深度学习的基础

简单说:反向传播就是神经网络"从错误中学习"的数学实现------它告诉网络每个参数应该调整多少来减少预测误差。

六、梯度下降

梯度下降

梯度下降是什么?

梯度下降是一种优化算法,用于最小化损失函数。它的核心思想是:通过迭代的方式,沿着损失函数梯度的反方向(下降最快的方向)更新模型参数,逐步逼近函数的最小值点。

为了解决什么问题?

梯度下降主要解决以下问题:

  1. 优化问题:在机器学习中,我们通常需要找到一组模型参数,使损失函数(预测值与真实值之间的差距)最小化
  2. 高维空间搜索:当参数数量很多时(深度学习模型可能有数百万甚至数十亿参数),无法直接计算全局最优解,需要高效的迭代方法
  3. 可扩展性:需要能够处理大规模数据集的优化方法

现在深度学习的反向传播都用梯度下降吗?

基本上是的,但有不同变体

  1. 反向传播(Backpropagation):是计算梯度的方法
  2. 梯度下降:是利用这些梯度更新参数的方法

现代深度学习使用的通常是梯度下降的变体

  • 随机梯度下降(SGD):每次使用单个样本计算梯度
  • 小批量梯度下降(Mini-batch Gradient Descent):每次使用一小批样本计算梯度(最常用)
  • 带动量的SGD:添加动量项加速收敛
  • 自适应学习率方法:如Adam、Adagrad、RMSprop等(当前主流)

Adam是目前最广泛使用的优化器,它结合了动量方法和自适应学习率的优点。

简单例子:线性回归的梯度下降

假设我们要拟合线性模型:y = wx + b

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 生成模拟数据
np.random.seed(42)
X = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 6, 8, 10])  # 完美线性关系:y = 2x

# 初始化参数
w = 0.0  # 权重
b = 0.0  # 偏置
learning_rate = 0.01  # 学习率
epochs = 100  # 迭代次数

# 存储历史值用于可视化
history_w = []
history_b = []
history_loss = []

# 梯度下降
for epoch in range(epochs):
    # 前向传播:计算预测值
    y_pred = w * X + b
    
    # 计算损失(均方误差)
    loss = np.mean((y_pred - y) ** 2)
    
    # 计算梯度(反向传播)
    dw = 2 * np.mean((y_pred - y) * X)  # w的梯度
    db = 2 * np.mean(y_pred - y)        # b的梯度
    
    # 更新参数(梯度下降步骤)
    w = w - learning_rate * dw
    b = b - learning_rate * db
    
    # 记录历史
    history_w.append(w)
    history_b.append(b)
    history_loss.append(loss)
    
    # 打印进度
    if epoch % 10 == 0:
        print(f"Epoch {epoch}: w={w:.4f}, b={b:.4f}, loss={loss:.4f}")

print(f"\n最终结果: w={w:.4f}, b={b:.4f}")
print(f"真实关系: y = 2.0*x + 0.0")

# 可视化训练过程
fig, axes = plt.subplots(1, 3, figsize=(15, 4))

# 损失函数下降曲线
axes[0].plot(history_loss)
axes[0].set_xlabel('Epoch')
axes[0].set_ylabel('Loss')
axes[0].set_title('损失函数下降')
axes[0].grid(True)

# 参数w的变化
axes[1].plot(history_w)
axes[1].set_xlabel('Epoch')
axes[1].set_ylabel('w value')
axes[1].set_title('权重w的更新过程')
axes[1].axhline(y=2.0, color='r', linestyle='--', label='真实值 w=2.0')
axes[1].legend()
axes[1].grid(True)

# 最终拟合结果
axes[2].scatter(X, y, label='真实数据')
axes[2].plot(X, w*X + b, color='red', label=f'拟合直线: y={w:.2f}x+{b:.2f}')
axes[2].set_xlabel('X')
axes[2].set_ylabel('y')
axes[2].set_title('拟合结果')
axes[2].legend()
axes[2].grid(True)

plt.tight_layout()
plt.show()

关键概念总结

概念 说明
梯度 函数在某点的变化率最快的方向
学习率 控制参数更新步长的超参数
迭代 重复执行参数更新的过程
收敛 损失函数不再显著减少的状态

梯度下降的变体对比

方法 优点 缺点
批量梯度下降 稳定,收敛路径平滑 计算成本高,内存要求大
随机梯度下降 计算快,可在线学习 波动大,收敛不稳定
小批量梯度下降 平衡了稳定性和效率 需要调整批量大小
Adam 自适应学习率,收敛快 超参数可能敏感

在实际深度学习项目中,通常从Adam 优化器开始尝试,如果发现收敛问题,再考虑使用SGD(可能配合动量)。选择哪种方法取决于具体问题、数据规模和模型架构。

相关推荐
NAGNIP5 小时前
一文搞懂深度学习中的通用逼近定理!
人工智能·算法·面试
冬奇Lab6 小时前
一天一个开源项目(第36篇):EverMemOS - 跨 LLM 与平台的长时记忆 OS,让 Agent 会记忆更会推理
人工智能·开源·资讯
冬奇Lab6 小时前
OpenClaw 源码深度解析(一):Gateway——为什么需要一个"中枢"
人工智能·开源·源码阅读
AngelPP10 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年10 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼10 小时前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS11 小时前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区12 小时前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈12 小时前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能
Ray Liang12 小时前
被低估的量化版模型,小身材也能干大事
人工智能·ai·ai助手·mindx