Skip to content

实验目标

  • 实现基于RNN的解码器模型
  • 实现基于Attention机制的解码器模型
  • 对比分析两种模型的性能差异
  • 探索模型优化方法

整体架构

两种模型均采用Encoder-Decoder架构:

  • Encoder: 使用预训练的ResNet-101网络提取图像特征
  • Decoder: 分别采用RNN和Attention机制生成文本描述

Encoder编码器

使用预训练的ResNet101作为编码器:

  • 移除最后的Pooling和全连接层
  • 使用AdaptiveAvgPool2d层得到14×14×2048的固定大小编码结果
  • 可选择是否对编码器进行微调

Decoder解码器

基础RNN解码器

  • 使用LSTMCell作为解码单元
  • 初始隐藏状态通过编码结果的全连接层和批归一化得到
  • 使用teacher forcing机制训练
  • 词汇嵌入维度:512,隐藏层维度:512

带Attention的RNN解码器

  • 引入Attention机制计算图像不同区域的权重
  • Attention维度:512,与解码器隐藏层维度相同
  • 每个时间步结合词嵌入和注意力加权的编码特征

实验设置

超参数设置

两种模型使用相同的训练配置:

  • 批量大小:32
  • 编码器学习率:1e-4(微调时使用)
  • 解码器学习率:4e-4
  • 嵌入维度:512
  • 隐藏层维度:512
  • Dropout:0.5
  • 梯度裁剪:5.0
  • 训练轮次:10
  • 早停机制:连续3轮无改进停止训练
  • 混合精度训练:启用
  • 梯度累积步数:2 主要是引用早停机制,因为时间关系,就不在增加就停止了,还有就是启用混合精度训练,减少显存占用,同时用梯度累积,模拟更大batch size训练,线程数也增加了到4 其他就日志频率调整

早停机制

python
# 实现逻辑
if cfg['epochs_since_improvement'] >= 3:  # 实际使用3而不是5
    print(f"早停:连续 {cfg['epochs_since_improvement']} 个轮次无改进")
    break

实际效果在Attention模型在第8轮触发早停(连续3轮无改进)

混合精度训练

python
# 混合精度训练实现
scaler = GradScaler()
with torch.amp.autocast(device_type='cuda', dtype=torch.float16):
    # 前向传播计算
    loss = criterion(scores_packed, targets_packed)

主要目的是训练加速:利用Tensor Core进行快速矩阵运算

梯度累积

python
# 梯度累积实现
loss = loss / accumulation_steps  # 梯度缩放
loss.backward()

if (i + 1) % accumulation_steps == 0:
    # 每accumulation_steps步更新一次权重
    optimizer.step()
    optimizer.zero_grad()

作用:

  • 模拟大batch训练:在显存有限的情况下实现等效batch_size=64的训练
  • 梯度更稳定:累积多个小batch的梯度,减少随机性

训练过程

基础RNN模型训练

  • 准确率: Top-5准确率达到77-78%
  • 训练稳定性:损失稳步下降,无明显波动
  • LOSS - 2.349, TOP-5 ACCURACY - 75.330, BLEU-4 - 0.022018895203058088

Attention模型训练

  • 收敛速度:相比基础RNN稍慢
  • 准确率: Top-5准确率约73-74%
  • LOSS - 3.325, TOP-5 ACCURACY - 74.578, BLEU-4 - 0.021177244287433863

知识如风,常伴吾身