基于PyTorch工程利器解析遥感影像分类任务,小白必看!

本赛题共有45个类别,涉及多分类问题。必定会存在样本不平衡问题。

 

核心思路

数据预处理:每个类别的样本个数不一样,故采用Imbalanced Dataset Sampler调整每个类别的权重最后使得整个样本群每个类别平衡。

以下是 Label Smoothing 的代码:

class ImbalancedDatasetSampler(torch.utils.data.sampler.Sampler):
ㅤdef __init__(self, dataset, indices=None, num_samples=None):
ㅤㅤㅤself.indices = list(range(len(dataset)))
ㅤㅤㅤㅤㅤif indices is None else indices
ㅤㅤㅤself.num_samples = len(self.indices)
ㅤㅤㅤㅤㅤif num_samples is None else num_samples

  # distribution of classes in the dataset
ㅤㅤㅤlabel_to_count = {}
ㅤㅤㅤfor idx in self.indices:
ㅤㅤㅤㅤㅤtry:
ㅤㅤㅤㅤㅤㅤㅤlabel = self._get_label(dataset, idx)
ㅤㅤㅤㅤㅤㅤㅤif label in label_to_count:
ㅤㅤㅤㅤㅤㅤㅤㅤlabel_to_count[label] += 1
ㅤㅤㅤㅤㅤㅤㅤelse:
ㅤㅤㅤㅤㅤㅤㅤㅤlabel_to_count[label] = 1
ㅤㅤㅤㅤㅤexcept:
ㅤㅤㅤㅤㅤㅤㅤpass
ㅤ
ㅤㅤㅤ# weight for each sample
ㅤㅤㅤweights = [1.0 / label_to_count[self._get_label(dataset, idx)]
ㅤㅤㅤㅤㅤㅤㅤㅤㅤfor idx in self.indices]
ㅤㅤㅤself.weights = torch.DoubleTensor(weights)
ㅤ
ㅤdef _get_label(self, dataset, idx):
ㅤㅤㅤdataset_type = type(dataset)
ㅤㅤㅤif dataset_type is torchvision.datasets.MNIST:
ㅤㅤㅤㅤㅤreturn dataset.train_labels[idx].item()
ㅤㅤㅤelif dataset_type is torchvision.datasets.ImageFolder:
ㅤㅤㅤㅤㅤreturn dataset.imgs[idx][1]
ㅤㅤㅤelse:
ㅤㅤㅤㅤㅤreturn np.argmax(dataset.labels[idx])
ㅤ
ㅤdef __iter__(self):
ㅤㅤㅤreturn (self.indices[i] for i in torch.multinomial(
ㅤㅤㅤㅤㅤself.weights, self.num_samples, replacement=True))
ㅤ
ㅤdef __len__(self):
ㅤㅤㅤreturn self.num_samples

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

模型选择:senet154,够强大的Baseline

模型优化:

  • Loss:基于CrossEntropy进行Label Smooth操作
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):
ㅤㅤㅤlog_probs = self.logsoftmax(inputs)
ㅤㅤㅤ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
  • Learning Rate:warm up

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

 

比赛经验总结

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

本文为作者在FlyAI平台发布的原创内容,采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,转载请附上原文出处链接和本声明。
本文链接地址:https://www.flyai.com/n/51410

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章