📚 课程目录

第1课:感知机与线性回归

📖 本课概述

深度学习的一切始于最简单的模型——感知机和线性回归。本课将从数学原理出发,理解这些基础模型如何学习,并通过PyTorch实机验证。

🧠 一、感知机(Perceptron)

1.1 历史背景

1957年,Frank Rosenblatt提出感知机——第一个可以学习的人工神经网络模型。它是现代神经网络的鼻祖,虽然简单,却蕴含了深度学习最核心的思想:通过数据自动学习参数

1.2 数学定义

感知机的数学表达式:

f(x) = σ(w₁x₁ + w₂x₂ + ... + wₙxₙ + b) = σ(wᵀx + b)

其中:

• x = (x₁, x₂, ..., xₙ) 是输入向量

• w = (w₁, w₂, ..., wₙ) 是权重向量

• b 是偏置项

• σ 是激活函数(感知机中使用阶跃函数)

1.3 几何直觉

在二维空间中,感知机画出一条直线 w₁x₁ + w₂x₂ + b = 0,将平面分成两个区域。权重向量 w 决定了直线的方向,偏置 b 决定了直线离原点的距离。

对于AND逻辑门,真值表为:

x₁x₂AND
000
010
100
111

AND门是线性可分的——存在一条直线可以完美分开正例和负例,所以感知机可以学会。

⚠️ 感知机的局限:XOR(异或)门是线性不可分的,单层感知机无法解决!这正是1969年Minsky指出的,导致了第一次AI寒冬。多层感知机(MLP)才能解决XOR问题。

1.4 PyTorch实现AND门


import torch
import torch.nn as nn

# 感知机实现
class Perceptron(nn.Module):
    def __init__(self, input_dim):
        super().__init__()
        self.linear = nn.Linear(input_dim, 1)
        self.activation = nn.Sigmoid()
    
    def forward(self, x):
        return self.activation(self.linear(x))

# AND 门训练
X = torch.tensor([[0,0],[0,1],[1,0],[1,1]], dtype=torch.float32)
y = torch.tensor([[0],[0],[0],[1]], dtype=torch.float32)

model = Perceptron(2)
criterion = nn.BCELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.5)

losses = []
for epoch in range(1000):
    optimizer.zero_grad()
    output = model(X)
    loss = criterion(output, y)
    loss.backward()
    optimizer.step()
    if epoch % 200 == 0:
        losses.append(f"Epoch {epoch}: loss={loss.item():.6f}")

# 测试
with torch.no_grad():
    pred = model(X)
    results = (pred > 0.5).float()
    accuracy = (results == y).float().mean()

print("=== AND 门训练结果 ===")
for l in losses:
    print(l)
print(f"\n预测输出: {pred.squeeze().tolist()}")
print(f"四舍五入: {results.squeeze().tolist()}")
print(f"准确率: {accuracy.item():.2%}")

# 权重分析
w = model.linear.weight.data.squeeze()
b = model.linear.bias.data.item()
print(f"\n权重: w1={w[0]:.4f}, w2={w[1]:.4f}")
print(f"偏置: b={b:.4f}")
print(f"决策边界: {w[0]:.4f}*x1 + {w[1]:.4f}*x2 + {b:.4f} = 0")
🟢 运行结果 — AND门训练 ✅验证通过 === AND 门训练结果 === Epoch 0: loss=0.798882 Epoch 200: loss=0.143578 Epoch 400: loss=0.081636 Epoch 600: loss=0.056532 Epoch 800: loss=0.043049 预测输出: [0.00010147895955014974, 0.03979651629924774, 0.039796553552150726, 0.9442138075828552] 四舍五入: [0.0, 0.0, 0.0, 1.0] 准确率: 100.00% 权重: w1=6.0122, w2=6.0122 偏置: b=-9.1956 决策边界: 6.0122*x1 + 6.0122*x2 + -9.1956 = 0

📐 二、线性回归

2.1 问题定义

线性回归是机器学习最基本的模型,目标是找到最优的线性关系:

ŷ = wx + b

目标:最小化均方误差(MSE):

L(w,b) = (1/N) Σᵢ(yᵢ - ŷᵢ)² = (1/N) Σᵢ(yᵢ - wxᵢ - b)²

2.2 解析解 vs 梯度下降

线性回归有解析解(闭式解),但在深度学习中,我们用梯度下降来优化。因为:

2.3 梯度推导

对w求偏导:∂L/∂w = (2/N) Σᵢ -xᵢ(yᵢ - wxᵢ - b)

对b求偏导:∂L/∂b = (2/N) Σᵢ -(yᵢ - wxᵢ - b)

梯度更新:w ← w - η · ∂L/∂w,b ← b - η · ∂L/∂b

其中 η 是学习率(learning rate)

2.4 PyTorch实现线性回归


import torch
import torch.nn as nn
import numpy as np

