FlyAI-遥感影像场景分类预测经验总结

文章目录

    • 数据介绍
    • 经验1. 准确率92.55%:SENet、PyTorch
      • (1)数据预处理:加权采样
      • (2)数据增强:采用随机裁剪,随机旋转,随机翻转,随机擦除
      • (3)模型选择:Senet154
      • (4)模型优化:标签平滑、学习率热身
      • (5)模型集成
    • 经验2. 准确率93.12%:DenseNet,Keras
      • (1)预处理-最大最小缩放中心化
      • (2)模型选择方面-预训练DenseNet
      • (3)数据增强-Flip,Rotate,Zoom
      • (4)损失函数-标签平滑技术
      • (5)Adam,Warmup Scheduler
    • 经验3. 准确率92.27%,DenseNet,PyTorch
      • (1)用余弦退火算法学习率
      • (2)随机裁剪和随机遮挡
      • (3)TTA 测试时数据增强
      • (4)个别类单独训练
    • 经验4. 准确率92.66:EfficientNet,PyTorch
      • (1)数据增强效果不好
      • (2)尽量使用预训练模型
      • (3)优化
      • (4)集成:翻转预测
    • 经验5. 准确率91.35:DenseNet,Keras
      • (1)添加底层特征
      • (2)random eraser
      • (3)adam + warmup learning rate
      • (4)测试时增强

数据介绍

遥感影像场景分类是遥感影像目标检测和高层语义理解的基础,遥感影像高层语义理解又是空间分析的基础。实际应用中空间分析借助地图与空间信息解决经济、社会、国防等重要领域的技术任务。
FlyAI-遥感影像场景分类预测经验总结_第1张图片
FlyAI-遥感影像场景分类预测经验总结_第2张图片

经验1. 准确率92.55%:SENet、PyTorch

(原文)
Batch大小为30,循环次数为10次,损失函数优化完,最终完成评分为92.55。
本赛题共有45个类别,涉及多分类问题。必定会存在样本不平衡问题。
【核心思路】

(1)数据预处理:加权采样

每个类别的样本个数不一样,故采用Imbalanced Dataset Sampler调整每个类别的权重最后使得整个样本群每个类别平衡。
原理主要是多的少采样,少的多采样。github有基于mnist的使用案例:Imbalanced Dataset Sampler

(2)数据增强:采用随机裁剪,随机旋转,随机翻转,随机擦除

(3)模型选择:Senet154

够强大的Baseline

(4)模型优化:标签平滑、学习率热身

ㅤ(1)Loss
基于CrossEntropy进行Label Smooth操作:
在这里插入图片描述
原理见:SoftMax原理介绍 及其 LabelSmooth优化

class CrossEntropyLabelSmooth(nn.Module):def __init__(self, num_classes, epsilon=0.1, use_gpu=True):
ㅤㅤㅤsuper(CrossEntropyLabelSmooth, self).__init__()
ㅤㅤㅤself.num_classes = num_classes
ㅤㅤㅤself.epsilon = epsilon
ㅤㅤㅤself.use_gpu = use_gpu
ㅤㅤㅤself.logsoftmax = nn.LogSoftmax(dim=1)def forward(self, inputs, targets):
  # inputs:[N,CLASS]  Targets[N,class]
ㅤㅤㅤlog_probs = self.logsoftmax(inputs) # 计算概率 [N,class]
	  # 把标签变成成one-hot编码,1表示按列填充
ㅤㅤㅤtargets = torch.zeros(log_probs.size()).scatter_(1,targets.unsqueeze(1).data.cpu(), 1)
ㅤㅤㅤif self.use_gpu: targets = targets.cuda()
ㅤㅤㅤtargets = (1 - self.epsilon) * targets + self.epsilon / self.num_classes
ㅤㅤㅤloss = (- targets * log_probs).mean(0).sum()
ㅤㅤㅤreturn loss

这里的scatter_函数:scatter_(input, dim, index, src)将src中数据根据index中的索引按照dim的方向填进input中。

此处按列填充,LongTensor中的index=2对应zeros(2, 4)(0,2)位置。相当于第3列和第四列。
>>> z = torch.zeros(2, 4).scatter_(1, torch.LongTensor([[2], [3]]), 1.23)
>>> z
 0.0000  0.0000  1.2300  0.0000
 0.0000  0.0000  0.0000  1.2300
[torch.FloatTensor of size 2x4]

ㅤ(2)Learning Rate:warm up
可参考:TensorFlow中的学习率“热身”

(5)模型集成

没采用此方法,单模型单尺度测试得到的结果

1、多看知乎上面的大佬分享,多动手多实践。多看论文,多关注一些最新的主流方法,其实通用的Trick就那么多,比如看到目标检测的Trick其实很多时候都可以用在分割或者识别上,很多任务都是共通的。
2、采用最强大Baseline进行网络训练才可以取得更高的分数。打比赛的时候先把Baseline设置好,再进行添砖加瓦,把一些骚操作用起来。
3、Warm Up 能涨一个点,Label Smooth 能涨一个点, Imbalanced Dataset Sampler能涨一个点,随机擦除能涨一个点。对这些Trick要铭记于心,不管在什么任务上都可以用的。
4、Triplet Loss在图像分类上也有不容忽视的作用,因为时间关系没有加上,之后大家也可以试试。

经验2. 准确率93.12%:DenseNet,Keras

