实验目标
- 实现基于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