# 线性回归:y = 3x + 2 + noise
torch.manual_seed(42)
X = torch.linspace(0, 10, 100).reshape(-1, 1)
y = 3 * X + 2 + torch.randn(X.shape) * 1.5

model = nn.Linear(1, 1)
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

loss_history = []
for epoch in range(500):
    optimizer.zero_grad()
    pred = model(X)
    loss = criterion(pred, y)
    loss.backward()
    optimizer.step()
    if epoch % 100 == 0:
        loss_history.append(loss.item())
        print(f"Epoch {epoch}: loss={loss.item():.4f}")

w = model.weight.item()
b = model.bias.item()
print(f"\n学习到的参数: w={w:.4f}, b={b:.4f}")
print(f"真实参数: w=3.0000, b=2.0000")
print(f"误差: w_err={abs(w-3):.4f}, b_err={abs(b-2):.4f}")

# 训练曲线数据
print("\n=== 训练曲线 ===")
for i, l in enumerate(loss_history):
    bar = "█" * int(l / max(loss_history) * 30)
    print(f"Epoch {i*100:4d}: {l:8.4f} {bar}")
🟢 运行结果 — 线性回归训练 ✅验证通过 Epoch 0: loss=365.9037 Epoch 100: loss=2.7672 Epoch 200: loss=2.3885 Epoch 300: loss=2.2486 Epoch 400: loss=2.1969 学习到的参数: w=3.0228, b=1.9237 真实参数: w=3.0000, b=2.0000 误差: w_err=0.0228, b_err=0.0763 === 训练曲线 === Epoch 0: 365.9037 ██████████████████████████████ Epoch 100: 2.7672 Epoch 200: 2.3885 Epoch 300: 2.2486 Epoch 400: 2.1969

🔬 三、深入理解

3.1 感知机与线性回归的统一视角

感知机和线性回归本质上都是线性模型,区别在于:

特性线性回归感知机
输出连续值离散类别(0/1)
损失函数MSE0-1损失/交叉熵
激活函数恒等函数阶跃/Sigmoid
任务类型回归分类

3.2 学习率的影响

学习率 η 是训练最重要的超参数之一:

💡 选择学习率的经验:从0.1开始,如果loss震荡则减半,如果收敛太慢则加倍。常用值:SGD用0.01-0.1,Adam用0.001-0.01。

🔬 四、从感知机到深度网络

4.1 多层感知机(MLP)

单层感知机只能解决线性可分问题。但如果把多个感知机层叠起来,就能解决XOR等非线性问题。

MLP: y = σ₂(W₂·σ₁(W₁x + b₁) + b₂)

第一层:学习中间表示 h = σ₁(W₁x + b₁)

第二层:在新的特征空间上做线性分类 y = σ₂(W₂h + b₂)

XOR问题的解决:第一层将输入映射到新的空间,使得原来线性不可分的数据变得可分。

4.2 通用近似定理

1989年,Cybenko证明:具有单个隐藏层的前馈网络,只要隐藏层足够宽,可以近似任意连续函数到任意精度。但实践中,深度比宽度更高效——更深的网络可以用指数级更少的神经元表达同样的函数。

4.3 线性回归的假设与局限

假设含义违反时怎么办
线性关系y与x线性相关特征变换/非线性模型
独立同分布样本独立采样时间序列模型
同方差性误差方差恒定加权回归
无多重共线性特征间不高度相关正则化/降维

📖 五、延伸阅读

💡 推荐资源:

📝 练习

练习1:实现OR门

修改上面的AND门代码,训练一个OR门感知机。OR门的真值表是什么?它是线性可分的吗?

练习2:XOR门的挑战

尝试用单层感知机训练XOR门,观察结果。思考:为什么无法收敛?如何用两层感知机解决?

练习3:不同学习率

用学习率 0.001、0.01、0.1、1.0 分别训练线性回归,观察收敛速度和稳定性。

💡 六、实践技巧总结

6.1 感知机实现Checklist

  1. 确保数据已归一化(零均值、单位方差)
  2. 使用合适的学习率(Sigmoid输出用0.1-1.0)
  3. 检查梯度是否正常(不为0、不爆炸)
  4. 监控训练/验证损失曲线
  5. 验证决策边界的合理性

6.2 调试技巧

⚠️ 当模型不收敛时,按以下顺序检查:

  1. 数据:标签是否正确?特征是否归一化?
  2. 损失函数:是否与任务匹配?数值是否稳定?
  3. 梯度:是否全为0?是否NaN?
  4. 学习率:是否太大/太小?
  5. 模型容量:是否太小(欠拟合)或太大(过拟合)?

6.3 线性回归在深度学习中的角色

虽然线性回归看起来简单,但它是理解深度学习的基石:

🏆

成就解锁:启蒙之光

完成本课学习,你已经理解了深度学习最基础的构建块——感知机和线性回归。
这是从单细胞生物到神经网络的第一步!