目标分类与tricks
- Image Classification on ImageNet [url]
过拟合解决方法
- simpler model structure
- regularization
- data augmentation
- dropout
- Bootstrap/Bagging
- ensemble
- early stopping
- utilize invariance
- Bayesian
数据增强
-
AutoAugment - Learning Augmentation Policies from Data [github]
-
Progressive Input size: 128 -> 192 -> 224
-
Mixup
-
Cutmix [github pytorch]
-
Fmix [paper]
高级API
-
PyTorch-Lightning [github]
-
NVIDIA-apex [github]
Training Data -> DALI (Decode | Resize | Augment) -> PytTorch
-
NVIDIA-dali 图像预处理 [github]
模型训练
学习率和优化器
-
Scheduling : LearningRate Warm-up + Cosine Decay
-
Adam:** i n i t _ l r = 5 e − 4 ( 3 e − 4 ) init\_lr=5e-4(3e-4) init_lr=5e−4(3e−4)(⭐︎⭐︎⭐︎⭐︎⭐︎),3e-4号称是Adam最好的初始学习率,有理有据,请看下图;SGD就更考验调参功力,这里就不详说(因为我也一般般)。
-
ReduceLROnPlateau,patience=4(5),gamma=0.1,这是我常用的一套组合,并不是最好的;
StepLR,个人比较喜欢用这个,自己设定好在哪个epoch进行学习率的衰减,个人比较喜欢用的衰减步骤是 [ 5 e − 4 ( 3 e − 4 ) , 1 e − 4 , 1 e − 5 , 1 e − 6 ] [5e-4(3e-4), 1e-4, 1e-5, 1e-6] [5e−4(3e−4),1e−4,1e−5,1e−6],至于衰减位置,就需要自己有比较好的直觉,或者就是看log调参,对着2.1上训练的valid loss走势,valid loss不收敛了,咱就立刻进行衰减;
CosineAnnealingLR+Multi cycle,这个相较于前两个,就不需要太多的调参,可以训练多个cycle,模型可以找到更多的局部最优,一般推荐min_lr=1e-6,至于每个cycle多少epoch这个就说不准了,不同数据不太一样。
-
Zero- γ \gamma γ
-
No-bias-decay [code]
-
Grid-Search [code]
模型处理
-
finetune**,微调也是有许多比较fancy的技巧,在这里不做优劣比较,针对分类任务说明。
微调方式一,最常用,只替换掉最后一层fc layer,改成本任务里训练集的类别数目,然后不做其余特殊处理,直接开始训练;
微调方式二,在微调一的基础上,freeze backbone的参数,只更新(预训练)新的fc layer的参数(更新的参数量少,训练更快)到收敛为止,之后再放开所有层的参数,再一起训练;
微调方式三,在微调方式二预训练fc layer之后或者直接就是微调方式一,可选择接上差分学习率(discriminative learning rates)即更新backbone参数和新fc layer的参数所使用的学习率是不一致的,一般可选择差异10倍,理由是backbone的参数是基于imagenet训练的,参数足够优秀同时泛化性也会更好,所以是希望得到微调即可,不需要太大的变化。
optimizer = torch.optim.Adam([{'params': model.backbone.parameters(), 'lr': 3e-5},
{'params': model.fc.parameters(), 'lr': 3e-4}, ])
微调方式四,freeze浅层,训练深层(如可以不更新resnet前两个resnet block的参数,只更新其余的参数,一样是为了增强泛化,减少过拟合)。
损失函数
-
topk-loss(OHEM) [example]
OHEM最初是在目标检测上提出来的,但其实思想是所有领域任务都通用的。意思就是提取当前batch里top k大的loss的均值作为当前batch的loss,进行梯度的计算和回传。其insight也很简单,就是一中hard mining的方法,一个batch里会有easy sample和hard sample,easy sample对网络的更新作用较小(loss值小,梯度也会小),而hard sample的作用会更大(loss值大,梯度值也会大),所以topk-loss就是提取hard sample。
loss = criterion(logits, truth)
loss,_ = loss.topk(k=..)
loss = loss.mean()
-
weighted loss
weighted loss其实也算是一种hard mining的方法,只不过这种是人为地认为哪种类别样本更加hard,哪种类别样本更加easy。也就是说人为对不同类别的loss进行进行一个权重的设置,比如0,1类更难,设置权重为1.2,2类更容易,设置权重为0.8。
-
Focal Loss
import torch import torch.nn as nn import torch.nn.functional as F from torch.autograd import Variable class FocalLoss(nn.Module): def __init__(self, alpha=1, gamma=2, logits=True, reduce=True): super(FocalLoss, self).__init__() self.alpha = alpha self.gamma = gamma self.logits = logits self.reduce = reduce def forward(self, inputs, targets): if self.logits: BCE_loss = F.cross_entropy(inputs, targets, reduce=None) else: BCE_loss = F.binary_cross_entropy(inputs, targets, reduce=None) pt = torch.exp(-BCE_loss) F_loss = self.alpha * (1-pt)**self.gamma * BCE_loss if self.reduce: return torch.mean(F_loss) else: return torch.sum(F_loss)
Model Tweaks
-
Channel Attention
Squeeze and Excitation
Selective Kernel
-
Anti-Alias Downsampling (AA)
Regulization
- DropBlock [github pytorch]
- AutoAug
- Knowledge Distill [github]
测试技巧
-
TTA [TTA PyTorch] [github pytorch]
一种暴力测试的方法,将有效的增强方式得到多个不同的input,然后进行infer,得到多个结果进行融合,一般会比原始input会高不少。这种方法的缘由就是希望通过对input进行不同的变换方式获取多个不同的但重要的特征,然后可以得到多个具有差异性的预测结果
-
Ensemble
Snapshot Ensembles,这个方法常在与cycle learning rate的情况下使用,在不同cycle下,模型会产出多个不同的snapshot weight(多个不同的局部最优,具有差异性),这时可以将这几个snapshot model一起进行推断,然后将预测结果进行平均融合。
SWA, Stochastic Weight Averaging,随机权重平均,其实现原理当模型在训练时收敛到一定程度后,开始追踪每次epoch后得到的模型的平均值,有一个计算公式和当前的模型权重做一个平均得到一个最终的权重,提高泛化性能。
stacking,在分类任务里,stacking是作为一种2nd level的ensemble方法,将多个“准而不同”的基分类器的预测集成与一身,再扔进去一个简单的分类器(mlp、logit regression、simple cnn,xgboost等)让其自己学习怎么将多个模型融合的收益做到最高。一般数据没有问题的话,stacking会更加稳定,不易过拟合,融合的收益也会更高。
-
Validation
Stratified Group-K cross validation [github] [Pytorch-Skorch]
nested cross validation [blog]
Ensemble
Example
一、Bags of tricks for Classification [code pytorch]
1. Baseline
训练的时候:
-
将图片转为32-bit float类型,像素值规范为[0,255] ;
-
随机crop出一个长宽比为[3/4,4/3]范围的矩形区域,面积的范围是[8%,100%], 然后resize得到的crop区域到224x224;
-
以0.5的概率Filp horizontally;
-
色彩,饱和度,亮度的范围是[0,6-1.4]
-
增加PCA噪声,
-
Normalize RGB channels by subtracting 123.68, 116.779, 103.939 and dividing by 58.393, 57.12, 57.375, respectively.
在测试的时候 :
-
在保持长宽比的情况下,将图片短边resize到256;
-
crop出一个224*224 范围的图像
-
RGB Normalize
网络初始化:
-
Xavier algorithm
-
Nesterov Accelerated Gradient(NAG) Descent
-
学习率初始化为0.1 ivided by 10 at the 30th, 60th, and 90th epochs.
-
训练120 epoch,batch_size=256
2. Efficient Training
Large Batch Training
-
Linear scaling learning rate
batch size为256的时候,initial lr 为0.1
随着batch size的变化, initial lr 为 0.1 ∗ b / 256 0.1 * b/256 0.1∗b/256
-
Learning rate warmup
The initial learning rate is η, then at batch i, 1 ≤ i ≤ m, we will set the learning rate to be iη=m.
-
Zero γ \gamma γ
将BN层的 γ \gamma γ 的值初始化为0
-
No Bias Decay
在对网络模型做Decay的时候,只对卷积层和全连接蹭的权重做Decay,而不对bias做decay
Low-precision Training
- 将FP32转化为FP16进行训练
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FXzylanK-1586052313940)(./images/train.png)]
3. Model Tweeks
4. Training Refinements
- Cosine Learning Rate Decay
- Label Smoothing
- Knowledge Distillation
- Mixup Training
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sRG4X1vB-1586052313943)(./images/refine.png)]
二、Identify Wildlife
Preprocess data
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J6y7teq1-1586052313944)(./images/preprocess.PNG)]
Final Solutions
- models: swsl_resnext50, wsl_resnext101d8
- scheduler(Default): WarmUp, CosineDecay, initLR 0.005
- Optimizer(default): SGD, WD 0.0001
- loss/Metrics: torch.nn.MultiLabelSoftMarginLoss
- Batch: 256 per GPU
- Augmentations: ColorJitter, Mirror
- Progressive input size: 256, 320, 480
- Averaging: gmean
总结
热爱比赛,热爱生活
ref
-
你有哪些deep learning(rnn、cnn)调参的经验? [zhihu]
-
Bags of tricks for Classification with Convolutional Neural Networks [paper] [stoa implement] [github]
-
Compounding the Performance Improvements of Assembled Techniques in a Convolutional Neural Network [paper] [github TF]