返回列表

10th Place: Single Model Using Snapshot Ensemble w/ code

363. Bengali.AI Handwritten Grapheme Classification | bengaliai-cv19

开始: 2019-12-19 结束: 2020-03-16 计算机视觉 数据算法赛
第10名:使用快照集成的单模型方案

第10名:使用快照集成的单模型方案(附代码)

作者: Tawara (Grandmaster) | 比赛: Bengali.AI Computer Vision Challenge

更新

我在本文末尾添加了额外的研究内容:

  • 关于数据增强的讨论链接
  • 关于 sSE Block 可视化的讨论和 Notebook 链接
  • 我的后期提交结果表格(包括不使用 RandomErasing、不使用 sSE Block、使用通用 sSE Block 以及使用 Chris's Magic 的结果)
  • GitHub 源代码仓库链接

当 Private Leaderboard(私有排行榜)揭晓时,我与其说是高兴,不如说是惊讶。我没想到会有如此大的排名变动。我仍然不明白为什么能获得这个名次(抱歉,因为我只有4天时间,没能做足够的实验),并希望通过后期提交来调查原因。

尽管仍有一些谜团,这是我第一个单人获得的金牌。我很高兴能作为金牌得主分享我的解决方案,并成为 Competitions Master!

最后,恭喜所有获得奖牌的团队和完成比赛的参赛者!感谢 Kaggle 和 Bengali.AI 举办这次比赛!

资源

Kaggle Notebooks 和一台本地机器 (GTX1080ti x 1)

方法

起初,为了解决未见过的字符问题,我通过多标签分层分组 K 折将训练数据分割,并尝试训练模型。然而,我无法成功训练模型。我怀疑这是因为某些组件只包含在一个或极少数字符中。

我的方法非常简单——使用所有训练数据训练一个模型(因为我想在训练中包含所有组件)。然而,这种方式有过拟合的风险。为了防止泛化性能下降,我使用余弦退火调度训练模型并进行快照集成。

没有特殊的预处理或后处理。

模型

该模型基于 SE-ResNext50,并不特别,但在全局池化步骤中有独特之处。下图是模型概览。

模型概览

我没有简单地将全局平均池化应用于特征图并将其结果用作每个组件头的通用输入,而是针对每个组件使用了 sSE Block 和全局平均池化。

如果您想了解有关 sSE Block 的更多详细信息,请阅读原始论文:

Concurrent Spatial and Channel Squeeze & Excitation in Fully Convolutional Networks (Abhijit Guha Roy, et al., MICCAI 2018)

注意:为了将单通道图像传递给预训练模型(3通道),我使用了一种简单的方法。有关更多详细信息,请参阅下方的评论。

训练

数据增强

按以下顺序应用增强,由 albumentations 实现:

[原始图像: 137x236]
-> Padding(至 140x245) -> Rotate(rotate limit=5, p=0.8)
-> Resize(至 128x224) -> RandomScale(scale limit=0.1, p=1.0)
-> Padding(至 146x256) -> RandomCrop(至 128x224, p=1.0)
-> RandomErasing(mask-ratio-min=0.02, mask-ratio-max=0.4, p=0.5)
-> Normalize(按训练数据的通道均值和标准差)
-> [模型输入: 128x224]

如您所见,我没有使用 CutMix/MixUp。

损失函数

计算每个组件的 softmax 交叉熵,并按权重(grapheme_root:vowel_diacritic:consonant_diacritic = 2 : 1 : 1)对它们进行平均。

优化

  • 优化器:SGD + NesterovAG(momentum: 0.9) with weight decay(1e-04)
  • Batch size: 64
  • Epoch: 105
  • 学习率调度:余弦退火 (3 cycle)
    • 每个 cycle 35 epoch