深度学习
⚡常用公式速查
激活函数
|函数|公式|输出范围|适用场景|
| ---------| ------| -----------------| --------------|
|Sigmoid| |[0, 1]|二分类输出层|
|Tanh| |[-1, 1]|浅层隐藏层|
|ReLU| |[0, +∞)|深层网络首选|
|Softmax| |(0, 1) 且和为 1|多分类输出层|
输出尺寸计算(卷积/池化)
优化算法
|算法|核心思想|适用场景|
| ----------| --------------------| ----------|
|SGD|基础梯度下降|简单任务|
|Momentum|指数加权平均梯度|减少震荡|
|Adam|Momentum + RMSProp|通用首选|
🎯 快速决策指南
激活函数怎么选?
隐藏层 → ReLU(深层)/ Tanh(浅层)
二分类输出 → Sigmoid
多分类输出 → Softmax
回归输出 → 线性/无激活
损失函数怎么选?
多分类 → CrossEntropyLoss
二分类 → BCELoss
回归(标准) → MSELoss
回归(有异常值) → SmoothL1Loss
优化器怎么选?
默认首选 → Adam
简单任务 → SGD
稀疏数据 → AdaGrad/RMSProp
正则化怎么选?
防止过拟合 → Dropout (p=0.2~0.5)
加速训练 → BatchNorm
特征选择 → L1 正则化
API 汇总
PyTorch 张量操作
创建张量
# 基础创建
torch.tensor(data, dtype=None, device=None, requires_grad=False)
torch.Tensor(data) # float32 张量
torch.IntTensor(data) # int32 张量
torch.FloatTensor(data) # float32 张量
torch.FloatTensor(*sizes)
# 特殊值张量
torch.zeros(2, 3) # 全 0 张量 的 2x3 张量 (*sizes=(2,3))
torch.zeros_like(data) # 基于 data 形状的全 0 张量
torch.ones(2, 3) # 全 1 张量 的 2x3 张量
torch.ones_like(data) # 基于 data 形状的全 1 张量
torch.full((2,3), 5) # 指定值张量 的 2x3 张量
torch.full_like(data, 5) # 基于 data 形状的指定值张量
# data 需要为 torch.Tensor
# 线性
torch.arange(0, 10, 2) # 等差数列 (start, end, step)
torch.linspace(0, 10, 5) # 等间距 (start, end, steps)
# 随机张量
torch.rand(2, 3) # 均匀分布 (0,1)
torch.randn(2, 3) # 正态分布 (0,1)
torch.randint(low=1, high=10, size=(2, 3)) # 随机整数
# 随机种子
torch.manual_seed(0)
torch.initial_seed() # 返回当前随机种子值
torch.seed() # 用系统时间重置随机种子类型转换
# 标准方法
data.type(torch.int16) # torch.int16
data.to(torch.int16) # 现代标准方法
# 类型包括有:
# float16、bfloat16、float32、float64、float8_e4m3fn、float8_e5m2
# int8、int16、int32、int64
# uint8、bool、complex64、complex128
# 快截方法
data.half() # torch.float16
data.float() # torch.float32
data.double() # torch.float64
data.short() # torch.int16
data.int() # torch.int32
data.long() # torch.int64
# 张量 -> NumPy
data.numpy() # 共享内存
data.numpy().copy() # 不共享内存
# numpy -> torch
torch.from_numpy(data) # 共享内存
torch.tensor(data) # 不共享内存
# 标量张量 -> 数字
data.item() # 返回张量的值,仅适用于单个元素的张量基本运算
add、sub、mul、div、neg # 加、减、乘、除、取负
add_、sub_、mul_、div_、neg_ # 带下划线_ :修改原数据
+、-、*、/、--
# 以"加法"为例
data.add(10) # 加法
data.add_(20) # 加法并赋值给data
data + 30 # 加法
data += 40 # 加法并赋值给data
# 乘法
# 元素级乘法,相同形状的两个张量
t1 * t2
t1.mul(t2)
# 矩阵乘法,A行B列
t1 @ t2
t1.matmul(t2)
# 点乘(内积)
torch.dot(t1, t2) # 要求 t1, t2 均为1D
# 运算函数
t.sum() # 整体求和
t.sum(dim=0) # 按列求和
t.sum(dim=1) # 按行求和
t.mean() # 整体求均值
t.max() # 整体求最大值(返回最大值索引)
t.min() # 整体求最小值(返回最小值索引)
t.pow(2) # 求幂(每个数求 2次幂)
t ** 2 # 求幂
t.sqrt() # 平方根
t.exp() # e 的 n 次幂
t.log() # 自然对数
t.log2() # 以 2 为底的对数
t.log10() # 以 10 为底的对数索引
# 【注】包左不包右
# 简单行列索引
data[1] # 单行,单个值时默认为行索引
data[1, :] # 单行
data[:, 2] # 单列
data[1, 2] # 单个元素,[行索引, 列索引]
# 范围索引
data[:2, :3]
data[1::2, ::2] # 奇数行,偶数列
# 多维索引
data[0, :, :] # 0轴上的第1个数据, [:, 行索引, 列索引]
data[:, 1, :] # 1轴上的第2个数据
data[:, :, 2] # 2轴上的第3个数据
# 列表索引,[[行索引],[列索引]]
data[[1,2],[1,2]] # 等价于 [data[1,1], data[2,2]]
data[[[1],[2]],[1,2]] # [[行索引],[列索引]]
# 布尔索引
data[data>5] # 大于5的所有元素
data[data[:, 2]>5, :] # 第3列大于5的所有行
data[:, data[2, :]>5] # 第3行大于5的所有列形状操作
data.reshape(3, 2) # 改变形状 -> (3, 2)
data.unsqueeze(0) # 升维 (在 0 维度增加)
data.squeeze() # 降维 (删除维度为 1 的维度)
data.transpose(0, 1) # 交换维度 0 <-> 1
data.permute(2, 0, 1) # 改变维度顺序 0,1,2 -> 2,0,1
data.view(3, 2) # 改变维度 (要求连续张量)
data.is_contiguous() # 判断是否连续
data.contiguous() # 转为连续张量
# 拼接
torch.cat([a,b], dim=0) # 沿已有维度拼接,dim:拼接的维度
# 以下三行等价:
torch.stack([a, b], dim=1) # 在新维度上堆叠
torch.cat([a.unsqueeze(1), b.unsqueeze(1)], dim=1)
torch.cat([t.unsqueeze(1) for t in [a, b]], dim=1)
# cat():除拼接维度外,其他维度形状完全一致
# stack():所有输入张量的完整形状完全一致自动微分
# 创建可梯度张量
w = torch.tensor(10, requires_grad=True, dtype=torch.float)
# requires_grad 表示是否需要计算梯度(仅支持浮点型)
# 计算梯度
loss.sum().backward() # 反向传播 (loss 必须是标量)
# 获取梯度
w.grad # 梯度值 (会累加)
w.grad.zero_() # 梯度清零
# 阻断梯度传播
t2 = t1.detach() # 返回新张量,不追踪梯度
# 解决:自动微分,无法直接转换为numpy神经网络 (nn.Module)
全连接层
nn.Linear(in_features, out_features, bias=True)
# in_features: 输入特征数
# out_features: 输出特征数
# bias: 是否使用偏置卷积层
nn.Conv2d(in_channels, out_channels, kernel_size,
stride=1, padding=0, dilation=1, groups=1, bias=True)
# in_channels: 输入通道数 (RGB 图片=3)
# out_channels: 输出通道数 (=卷积核数量)
# kernel_size: 卷积核大小 (3, 5, 7...)
# stride: 步长 (整数或元组)
# padding: 填充 (0, 1, 'same'等)
# - padding='same' 时,stride 必须=1池化层
# 最大池化 (最常用)
nn.MaxPool2d(kernel_size=2, stride=2, padding=0)
# 平均池化
nn.AvgPool2d(kernel_size=2, stride=2, padding=0)
# 全局平均池化 (替代全连接层,工程首选)
nn.AdaptiveAvgPool2d(output_size=1)循环神经网络层
# RNN
nn.RNN(input_size, hidden_size, num_layers=1, batch_first=False)
# input_size: 输入特征维度 (词向量维度)
# hidden_size: 隐藏层维度
# num_layers: 隐藏层层数
# batch_first: True 时输入为 (batch, seq_len, input_size)
# 调用
output, hn = rnn(x, h0)
# x: [seq_len, batch, input_size]
# h0: [num_layers, batch, hidden_size]
# output: [seq_len, batch, hidden_size]
# hn: [num_layers, batch, hidden_size]词嵌入层
nn.Embedding(num_embeddings, embedding_dim)
# num_embeddings: 词汇表大小
# embedding_dim: 词向量维度激活函数
nn.Sigmoid()
nn.Tanh()
nn.ReLU()
nn.LeakyReLU(negative_slope=0.01)
nn.Softmax(dim=1) # dim=1 按行归一化正则化层
# Dropout (随机失活)
nn.Dropout(p=0.4) # p: 失活概率 (0.2~0.5)
# Batch Normalization
nn.BatchNorm1d(num_features) # 全连接层/1D 数据
nn.BatchNorm2d(num_features) # 卷积层/2D 图像
nn.BatchNorm3d(num_features) # 3D 卷积/视频
# num_features: 输入特征数 (=通道数)
# eps: 防止除以 0 (默认 1e-5)
# momentum: 动量系数 (默认 0.1)
# affine: 是否使用可学习参数γ和β (默认 True)损失函数 (nn.Loss)
分类任务
# 多分类交叉熵损失 (最常用)
nn.CrossEntropyLoss()
# 输入:logits (未归一化的分数)
# 自动包含 softmax + NLLLoss
# 适用:多分类问题
# 二分类交叉熵损失
nn.BCELoss()
# 输入:概率值 (需先经过 sigmoid)
# 适用:二分类问题
# 二分类交叉熵损失 (带 logits)
nn.BCEWithLogitsLoss()
# 输入:logits (自动包含 sigmoid)
# 适用:二分类问题 (数值更稳定)回归任务
# MAE 损失 (L1 Loss)
nn.L1Loss()
# 对异常值不敏感
# MSE 损失 (L2 Loss)
nn.MSELoss()
# 对异常值敏感,梯度易爆炸
# Smooth L1 Loss
nn.SmoothL1Loss()
# 误差<1 时用 MSE,误差>1 时用 MAE
# 对异常值鲁棒,梯度平滑优化器 (torch.optim)
基础优化器
# 随机梯度下降
optim.SGD(params, lr=0.01, momentum=0.9, weight_decay=0)
# momentum: 动量系数 (默认 0,常用 0.9)
# weight_decay: L2 正则化系数
# Adam (默认首选)
optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)
# betas: 一阶矩和二阶矩的衰减系数
# AdaGrad (稀疏数据)
optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0)
# RMSProp
optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0)
# alpha: 衰减系数 (对应 beta)优化器基本操作
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 梯度清零
optimizer.zero_grad()
# 参数更新
optimizer.step()
# 保存/加载状态
torch.save(optimizer.state_dict(), 'optimizer.pth')
optimizer.load_state_dict(torch.load('optimizer.pth'))学习率调度器 (torch.optim.lr_scheduler)
StepLR (等间隔衰减)
scheduler = optim.lr_scheduler.StepLR(optimizer,
step_size=50, # 衰减周期 (epoch)
gamma=0.1) # 衰减系数
# 每 50 个 epoch,lr = lr * 0.1MultiStepLR (指定间隔衰减)
scheduler = optim.lr_scheduler.MultiStepLR(optimizer,
milestones=[50, 125, 160],
gamma=0.1)
# 在第 50, 125, 160 个 epoch 时衰减ExponentialLR (指数衰减)
scheduler = optim.lr_scheduler.ExponentialLR(optimizer,
gamma=0.95)
# 每个 epoch: lr = lr * 0.95^epoch调度器使用
# 训练循环中
for epoch in range(max_epoch):
for x, y in dataloader:
# 训练...
optimizer.step()
# 每个 epoch 结束后调用
scheduler.step()
# 获取当前学习率
current_lr = scheduler.get_last_lr()数据加载 (torch.utils.data)
数据集
from torch.utils.data import TensorDataset, DataLoader
# 张量数据集
dataset = TensorDataset(torch.tensor(x_data),
torch.tensor(y_data))
# 数据加载器
dataloader = DataLoader(dataset,
batch_size=16, # 批次大小
shuffle=True, # 训练时打乱
num_workers=0) # 数据加载进程数
# 遍历
for x_batch, y_batch in dataloader:
# 训练...数据集划分
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(
x, y,
test_size=0.2, # 测试集比例
random_state=24, # 随机种子
stratify=y # 分层抽样
)数据标准化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
x_train = scaler.fit_transform(x_train) # 拟合并转换
x_test = scaler.transform(x_test) # 仅转换 (用训练集的参数)模型保存与加载
保存模型参数 (推荐)
# 保存
torch.save(model.state_dict(), 'model.pth')
# 加载
model = ModelClass() # 先创建模型实例
model.load_state_dict(torch.load('model.pth'))
model.eval() # 设为评估模式保存整个模型
# 保存
torch.save(model, 'model_full.pth')
# 加载
model = torch.load('model_full.pth')模型可视化和评估
torchsummary (查看模型结构)
from torchsummary import summary
summary(model,
input_size=(3, 32, 32), # 输入尺寸 (C, H, W)
batch_size=16, # 批次大小
device='cpu') # 运行设备模型训练/评估模式
# 训练模式 (启用 Dropout, BN 的训练行为)
model.train()
# 评估模式 (关闭 Dropout, BN 使用统计量)
model.eval()
# 重要:评估时要用 torch.no_grad()
with torch.no_grad():
output = model(x)准确率计算
# 多分类
correct = (y_pred.argmax(dim=1) == y).sum().item()
accuracy = correct / len(y)
# 二分类
correct = ((y_pred > 0.5).float() == y).sum().item()
accuracy = correct / len(y)常用工具函数
参数初始化
import torch.nn as nn
# 获取参数
tensor = model.linear.weight
tensor = model.linear.bias
# 初始化方法
nn.init.uniform_(tensor, a, b) # 均匀分布
nn.init.normal_(tensor, mean=0, std=1) # 正态分布
nn.init.zeros_(tensor) # 全 0
nn.init.ones_(tensor) # 全 1
nn.init.constant_(tensor, val=0.1) # 固定值
nn.init.kaiming_uniform_(tensor) # Kaiming 均匀 (ReLU 首选)
nn.init.kaiming_normal_(tensor) # Kaiming 正态
nn.init.xavier_uniform_(tensor) # Xavier 均匀 (Tanh/Sigmoid)
nn.init.xavier_normal_(tensor) # Xavier 正态设备管理
# 选择设备
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 移动模型和数据到设备
model = model.to(device)
x = x.to(device)
y = y.to(device)梯度裁剪 (防止梯度爆炸)
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
# 在 optimizer.step() 之前调用完整训练流程模板
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
# 1. 准备数据
dataset = TensorDataset(x_data, y_data)
dataloader = DataLoader(dataset, batch_size=16, shuffle=True)
# 2. 创建模型
model = MyModel().to(device)
# 3. 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 4. 学习率调度器 (可选)
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.1)
# 5. 训练循环
epochs = 100
for epoch in range(epochs):
model.train()
total_loss, total_correct, total_samples = 0, 0, 0
for x_batch, y_batch in dataloader:
x_batch, y_batch = x_batch.to(device), y_batch.to(device)
# 前向传播
y_pred = model(x_batch)
loss = criterion(y_pred, y_batch)
# 反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 统计
total_loss += loss.item() * len(y_batch)
total_correct += (y_pred.argmax(dim=1) == y_batch).sum().item()
total_samples += len(y_batch)
# 更新学习率
scheduler.step()
# 打印日志
print(f'Epoch {epoch+1}/{epochs}, '
f'Loss: {total_loss/total_samples:.4f}, '
f'Acc: {total_correct/total_samples:.4f}')
# 6. 保存模型
torch.save(model.state_dict(), 'model.pth')
# 7. 评估
model.load_state_dict(torch.load('model.pth'))
model.eval()
with torch.no_grad():
# 评估代码...关键API
|类别|关键 API|
| ------| ------------|
|张量创建|torch.tensor(),torch.zeros(),torch.rand()|
|张量运算|t.sum(),t.mean(),t @ t2|
|自动微分|requires_grad,.backward(),.grad|
|全连接层|nn.Linear()|
|卷积层|nn.Conv2d()|
|池化层|nn.MaxPool2d(),nn.AdaptiveAvgPool2d()|
|RNN|nn.RNN(),nn.Embedding()|
|激活函数|nn.ReLU(),nn.Sigmoid(),nn.Softmax()|
|正则化|nn.Dropout(),nn.BatchNorm2d()|
|损失函数|nn.CrossEntropyLoss(),nn.MSELoss()|
|优化器|optim.Adam(),optim.SGD()|
|学习率|lr_scheduler.StepLR()|
|数据加载|DataLoader,TensorDataset|
|模型保存|torch.save(),load_state_dict()|
|可视化|summary()|
|初始化|nn.init.kaiming_normal_()|