基於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

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