346. Severstal; Steel Defect Detection | severstal-steel-defect-detection
这一次,我试图更加有条理,而不是随机地从论文中挑选想法。在训练新模型之前,我花了更多时间思考和深入研究当前模型表现不佳的原因。加上运气,我终于拿到了我的第一块金牌。
我使用 albumentation 进行数据增强:
def aug_medium(prob=1):
return aug.Compose([
aug.Flip(),
aug.OneOf([
aug.CLAHE(clip_limit=2, p=.5),
aug.IAASharpen(p=.25),
], p=0.35),
aug.OneOf([
aug.RandomContrast(),
aug.RandomGamma(),
aug.RandomBrightness(),
], p=0.3),
aug.OneOf([
aug.ElasticTransform(alpha=120, sigma=120 * 0.05, alpha_affine=120 * 0.03),
aug.GridDistortion(),
aug.OpticalDistortion(distort_limit=2, shift_limit=0.5),
], p=0.3),
aug.ShiftScaleRotate(rotate_limit=12),
aug.OneOf([
aug.GaussNoise(p=.35),
SaltPepperNoise(level_limit=0.0002, p=.7),
aug.ISONoise(p=.7),
], p=.5),
aug.Cutout(num_holes=3, p=.25),
], p=prob)
然后,我从增强后的图像中裁剪出 256x512 的区域。请注意,许多图像包含大面积的黑色区域,并且图像的至少一端总是显示有钢材部分。简单的随机裁剪会降低训练效率,所以我采取了以下做法:
为了应对类别不平衡,我使用了平衡采样。我不喜欢以相同的概率随机选择缺陷类型(或无缺陷)的方法,这会让“Epoch”的概念变得随意。我更喜欢确定性的方法,所以在每个 epoch 中,我做了类似这样的操作:
0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 ...
直到每一个无缺陷样本(类别 0)都被采样过一次。
仅在训练集上训练的端到端分类 + 分割非对称 U-Net。
主干网络: se-resnext50 32x4d
解码器: CBAM 注意力机制和超列(hyper-columns)。我认为最后一个解码器(以及可能倒数第二个解码器中的上采样)有点多余,所以我移除了它。这样,我模型的输出步长变成了 2。这节省了大量的 GPU 显存。
我在 TGS Salt 竞赛中也使用了类似的设置。注意,与其他类别不同,我将所有图像都输入到了缺陷 3 的分支中,而不仅仅是包含缺陷 3 的图像。
与模型 1 相同,区别在于使用了 deep-stem 并将所有 ReLU 替换为 Mish。在训练集和公共测试集的伪标签上进行训练。