(原文)
Batch大小为24,循环次数为30次,损失函数优化完,最终完成评分为93.12。
【赛题难点分析】
1、赛题选取的数据量和尺寸较大,训练集达到80000多,测试集未知,图片分辨率不一,平均在512*512左右,且比赛平台并没有公开数据来源,无法构造完全等价的线下测试环境,同时,选择何种图片采样手段、分辨率没有先验标准,需要耐心的设计实验去选取。因此每一个版本的训练时间较长,平均在10-20小时左右才能看出显著的效果,需要耐心和一定的经验;

2、类别45个,比赛评价指标为每类F1的平均值(macro avg),理论上类别越多难度越大,可能需要关注样本是否存在不平衡的现象,或者不同类别的分类难度是否存在较大的差异;

3、另外,从示例图片观察,某些场景可能还存在二义性、混淆,甚至疑似错误标注,数据质量相比其他遥感数据有一定差别;

4、场景分类可能是细粒度、粗粒度兼有的一种分类问题,轮廓、纹理、对象分布可能都跟分类有关,具体选取那种Backbone,从已有的文献和开源项目看,没有一个统一的标准,所以还得暴力去试。

总之,该题的挑战就是,每一次调参周期长,数据质量分布不一致容易过拟合,要在有限的时间、积分条件下尽可能找到一个较好的网络架构、学习率、优化器、批次和迭代次数大小的组合。
【核心思路】

(1)预处理-最大最小缩放中心化

因为没有均值和标准差的信息,同时该数据集与ImageNet有一定差别,所以直接用最大最小缩放中心化来处理,图片大小选取了224、256、320、384四种组合进行测试。

(2)模型选择方面-预训练DenseNet

由于平台特性和限制,分别试验了DenseNet、ResNet、Inception v3、Inception ResNet v2进行比较。同时也发现,尽管样本多达80000,但从头训练还不足以提取和学习到足够的特征,因此一律采用预训练权重。

(3)数据增强-Flip,Rotate,Zoom

为了缓解过拟合,综合运用了Flip,Rotate,Zoom等手段,这个环节主要通过线下调参得到,不一定是最优的增强策略。

(4)损失函数-标签平滑技术

(5)Adam,Warmup Scheduler

经验3. 准确率92.27%,DenseNet,PyTorch

原文
使用DenseNet作为训练模型,训练速度快且效果好。

(1)用余弦退火算法学习率

分阶段训练,更好地进行微调,并采用余弦退火算法对学习率进行调整,加快Loss收敛。

(2)随机裁剪和随机遮挡

数据增强使用随机裁剪和随机遮挡,未添加更多的数据增强操作,可以调整亮度,高斯模糊等基础操作,添加之后进行调整效果更好。

图片大小为节省时间使用的是224,提高图片分辨率大小可以提升效果,但相应的Batch Size要减小,训练时间就变得更长了。

(3)TTA 测试时数据增强

测试时直接预测,未使用TTA,进行测试增强可以提升效果,如将图片进行翻转,裁剪等操作之后进行预测,平均多次操作之后的综合结果。

(4)个别类单独训练

代码中内置混淆矩阵显示,可以观察分类错误的类别信息,抽取出来进行单独分类再融合进结果中,提高个别容易出错的类别的准确率,在比赛中发现桥和立交桥这两个类别准备率较低,可以单独进行分类在进行融合,但时间关系就没有提交新的结果。

经验4. 准确率92.66:EfficientNet,PyTorch

原文
赛题分析
1、该题属于常规的图像分类问题,图像为遥感图像,类别为45类包含沙滩、生活区、直升机场等,此任务是实现复杂场景快速自动识别的基础,在军事、救灾等领域有十分重要的意义。
2、图像视角都为俯视图,所以纹理信息与颜色信息很重要,数据增强需要在这两点上做文章;
3、数据量中等,故不需要太大的网络也可以在一定程度上拟合数据集。
难点解析:
此赛题难点在于部分图像类别之间差异很小,比如立交桥与桥梁,由于只有100张可见图像,猜测很多类别的图片在一定程度上有交叉,神经网络不易分辨这些图片。由于使用卷积神经网络,其良好的分类精度往往是依赖于大量的训练数据,而在此类中等大小数据集上过长的训练时间容易出现过拟合问题。
核心思路

(1)数据增强效果不好

正常的随机剪裁与翻转,Padding和随机亮度灰度试过,估计改变了原有的结构和颜色,故效果不佳;

(2)尽量使用预训练模型

线上比赛使用ImageNet预训练模型是必须的,低层特征已经训得差不多了,加快了收敛,节约了FAI。由于难点在于细腻度分类,所以模型适当选择在细腻度上表现比较好的。最终选择了两个: ResNext101和EfficieNet。采用的两个Net的最终表现其实相差不大±0.2%左右。对于此类型数据可能有更好的方法;

(3)优化

由于跑一次时间较久,FAI消耗巨大,所以用Adam,要使用Weight Decay 就用AdamW,Weight Decay是放在正则项前面的一个系数,正则项一般指示模型的复杂度,所以Weight Decay的作用是调节模型复杂度对损失函数的影响,防止过拟合,AdamW就是PyTorch Adam的改良版;FAI多就用SGD可能效果更好;

(4)集成:翻转预测

经验5. 准确率91.35:DenseNet,Keras

原文
Batch大小为64,循环次数为20次,损失函数优化完,最终完成评分为91.35。

(1)添加底层特征

通过观察本地图片发现停车场和路边停车场等类别比较接近,更多的是细节上的差异。
因此对DenseNet121网络结构进行调整,添加了更多底层特征。

(2)random eraser

(3)adam + warmup learning rate

(4)测试时增强

在评估预测的时候,对测试集进行了增强,并对所有预测结果取均值。

你可能感兴趣的:(cv)