【深度学习|学习笔记】如何提高小型网络的精度?原则 → 方法 → 代码骨架 → 落地细节!(二)
【深度学习|学习笔记】如何提高小型网络的精度?原则 → 方法 → 代码骨架 → 落地细节!(二)
·
【深度学习|学习笔记】如何提高小型网络的精度?原则 → 方法 → 代码骨架 → 落地细节!(二)
【深度学习|学习笔记】如何提高小型网络的精度?原则 → 方法 → 代码骨架 → 落地细节!(二)
文章目录
欢迎铁子们点赞、关注、收藏!
祝大家逢考必过!逢投必中!上岸上岸上岸!upupup
大多数高校硕博生毕业要求需要参加学术会议,发表EI或者SCI检索的学术论文会议论文。详细信息可扫描博文下方二维码 “
学术会议小灵通”或参考学术信息专栏:https://blog.csdn.net/2401_89898861/article/details/148877490
前言
- 下面给你一份“小型网络提效路线图 + 可直接复用的 PyTorch 配方”。内容按“原则 → 方法 → 代码骨架 →
落地细节/坑位”展开,你可以把代码片段按需拼装到自己的训练脚本中。
2) PyTorch“可拼装”训练配方(小网络专用)
- 说明:下面是可直接集成的函数/模块:
Label Smoothing、Mixup/CutMix、Focal/类平衡损失、Warmup+Cosine、EMA、KD 蒸馏、TTA、SE 模块、GroupNorm 小批训练稳定化。你可以把它们嵌入自己的train_one_epoch和evaluate中。
2.1 训练循环(支持 Mixup/CutMix + Label Smoothing + KD + EMA)
def train_one_epoch(
model, loader, optimizer, epoch,
criterion_ce, device,
teacher=None, kd_T=4.0, kd_alpha=0.5,
use_mixup=True, use_cutmix=False, # 二选一或都关
grad_clip=1.0, ema: EMA=None
):
model.train()
total_loss = 0.0
for x, y in loader:
x, y = x.to(device, non_blocking=True), y.to(device, non_blocking=True)
lam, y_a, y_b = 1.0, y, y
if use_cutmix:
x, y_a, y_b, lam = cutmix_data(x, y, alpha=1.0)
elif use_mixup:
x, y_a, y_b, lam = mixup_data(x, y, alpha=0.2)
logits = model(x)
ce = mix_criterion(criterion_ce, logits, y_a, y_b, lam) if (use_mixup or use_cutmix) else criterion_ce(logits, y)
loss = ce
if teacher is not None:
with torch.no_grad():
t_logits = teacher(x) # 可以用 EMA 教师或预训练大教师
loss = kd_alpha * ce + (1 - kd_alpha) * kd_loss(logits, t_logits, T=kd_T)
optimizer.zero_grad(set_to_none=True)
loss.backward()
if grad_clip is not None:
nn.utils.clip_grad_norm_(model.parameters(), grad_clip)
optimizer.step()
if ema is not None:
ema.update(model)
total_loss += loss.item() * x.size(0)
return total_loss / len(loader.dataset)
2.2 评估(含 TTA)
@torch.no_grad()
def evaluate(model, loader, device, num_classes):
model.eval()
correct, total = 0, 0
for x, y in loader:
x, y = x.to(device), y.to(device)
logits = tta_logits(model, x) # 如需关闭 TTA,改为 model(x)
pred = logits.argmax(1)
correct += (pred == y).sum().item()
total += y.numel()
return correct / total
2.3 一把梭的 main(展示:类平衡 + Label Smoothing + Warmup-Cosine + EMA + 自蒸馏)
def run_training(train_loader, val_loader, num_classes=10, epochs=100, lr=0.1, wd=5e-4, device='cuda'):
student = SmallSEConvNet(num_classes=num_classes).to(device)
# EMA 自蒸馏:以学生的 EMA 作为教师(无须大教师)
ema_teacher = EMA(student, decay=0.999)
# 类平衡权重(从 train_loader 首批统计或预先统计)
all_labels = torch.cat([y for _, y in train_loader], dim=0)
cb_weight = class_balanced_weight(all_labels, num_classes=num_classes, beta=0.999).to(device)
criterion = SmoothCE(eps=0.1, weight=cb_weight) # Label Smoothing + 类平衡
optimizer = torch.optim.SGD(student.parameters(), lr=lr, momentum=0.9, weight_decay=wd, nesterov=True)
scheduler = build_warmup_cosine(optimizer, warmup_epochs=5, total_epochs=epochs)
best_acc, best_state = 0.0, None
for ep in range(epochs):
# 用上一轮 EMA 权重复制到一个“冻结教师”上做蒸馏
teacher_model = copy.deepcopy(student).to(device)
ema_teacher.apply_to(teacher_model) # teacher = EMA(student)
for p in teacher_model.parameters(): p.requires_grad_(False)
tr_loss = train_one_epoch(
student, train_loader, optimizer, ep, criterion, device,
teacher=teacher_model, kd_T=4.0, kd_alpha=0.6,
use_mixup=True, use_cutmix=False, grad_clip=1.0, ema=ema_teacher
)
scheduler.step()
val_acc = evaluate(student, val_loader, device, num_classes)
if val_acc > best_acc:
best_acc, best_state = val_acc, copy.deepcopy(student.state_dict())
print(f"Epoch {ep+1}/{epochs} | train_loss={tr_loss:.4f} | val_acc={val_acc:.4f}")
# 加载最佳权重并再套一次 EMA(提升泛化)
student.load_state_dict(best_state)
ema_teacher.apply_to(student)
return student, best_acc
- 以上主干可直接搬到你的项目里:无外部依赖(除数据加载外),能在小网络上稳定吃到一波“白给”的精度。
3) 怎么选与怎么调:给出“有数的”优先级与期望收益
- RandAugment + Mixup/CutMix + Label Smoothing:最先上,常见 +1%~+3% Top-1(小模型更明显)。
- Warmup+Cosine、合适的 weight_decay、梯度裁剪、SiLU/GELU:训练更稳,+0.5%~+1.5%。
- EMA 权重:几乎“白嫖”的提升,+0.3%~+1.0%。
- 类不平衡(Focal/类平衡权重):长尾分布下,目标类 F1/AUC 提升显著。
- 知识蒸馏(大教师/EMA 自蒸馏):常见 +1%~+4%(视教师质量/温度与 α)。
- SE/ECA 模块:参数上涨很小,特征选择更好,+0.2%~+1%。
- TTA:线上允许多次前向时,+0.2%~+0.5%。
注:收益取决于数据规模/噪声/不平衡程度;对极小模型(比如 <1M 参数),蒸馏与数据增广的边际收益更高。
4) 常见坑与对策
- Batch 太小 BN 不稳 → 用 GroupNorm/LayerNorm,或冻结 BN 的统计(eval BN)。
- 过度增广导致欠拟合 → 降低强度/概率;Mixup/CutMix 仅在中后期使用;或对难样本降低增广强度。
- 长尾数据下总体 Acc 上升但关键类掉点 → 使用类平衡损失/重采样 + 分层评估(macro-F1、per-class Acc)。
- 蒸馏不收敛 → 调高温度 T=4~8,减小 kd_alpha,保证教师精度显著高于学生或用 EMA 教师。
- 小网络欠表达 → 加 SE/ECA、适当加深而非加宽;替换激活为 SiLU/GELU。
- 复现实验 → 固定随机种子、控制数据顺序、记录所有超参;把“配方”写入配置文件便于 A/B。
5) 针对遥感/时空栅格(如果你的数据是格网/影像)
- 分块训练 + 重叠滑窗(训练/推理一致),边界 label smoothing 抑制边缘噪声。
- 多尺度训练/推理(TTA):短边缩放若干尺度后投票。
- 时序样本构造:用邻近时刻堆叠成多通道;或短序列→Transformer/LSTM 小头部。
- 类别不平衡:罕见地物/工况用 Focal/类平衡 + 目标挖矿(hard example mining)。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)