深度学习基础:从线性回归到深度神经网络
本文将将从最基础的线性回归出发,逐步推演至Softmax回归、多层感知机(MLP),最后通过一个完整的PyTorch工程实践,展示如何构建、训练并部署一个深度学习模型。
1. 深度学习的数学基石:线性回归
线性回归是神经网络最简单的形式(单层网络)。它试图通过特征的线性组合来拟合目标值。
1.1 理论模型
假设输入特征为 \(x \in \mathbb{R}^d\) ,权重为 \(w \in \mathbb{R}^d\) ,偏置为 \(b \in \mathbb{R}\) ,则预测值 \(\hat{y}\) 为:
\[ \hat{y} = w^T x + b \]
为了衡量预测值与真实值 \(y\) 的差异,我们通常使用均方误差(MSE) 作为损失函数:
\[ L(\hat{y}, y) = \frac{1}{2} (\hat{y} - y)^2 \]
训练的目标是找到 \(w\) 和 \(b\) ,使得所有样本的平均损失最小化。
1.2 原生实现(基于 PyTorch Autograd)
我们不依赖高级API,仅使用张量和自动求导来实现随机梯度下降(SGD)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 import torch
import random
import numpy as np
import matplotlib.pyplot as plt
# 1. 生成合成数据 y = Xw + b + noise
def synthetic_data ( w , b , num_examples ):
X = torch . normal ( 0 , 1 , ( num_examples , len ( w )))
y = torch . matmul ( X , w ) + b
y += torch . normal ( 0 , 0.01 , y . shape )
return X , y . reshape (( - 1 , 1 ))
true_w = torch . tensor ([ 2 , - 3.4 ])
true_b = 4.2
features , labels = synthetic_data ( true_w , true_b , 1000 )
# 2. 定义模型参数
w = torch . normal ( 0 , 0.01 , size = ( 2 , 1 ), requires_grad = True )
b = torch . zeros ( 1 , requires_grad = True )
# 3. 定义模型与损失
def linreg ( X , w , b ):
return torch . matmul ( X , w ) + b
def squared_loss ( y_hat , y ):
return ( y_hat - y . reshape ( y_hat . shape )) ** 2 / 2
# 4. 优化算法:随机梯度下降
def sgd ( params , lr , batch_size ):
with torch . no_grad ():
for param in params :
param -= lr * param . grad / batch_size
param . grad . zero_ ()
# 5. 训练循环
lr = 0.03
num_epochs = 3
batch_size = 10
for epoch in range ( num_epochs ):
for i in range ( 0 , len ( features ), batch_size ):
X = features [ i : i + batch_size ]
y = labels [ i : i + batch_size ]
l = squared_loss ( linreg ( X , w , b ), y )
l . sum () . backward ()
sgd ([ w , b ], lr , batch_size )
with torch . no_grad ():
train_l = squared_loss ( linreg ( features , w , b ), labels )
print ( f 'epoch { epoch + 1 } , loss { float ( train_l . mean ()) : f } ' )
2. 处理分类问题:Softmax 回归
线性回归适用于预测连续值,而对于分类问题(如手写数字识别),我们需要输出属于每个类别的概率。
2.1 核心概念
Logits : 模型的原始输出 \(o = Wx + b\) 。
Softmax : 将Logits映射为概率分布,保证所有概率非负且和为1。
\[
\hat{y}_j = \frac{\exp(o_j)}{\sum_k \exp(o_k)}
\]
交叉熵损失 (Cross Entropy) : 衡量两个概率分布的差异。
\[
L(y, \hat{y}) = - \sum_j y_j \log \hat{y}_j
\]
2.2 PyTorch 简洁实现
利用 torch.nn 模块,我们可以更高效地实现Softmax回归。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import torch
from torch import nn
# 定义网络:输入维度784 (28x28图片展平),输出维度10 (10个类别)
# PyTorch的CrossEntropyLoss已经内置了Softmax,所以网络只需输出Logits
net = nn . Sequential ( nn . Flatten (), nn . Linear ( 784 , 10 ))
# 初始化权重
def init_weights ( m ):
if type ( m ) == nn . Linear :
nn . init . normal_ ( m . weight , std = 0.01 )
net . apply ( init_weights )
# 损失函数与优化器
loss = nn . CrossEntropyLoss ()
trainer = torch . optim . SGD ( net . parameters (), lr = 0.1 )
# 训练代码(伪代码)
# for X, y in train_iter:
# l = loss(net(X), y)
# trainer.zero_grad()
# l.backward()
# trainer.step()
3. 引入非线性:多层感知机 (MLP)
线性模型(线性回归和Softmax回归)的局限性在于它们只能学习线性决策边界。为了解决复杂问题(如XOR问题),我们需要引入隐藏层和非线性激活函数。
3.1 网络结构
输入层 : 特征向量
隐藏层 : \(H = \sigma(W_1 X + b_1)\) ,其中 \(\sigma\) 是非线性激活函数。
输出层 : \(O = W_2 H + b_2\)
3.2 常见激活函数
ReLU : \(\max(0, x)\) 。计算简单,缓解梯度消失,是目前最主流的选择。
Sigmoid : \(\frac{1}{1+e^{-x}}\) 。将输出压缩到(0,1),但在深层网络中易导致梯度消失。
Tanh : 双曲正切,输出范围(-1, 1)。
3.3 实现 MLP
1
2
3
4
5
6
7
8
9
10
11
12 net = nn . Sequential (
nn . Flatten (),
nn . Linear ( 784 , 256 ), # 隐藏层:256个神经元
nn . ReLU (), # 非线性激活
nn . Linear ( 256 , 10 ) # 输出层
)
# 权重初始化
def init_weights ( m ):
if type ( m ) == nn . Linear :
nn . init . xavier_uniform_ ( m . weight )
net . apply ( init_weights )
4. 计算机视觉核心:卷积神经网络 (CNN)
多层感知机(MLP)在处理图像时面临两个主要问题:
参数量爆炸 :全连接层需要将图像展平,忽略了像素间的空间结构。对于高分辨率图像,参数量会非常巨大。
忽略局部相关性 :图像中的物体(如猫)可能出现在任何位置,全连接层难以高效捕捉这种平移不变性。
卷积神经网络(CNN)通过局部感受野 和权值共享 解决了这些问题。
4.1 核心组件
卷积层 (Convolutional Layer)
卷积层通过滑动一个小的“滤波器”(Kernel)在图像上提取特征(如边缘、纹理)。
计算公式 :
输出特征图 \(Y\) 的某个位置 \((i,j)\) 的计算如下:
$$
Y_{i,j} = \sum_m \sum_n X_{i+m, j+n} \cdot K_{m,n} + B
$$
关键参数 :
Kernel Size : 卷积核大小(如 3x3)。
Stride : 滑动步长,步长越大,输出尺寸越小。
Padding : 填充边缘,保持输出尺寸或保留边缘信息。
池化层 (Pooling Layer)
池化层用于降维和提取主要特征,增加模型的鲁棒性。
* Max Pooling : 取窗口内的最大值。
* Average Pooling : 取窗口内的平均值。
4.2 PyTorch 实现 CNN Block
一个典型的 CNN 模块包含:卷积 -> 激活 -> 池化。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import torch
from torch import nn
# 定义一个简单的 CNN 块
cnn_block = nn . Sequential (
# 卷积层: 输入通道3 (RGB),输出通道32,卷积核3x3,填充1
nn . Conv2d ( in_channels = 3 , out_channels = 32 , kernel_size = 3 , padding = 1 ),
# 激活函数
nn . ReLU (),
# 池化层: 2x2 最大池化,特征图长宽减半
nn . MaxPool2d ( kernel_size = 2 , stride = 2 )
)
# 测试输入 (Batch=1, Channel=3, Height=32, Width=32)
x = torch . randn ( 1 , 3 , 32 , 32 )
output = cnn_block ( x )
print ( output . shape )
# 输出: torch.Size([1, 32, 16, 16])
# 通道数变为32,尺寸 32x32 -> 16x16
5. PyTorch 深度学习工程实践
整合以上知识,我们以 CIFAR-10 数据集为例,构建一个完整的深度学习训练流程。我们将利用 CNN 的能力来识别图像。
5.1 完整训练 Pipeline
一个标准的深度学习工程包含以下步骤:
1. 数据准备 : Dataset 与 DataLoader
2. 模型构建 : 继承 nn.Module
3. 损失与优化 : Loss Function & Optimizer
4. 训练循环 : Forward -> Loss -> Backward -> Step
5. 评估与保存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 import torch
import torchvision
import torchvision.transforms as transforms
from torch import nn
from torch.optim import SGD
from tqdm import tqdm
# 1. 设备配置
device = "cuda" if torch . cuda . is_available () else "mps" if torch . backends . mps . is_available () else "cpu"
print ( f "Using device: { device } " )
# 2. 数据预处理与加载
transform = transforms . Compose ([
transforms . ToTensor (),
transforms . Normalize (( 0.5 , 0.5 , 0.5 ), ( 0.5 , 0.5 , 0.5 )) # 标准化
])
batch_size = 64
train_dataset = torchvision . datasets . CIFAR10 ( root = "../data" , train = True , download = True , transform = transform )
test_dataset = torchvision . datasets . CIFAR10 ( root = "../data" , train = False , download = True , transform = transform )
train_dataloader = torch . utils . data . DataLoader ( train_dataset , batch_size = batch_size , shuffle = True )
test_dataloader = torch . utils . data . DataLoader ( test_dataset , batch_size = batch_size , shuffle = False )
# 3. 构建模型 (简单的 CNN)
class CNNModel ( nn . Module ):
def __init__ ( self ):
super () . __init__ ()
# 特征提取层
self . features = nn . Sequential (
nn . Conv2d ( 3 , 32 , kernel_size = 3 , padding = 1 ),
nn . ReLU (),
nn . MaxPool2d ( 2 , 2 ), # 32x16x16
nn . Conv2d ( 32 , 64 , kernel_size = 3 , padding = 1 ),
nn . ReLU (),
nn . MaxPool2d ( 2 , 2 ), # 64x8x8
)
# 分类层
self . classifier = nn . Sequential (
nn . Flatten (),
nn . Linear ( 64 * 8 * 8 , 512 ),
nn . ReLU (),
nn . Linear ( 512 , 10 )
)
def forward ( self , x ):
x = self . features ( x )
x = self . classifier ( x )
return x
model = CNNModel () . to ( device )
# 4. 损失函数与优化器
criterion = nn . CrossEntropyLoss ()
optimizer = SGD ( model . parameters (), lr = 0.01 , momentum = 0.9 )
# 5. 训练与评估循环
epochs = 10
for epoch in range ( epochs ):
# --- 训练阶段 ---
model . train ()
running_loss = 0.0
for inputs , labels in tqdm ( train_dataloader , desc = f "Epoch { epoch + 1 } Train" ):
inputs , labels = inputs . to ( device ), labels . to ( device )
optimizer . zero_grad () # 清空梯度
outputs = model ( inputs ) # 前向传播
loss = criterion ( outputs , labels ) # 计算损失
loss . backward () # 反向传播
optimizer . step () # 更新参数
running_loss += loss . item ()
# --- 评估阶段 ---
model . eval ()
correct = 0
total = 0
with torch . no_grad ():
for inputs , labels in test_dataloader :
inputs , labels = inputs . to ( device ), labels . to ( device )
outputs = model ( inputs )
_ , predicted = torch . max ( outputs . data , 1 )
total += labels . size ( 0 )
correct += ( predicted == labels ) . sum () . item ()
acc = 100 * correct / total
print ( f "Epoch { epoch + 1 } Loss: { running_loss / len ( train_dataloader ) : .3f } | Test Acc: { acc : .2f } %" )
# 6. 保存模型
torch . save ( model . state_dict (), "cifar10_cnn.pth" )
总结
从最简单的线性回归到复杂的卷积神经网络,深度学习的核心思想是一致的:通过数据驱动 ,利用梯度下降 算法,不断优化模型参数 以最小化损失函数 。掌握这些基础构建模块(Linear, Conv2d, ReLU, CrossEntropy等),是理解和构建现代大规模AI模型(如Transformer, LLM)的必经之路。
参考资料