1. 线性回归:深度学习的"Hello World"
线性回归是机器学习领域最基础的算法之一,也是理解深度学习的重要起点。这个看似简单的模型实际上包含了神经网络的核心概念:权重、偏置、损失函数和优化过程。就像学习编程从"Hello World"开始一样,线性回归就是深度学习的入门仪式。
在PyTorch框架中实现线性回归,我们可以清晰地看到深度学习框架如何将数学公式转化为可执行的代码。不同于从零开始手动实现,使用框架能让我们专注于模型设计而非底层计算细节。这就像用现成的积木搭建房屋,而不需要从砍树烧砖开始。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 线性回归的数学本质
2.1 模型定义
线性回归模型的基本形式为:
y = Xw + b
其中:
- X是输入特征矩阵(形状为n×d,n是样本数,d是特征维度)
- w是权重向量(形状为d×1)
- b是偏置项(标量)
- y是预测输出(形状为n×1)
2.2 损失函数
我们使用均方误差(MSE)作为损失函数:
L = 1/n Σ(y_pred - y_true)²
这个损失函数衡量了模型预测值与真实值之间的差距,是优化过程的核心指引。
3. PyTorch实现详解
3.1 数据准备
首先我们需要生成模拟数据:
python复制import torch
from torch.utils import data
# 真实参数
true_w = torch.tensor([2, -3.4])
true_b = 4.2
# 生成数据集
features, labels = synthetic_data(true_w, true_b, 1000)
# 构建数据加载器
def load_array(data_arrays, batch_size, is_train=True):
dataset = data.TensorDataset(*data_arrays)
return data.DataLoader(dataset, batch_size, shuffle=is_train)
batch_size = 10
data_iter = load_array((features, labels), batch_size)
这里我们生成了1000个样本,每个样本有2个特征。数据加载器将数据分成小批量,便于后续训练。
3.2 模型定义
在PyTorch中,我们可以用几行代码定义模型:
python复制from torch import nn
net = nn.Sequential(nn.Linear(2, 1))
这行代码创建了一个包含单个全连接层的神经网络。nn.Linear(2, 1)表示输入维度是2,输出维度是1。
3.3 参数初始化
良好的初始化对训练至关重要:
python复制net[0].weight.data.normal_(0, 0.01)
net[0].bias.data.fill_(0)
这里我们将权重初始化为均值为0,标准差为0.01的正态分布,偏置初始化为0。
3.4 损失函数和优化器
python复制loss = nn.MSELoss()
trainer = torch.optim.SGD(net.parameters(), lr=0.03)
我们选择均方误差作为损失函数,使用随机梯度下降(SGD)作为优化器,学习率设为0.03。
4. 训练过程剖析
4.1 训练循环
python复制num_epochs = 3
for epoch in range(num_epochs):
for X, y in data_iter:
l = loss(net(X), y)
trainer.zero_grad()
l.backward()
trainer.step()
l = loss(net(features), labels)
print(f'epoch {epoch + 1}, loss {l:f}')
训练过程分为以下几个关键步骤:
- 前向传播计算预测值
- 计算损失
- 反向传播计算梯度
- 优化器更新参数
4.2 训练结果分析
经过3个epoch的训练,我们可以看到损失从初始的约0.000248下降到0.000103,说明模型已经较好地拟合了数据。
检查学习到的参数:
python复制w = net[0].weight.data
print('w的估计误差:', true_w - w.reshape(true_w.shape))
b = net[0].bias.data
print('b的估计误差:', true_b - b)
输出显示参数估计非常接近真实值,误差在可接受范围内。
5. 关键知识点解析
5.1 自动微分系统
PyTorch的autograd系统自动计算导数,这是深度学习框架的核心功能。通过l.backward()调用,框架会自动计算所有需要梯度的张量的导数。
5.2 小批量训练的优势
使用小批量训练有多个好处:
- 内存效率更高
- 计算更高效(可以利用GPU并行计算)
- 引入噪声有助于逃离局部极小值
5.3 学习率的选择
学习率是超参数调优中最关键的参数之一:
- 太大:可能导致震荡甚至发散
- 太小:收敛速度过慢
0.03在这个例子中是经过实验确定的合适值。
6. 常见问题与解决方案
6.1 梯度消失/爆炸
虽然线性回归中不常见,但在更深层的网络中可能遇到:
- 解决方案:合适的初始化、归一化、残差连接等
6.2 过拟合
线性回归模型简单,通常不易过拟合,但仍需注意:
- 解决方案:增加数据量、正则化(L1/L2)
6.3 数值稳定性
当特征尺度差异大时可能出问题:
- 解决方案:特征标准化
7. 扩展应用
虽然我们实现的是简单线性回归,但相同原理可应用于:
- 多元线性回归
- 逻辑回归
- 更复杂的神经网络
这个基础模型展示了PyTorch的核心工作流程,后续更复杂的模型都是在这个基础上的扩展。
8. 调试技巧
8.1 检查梯度
python复制print(net[0].weight.grad)
print(net[0].bias.grad)
在训练过程中检查梯度可以帮助诊断问题。
8.2 可视化训练过程
绘制损失曲线可以直观观察训练效果:
python复制import matplotlib.pyplot as plt
losses = [...] # 记录每个epoch的loss
plt.plot(losses)
plt.xlabel('epoch')
plt.ylabel('loss')
9. 性能优化建议
9.1 使用GPU加速
python复制device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
net.to(device)
features = features.to(device)
labels = labels.to(device)
对于更大规模的数据,使用GPU可以显著加速训练。
9.2 调整批量大小
批量大小影响训练动态和内存使用:
- 较小批量:更频繁的更新,更多噪声
- 较大批量:更稳定的梯度估计,更高内存需求
10. 从线性回归到深度学习
虽然线性回归看似简单,但它包含了深度学习的核心要素:
- 层结构(这里是单个全连接层)
- 损失函数
- 优化算法
- 自动微分
理解了这个基础模型,就掌握了打开深度学习大门的钥匙。后续的卷积网络、循环网络等复杂架构,都是在这些基础概念上的扩展和组合。
