本科生晉升GM記錄: Kaggle比賽進階技巧分享

​                                                             點擊上方“邁微電子研發社”,選擇“星標★”公衆號

                                                                               重磅乾貨,第一時間送達                                        

 

本文轉自「知乎」Gary,編輯整理而發

作者:Gary

知乎鏈接:https://zhuanlan.zhihu.com/p/93806755

 

作者的Kaggle profile

                          https://www.kaggle.com/garybios

rank: 60/125547

 

 

Phase 1

去年9月中的時候,剛上大四不久,之前一直對熱衷於DL的我,其實都只是在自學看書,學習一些理論知識,但動手實踐非常少,框架也只是會一些Tensorflow/Keras/sklearn之類的。某一天無意只是想查一些項目的開源code,自己對着學習一下,就查到了kaggle,之前在kaggle也是有賬號的,但只是爲了下載Dog vs Cat的數據。

 

當時入坑的是TGS Salt Identification,一開始只能嘗試着用keras去把開源kernel的代碼跑一下,最後發現自己連改Unet換backbone都不會(之前都是白學了),就死皮賴臉的在討論區發帖/水貼(參加過這個比賽的老師估計對我當時都有點印象),但幸運的是得到了許多非常熱心的回答。

 

慢慢地,對LB上分上了癮。從一點都不會用pytorch到學會用pytorch魔改Unet模型,自己一路上分到top20,真的是非常刺激。GPU機器都是自己花在校生活費在vast.ai上租的單卡1080ti。

 

有了第一次在TGS獲取的top2%銀牌,開始在一些老師腦海中留下了些印象,到了第二個比賽Doodle Recognition Challenge,當時就和杜老師在知乎上認識了,並且和吳老師也一起組上了隊伍。

 

當然,當時的我還是對很多都非常不懂的,只是在隊伍裏打打下手。拿下第二個銀牌升級爲Expert title後,進入了華人Kagglers大羣(當時expert是進羣門檻,現在已經是master了),裏面全是GM/Master/Expert大神,在羣裏向各位老師學習。

 

後面寒假實習面試(鵝廠),遇到了Chen Joya師兄,雖然當時不match實習崗位,但是師兄挺欣賞我(師兄真的非常非常好人,感謝),私下給我提供4 * p40+4 * v100和我一起打比賽。

 

這個時候就是在Human Protein Atlas Image Classification和action(國內第一位本科應屆生Grand Master)他們一起打了,拿下第一枚金牌,我們的solution: kaggle Human Protein Atlas 比賽總結:https://zhuanlan.zhihu.com/p/54743461

 

Phase 2

自己當時完全想不到自己有機會拿下金牌和Master title,在比賽裏也認識到了濤哥(史上最快晉升GM的男人),楊老師等。在此階段,和濤哥/action他們繼續組隊,或者和羣裏一些老師的討論,主要是吸收/學習他們身上的一些調參和對數據的理解的經驗。同時,自己也在相關崗位實習,做research,每天更是閱讀許多論文,自己的能力在此階段成長了許多。也在此階段拿下了兩塊金牌,不過時間不等人,這個時候我剛好大學畢業了。

 

Phase 3

當覺得自己學習到一個程度,認爲自己能夠獨當一面,可獨立解決大部分問題的時候,這時我選擇了solo,但發現solo確實是比組隊辛苦很多的,無隊友討論,需要自己去挖掘idea等等。幸運的是,在此階段拿下了一枚solo金和一枚team金,成功在一年後晉升自己以前想都不敢想的Grand Master。

 

分享初衷

  1. 鑑於國內競賽的討論氛圍確實是非常的糟糕,同時不少小夥伴的英語閱讀能力並非那麼好,在kaggle經常閱讀不太懂許多solution,或者不知道如何去使用kaggle,如何在這個平臺上進行學習。

     

  2. 然後,希望能夠分享自己在此期間學習到的一些皮毛知識給大家,讓更多的小白能夠很好的入門,也能拿到一枚金牌,回饋給社區。

 

經驗分享

1. 以下所有的一些方法,都是一些top選手常用的,如果你使用得當,銀牌是非常穩的,然後自己再加把勁點,金牌都非常有機會的。可能不夠全面或者有錯誤的,希望各位小夥伴一起觀摩觀摩,如有補充的,麻煩留下評論,或者私信我,我修改補充上去。
2. 基本都是CV任務下的經驗,其它類型的任務可適當借鑑下。

常用框架

 

編程語言:python(⭐︎⭐︎⭐︎⭐︎⭐︎) 

 

煉丹框架:Pytorch(⭐︎⭐︎⭐︎⭐︎⭐︎)、Keras(⭐︎⭐︎⭐︎⭐︎)、Mxnet(⭐︎⭐︎⭐︎)、Tensorflow(⭐︎) 

 

必備框架:Apex(⭐︎⭐︎⭐︎⭐︎⭐︎)、Numpy、Opencv、PIL、Scikit-learn、albumentations、imgaug等

1. 個人看來,Pytorch的易用性其實是已經超越了另外幾個框架,搭建/魔改模型都非常方便;

2. Apex可以讓你只寫幾行代碼,就可以輕鬆使用float16或者混合精度來訓練模型,顯存減少將近一半的情況下,訓練速度也得到大幅度提升。

3. 自寫數據增強庫,推薦使用Opencv;如果是封裝好的數據增強庫,推薦albumentations或imgaug(或torchvison.transforms),基本想得到的transform方式都包含。

 

apex使用實例

from apex import amp
import apex
...

model = resnet18()
optimizer = Adam(....)
model, optimizer = amp.initialize(model, optimizer, opt_level="O1", verbosity=0)
...
logits = model(inputs)
train_loss = criterion(logits, truth)
with amp.scale_loss(train_loss, optimizer) as scaled_loss:
    scaled_loss.backward()
optimizer.step()

 

實驗pipeline(baseline)

 

  1. 建議baseline模型從resnet18/34 or efficientnet-B0,小模型迭代快,實驗進程也可以快速推進;

     

  2. Adam優化器,SGD(可選,但是SGD沒有Adam那麼好調,所以baseline可以不選,後面細緻調參的時候再轉SGD也行。);

     

  3. loss function: 多分類(cross entropy),多標籤分類(binary cross entropy),語義分割(binary cross entropy,如果是多類語義分割,可選cross entropy);

     

  4. metric: 這個就有點難度,一般根據比賽評測指標來選擇;

     

  5. 數據增強:可以爲空,因爲是baseline,需要數據增強後面是可以逐漸試錯找到有效的再添加上去。

 

如何提升搭建baseline的能力

對於參賽者而言,往往具有一個好的baseline,或有着一套屬於自己風格的pipeline,其實是已經成功了一半。好的baseline等價於一個好的起點,後面的改進遇到的阻礙相對也會少非常多。但是,要把baseline寫好,其實是需要不少場比賽下來的經驗或者是已經有過相關項目的工作經驗。
  1. 對於初學者,每場比賽,都會有許多kagglers將自己的baseline開源到kernel上,你所要做的是,不是直接copy,而是去學習,從多個kernel中取出其比較精妙的部分,再組合成自己的baseline;

     

  2. 在以前相關類型的比賽裏,模仿top solution codes,整理出一個baseline。

     

  3. 多次實踐下來,你基本掌握了自己動手寫baseline的能力。

 

調參技巧

調參是比賽環節裏最重要的一步(日常工作也都是一樣離不開調參的),好的learning rate和learning rate schedule對比不合適的,得到的結果也是千差萬別,optimizer的選取或許多比較fancy的finetune技巧也是類似的結果。
 

1.Adam: init_lr=5e-4(3e-4)(⭐︎⭐︎⭐︎⭐︎⭐︎),3e-4號稱是Adam最好的初始學習率,有理有據,請看下圖;SGD就更考驗調參功力,這裏就不詳說(因爲我也一般般)。

 

 

2. lr schedule

  • ReduceLROnPlateau,patience=4(5),gamma=0.1,這是我常用的一套組合,並不是最好的;

 

  • StepLR,個人比較喜歡用這個,自己設定好在哪個epoch進行學習率的衰減,個人比較喜歡用的衰減步驟是[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這個就說不準了,不同數據不太一樣。

 

3.  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的參數,只更新其餘的參數,一樣是爲了增強泛化,減少過擬合)。

 

 

4.  Find the best init_lr,前面說到3e-4在Adam是較優的init_lr,那麼如何尋找最好的init_lr?

 

  • 出自fastai, lr_find(),其原理就是選取loss function仍在明顯降低的較大的學習速率,優劣性其實也是相對而言,不一定都是最好的。

 

5. learning rate warmup,理論解釋可以參 zhihu.com/question/3380

 

6. 如果模型太大的同時你的GPU顯存又不夠大,那麼設置的batch size就會太小,如何在有限的資源裏提升多一點?

 

  • 梯度累計(gradient accumulation),其實就是積累多個batch的梯度之後,再進行梯度的回傳做參數的更新,變相的增大了訓練的batch size,但缺點是對Batch Normalization沒影響的。

 

  • 如果你卡多,這時可以使用多卡並行訓練,但要使用syncbn(跨卡同步bn),即增大了batch size,又對Batch Normalization起到相同的作用。

 

分類賽技巧

1. label smoothing

分類任務的標籤是one-hot形式,交叉熵會不斷地去擬合這個真實概率,在數據不夠充足的情況下擬合one-hot容易形成過擬合,因爲one-hot會鼓勵正確類別與所屬類別之間的差異性儘可能大,但其實有不少類別之間是極爲相似的。label smoothing的做法其實就是將hard label變成soft label。

 

2. top k-loss(OHEM)

 

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()

 

3. weighted loss

 

weighted loss其實也算是一種hard mining的方法,只不過這種是人爲地認爲哪種類別樣本更加hard,哪種類別樣本更加easy。也就是說人爲對不同類別的loss進行進行一個權重的設置,比如0,1類更難,設置權重爲1.2,2類更容易,設置權重爲0.8。

 

weights = [1.2, 1.2, 0.8]
class_weights = torch.FloatTensor(weights).to(device)
criterion = torch.nn.CrossEntropyLoss(weight=class_weights)

 

4. dual pooling

 

這種是在模型層進行改造的一種小trick了,常見的做法:global max/average pooling + fc layer,這裏試concat(global max-pooling, global average pooling) + fc layer,其實就是爲了豐富特徵層,max pooling更加關注重要的局部特徵,而average pooling試更加關注全局的特徵。不一定有效,我試過不少次,有效的次數比較少,但不少人喜歡這樣用。

 

class res18(nn.Module):
    def __init__(self, num_classes):
        super(res18, self).__init__()
        self.base = resnet18(pretrained=True)
        self.feature = nn.Sequential(
            self.base.conv1,
            self.base.bn1,
            self.base.relu,
            self.base.maxpool,
            self.base.layer1,
            self.base.layer2,
            self.base.layer3,
            self.base.layer4
        )
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.max_pool = nn.AdaptiveMaxPool2d(1)
        self.reduce_layer = nn.Conv2d(1024, 512, 1)
        self.fc  = nn.Sequential(
            nn.Dropout(0.5),
            nn.Linear(512, num_classes)
            )
    def forward(self, x):
        bs = x.shape[0]
        x = self.feature(x)
        x1 = self.avg_pool(x).view(bs, -1)
        x2 = self.max_pool(x).view(bs, -1)
        x1 = self.avg_pool(x)
        x2 = self.max_pool(x)
        x = torch.cat([x1, x2], dim=1)
        x = self.reduce_layer(x).view(bs, -1)
        logits = self.fc(x)
        return logits

 

5. margin-based softmax

  • 在人臉識別領域,基於margin的softmax loss其實就是對softmax loss的一系列魔改(large margin softmax、NormFace、AM-softmax、CosFace、ArcFace等等),增加類間 margin,當然也有其它的特點,如weight norm和基於餘弦角度的優化等等。其共同目標都是爲了獲得一個更加具有區分度的feature,不易過擬合。

 

  • 一個比較多同學忽略的點是,如果使用了margin-based softmax,往往連同開源repo裏默認的超參數也一起使用了,比如s=32.0,m=0.5,但其實這兩個參數的設定都是有一定的緣由,比如s值象徵着超球體的體積,如果類別數較多,那麼s應該設置大點。如果你沒有很好的直覺,那grid search一波,搜索到適合的s和m值也不會花很多時間。

 

6. Lovasz loss

 

  • 這個loss本來是出於分割任務上的,其優化的是IOU,但你如果仔細觀察lovasz傳入的logit和truth,可以發現是和multi label classification類似,logit和truth都是由多個1值的one-hot形式。

 

  • 所以在多標籤分類任務上,其實是可以用lovasz loss來進行優化的,出自(Bestfitting)(kaggle.com/c/human-prot)

 

分類賽技巧(openset/檢索)

 

1. BNNeck(出自羅浩博士的Bag of Tricks and A Strong Baseline for Deep Person Re-identification ),鏈接https://zhuanlan.zhihu.com/p/61831669, 其實就是在feature層和fc layer之間增加一層Batch Normalization layer,然後在retrieval的時候,使用BN後的feature再做一個l2 norm,也就是retrieval with Cosine distance。

 

class res50(torch.nn.Module):
    def __init__(self, num_classes):
        super(res50, self).__init__()
        resnet = resnet50(pretrained=True)
        self.backbone = torch.nn.Sequential(
                        resnet.conv1,
                        resnet.bn1,
                        resnet.relu,
                        resnet.layer1,
                        resnet.layer2,
                        resnet.layer3,
                        resnet.layer4
        )
        self.pool = torch.nn.AdaptiveMaxPool2d(1)
        self.bnneck = nn.BatchNorm1d(2048)
        self.bnneck.bias.requires_grad_(False)  # no shift
        self.classifier = nn.Linear(2048, num_classes, bias=False)
    def forward(self, x):
        x = self.backbone(x)
        x = self.pool(x)
        feat = x.view(x.shape[0], -1)
        feat = self.bnneck(feat)
        if not self.training:
            return nn.functional.normalize(feat, dim=1, p=2)
        x = self.classifier(feat)
        return x

 

2. margin-based softmax(上面已經說到)

 

3. triplet loss + softmax loss,結合metric learning,對feature進行多個loss的優化,triplet loss也是可以有很多的花樣,Batch Hard Triplet Loss,是針對triplet loss的一種hard mining方法。

 

4. IBN,切換帶有IBN block的backbone,搜圖(open-set)往往test和train是不同場景下的數據,IBN block當初提出是爲了提高針對不同場景下的模型泛化性能,提升跨域(cross domain)能力,在reid下的實驗,IBN表現優異。

 

5. center loss

 

6. Gem,generalized mean pooling,出自Fine-tuning CNN Image Retrieval with No Human Annotation,提出的是一種可學習的pooling layer,可提高檢索性能,代碼出自 https://github.com/tuananh1007/CNN-Image-Retrieval-in-PyTorch/blob/master/cirtorch/layers/pooling.py

 

class GeM(nn.Module):
    def __init__(self, p=3, eps=1e-6):
        super(GeM,self).__init__()
        self.p = Parameter(torch.ones(1)*p)
        self.eps = eps
    def forward(self, x):
        return LF.gem(x, p=self.p, eps=self.eps)
    def __repr__(self):
        return self.__class__.__name__ + '(' + 'p=' + '{:.4f}'.format(self.p.data.tolist()[0]) + ', ' + 'eps=' + str(self.eps) + ')'

 

7. global feature + local features 

 

將全局特徵和多個局部特徵一起融合,其實就是一種暴力融合特徵的方法,對提升精度有一定的幫助,就是耗時相對只使用global feature來說很多點,此種方法可參考在reid常用的PCB(Beyond Part Models: Person Retrieval with Refined Part Pooling)或MGN(Learning Discriminative Features with Multiple Granularities for Person Re-Identification)方法

 

8. re-ranking,是一種在首次獲取檢索圖的候選圖裏做一次重新排序,獲得更加精準的檢索,相對比較耗時間,不適合現實場景,適合比賽刷精度。

 

 

分割賽技巧

1.Unet

Unet可以說是在kaggle的語義分割賽裏的一個較優的選擇,許多top solution都是使用了Unet,FPN也是一個非常不錯的選擇。

 

2.Unet的魔改

現在有個開源庫其實是已經集成了許多不同分割網絡,表現也是相對不錯的,如果覺得自己修改比較困難,或者自己改得不夠好,可以嘗試使用這個庫segmentation_models_pytorch

 

  • 很多top solution都是修改Unet的Decoder,最常見的就是增加scse block和Hypercolumn block,也有一些是使用了CBAM(Convolutional Block Attention Module,bestfitting比較喜歡用)或BAM(Bottleneck attention module),這些注意力block一般是放在decoder不同stage出來的feature後面,因爲注意力機制往往都是來優化feature的。

     

  • dual head(multi task learning),也就是構造一個end2end帶有分割與分類的模型。同時,多任務學習往往會降低模型過擬合的程度,並可以提升模型的性能。

出自蛙神-Heng CherKeng

import segmentation_models_pytorch as smp
class Res34_UNET(nn.Module):
    def __init__(self, num_classes):
        super(Res34_UNET, self).__init__()
        self.model = smp.Unet(encoder_name='resnet34', encoder_weights='imagenet', classes=num_classes, activation=None)
        self.avgpool = nn.AdaptiveAvgPool2d((1,1))
        self.cls_head = nn.Linear(512, num_classes, bias=False)

    def forward(self, x):
        global_features = self.model.encoder(x)
        cls_feature = global_features[0]
        cls_feature = self.avgpool(cls_feature)
        cls_feature = cls_feature.view(cls_feature.size(0), -1)
        cls_feature = self.cls_head(cls_feature)
        seg_feature = self.model.decoder(global_features)
        return seg_feature, cls_feature

 

3.  lovasz loss 

 

之前在TGS Salt Identification的適合,lovasz對分割的效果的表現真的是出類拔萃,相比bce或者dice等loss可以提高一個檔次。但是最近的分割賽這個loss的表現就一般,猜測是優化不同metric,然後不同loss就會帶來不同的效果,又或者是數據的問題。

 

4. dice loss for postive,bce loss for negtive 主要就是將分割任務劃分兩個任務:1. 分割任務,2. 分類任務 dice loss可以很好的優化模型的dice score,而bce loss訓練出來的分類器可以很好地找出negtive sample,兩者結合可以達到一種非常好效果,詳細解說可以參考我之前的一個solution: https://zhuanlan.zhihu.com/p/93198713

 

通用技巧

大部分都是犧牲推斷速度來提高精度的方法,適合比賽,不適合現實場景。

1. TTA(Test Time Augmentation) 

一種暴力測試的方法,將有效的增強方式得到多個不同的input,然後進行infer,得到多個結果進行融合,一般會比原始input會高不少。這種方法的緣由就是希望通過對input進行不同的變換方式獲取多個不同的但重要的特徵,然後可以得到多個具有差異性的預測結果。

 

2. 多尺度訓練,融合 

在訓練期間,隨機輸入多種尺度的圖像進行訓練,如(128128,196196,224224,256256,384*384等等)然後測試的時候可適當的選取其中某幾個尺度表現優異的預測結果出來融合,這種方法其實就是爲了提升模型對尺度的變換的魯棒性,不易受尺度變換的影響。

 

3. 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會更加穩定,不易過擬合,融合的收益也會更高。

 

4. 設計metric loss

許多小夥伴會有這樣一個疑惑,比賽的評測metric往往和自己訓練時所使用的loss優化方向不是那麼一致。比如多標籤分類裏的metric是fbeta_score,但訓練時是用了bce loss,經常可以看到val loss再收斂後會有一個反彈增大的過程,但此時val fbeta_score是還在繼續提升的。這時就可以針對metric來自行設計loss,比如fbeta loss就有。

 

5. semi-supervised learningrecurssive pseudo-label(僞標籤)

僞標籤現在已經是kaggle賽裏一個必備工具了,但是這是個非常危險的操作,如果沒有篩選好的僞標籤出來,容易造成模型過擬合僞標籤裏的許多噪聲。

 

比較安全的方法是:

  1. 篩選預測置信度高的樣本作爲僞標籤,如分類裏,再test裏的預測概率是大於0.9的,則視爲正確的預測,此時將其作爲僞標籤來使用。

  2. 幫第一次的僞標籤扔進去訓練集一起訓練後,得到新的模型,按相同的規則再次挑一次僞標籤出來。

  3. 如此不斷循環多次,置信度的閾值可以適當作調整。

 

  • mean teacher

from seutao

  • knowledge distillation(知識蒸餾),此方法有助於提高小模型(student)的性能,將大模型(teacher)的預測作爲soft label(用於學習teacher的模型信息)與truth(hard label)扔進去給小模型一起學習,當然兩個不同label的loss權重需要調一調。當然,蒸餾的方法有很多種,這只是其中一種最簡單的方法。蒸餾不一定用於訓練小模型,大模型之間也是可以一同使用的。

 

數據增強與預處理

數據增強往往都是調出來的,可以先在本地裏對圖像施加不同的變換方式,用肉眼觀察其是否有效(肉眼觀察和模型學習到的不一定對等),之後再扔進去網絡裏訓練驗證其是否有效。
  1. h/v flip(水平垂直翻轉),95%的情況下都是有效的,因爲不怎麼破壞圖像空間信息。

     

  2. random crop/center crop and resize,在原圖進行crop之後再resize到指定的尺度。模型的感受野有限,有時會看不到圖像中一些分佈比較邊緣或者是面積比較小的目標物體,crop過後其佔比有更大,模型看到的機會也會更多。適用性也是比較大的。

     

  3. random cutout/erasing(隨機擦除),其實就是爲了隨機擦除圖像中局部特徵,模型根據有限的特徵也可以判斷出其屬性,可提高模型的泛化性。

     

  4. AutoAugment,自己設定一些規則policy,讓模型自己尋找合適的數據增強方式,需要消耗比較多的計算資源。

     

  5. mixup 一種與數據無關的數據增強方式,即特徵之間的線性插值應導致相關標籤之間的線性插值,擴大訓練分佈。意思是兩個不同的label的樣本進行不同比例的線性插值融合,那麼其label也應該是相同比例關係進行線性融合。(上圖)

     

  6. Class balance 主要就是針對數據不平衡的情況下進行的操作,一般是針對採樣方法,或者在loss上做處理,如focal loss、weighted loss等。

     

  7. 圖像預處理,許多看似有效的預處理操作,但是並不一定有效,如在醫學領域的圖像,許多肉眼觀察良好的預處理的方式,實際上是破壞了原圖真實類別關聯的特徵,這種方面需要相關領域知識。

     

 

如何選擇更好的backbone模型

 

  1. 對於baseline,從resnet18/34 or efficientnet-B0起步,把所有work的技巧(loss/augmentation/metric/lr_schedule)調好之後,這時就應該大模型(deeper);

     

  2. 當更好需要換模型的時候,是不是就需要自己去設計/構造新模型呢?其實在比賽的短期裏,重新設計一個新的backbone出來是不提倡的,因爲模型不僅要work,還要重新在imagenet上預訓練,時間消耗巨大,不合適比賽;

     

  3. 由於學術界裏,sota模型多之又多,那如何選擇?從個人經驗總結來看,比較推薦se-resnext50/101、SENet154(太大,很少用),帶有se block的resnet,都不同類型的任務都有一定的通用性,性價比也較高;efficientnet系列(最近在某些比賽裏還優於se-resnext)可以上到B3,B5,有條件的B7都沒問題。其他的sota模型,可以嘗試Xception,inception-resnetV2等等。

 

建議與勸退

 

  1. 不要過擬合public lb,要在oof上看cv。一般來說,oof cv是比較準的,除非是遇到了private、public、train數據分佈都不一致的必賽,這時就需要靠人品。

     

  2. 如果是小白入坑,一定要自己獨立去完成一個比賽,儘量地去上分,從kernel,討論區去挖掘有用的信息,如果你沒一個比較好的基礎名次,自己也不會有資本去和前排的大神一起組隊。

     

  3. 勸退建議,希望大家都是在了以提高自身能力/興趣濃厚的前提下來kaggle參加比賽,不要太功利性:如出發點爲了找工作想來拿牌、申請好學校offer、帶隊拿牌並收取佣金和各種py交易來一起拿獎牌等等,當然前面兩種無可厚非,在kaggle拿金確實是有一定的加分。我這裏只是強調出發點。

     

  4. 沒有堅持的魄力,如遇到一些代碼上的難題(debug不通)或者無法上分,就直接放棄比賽或者是讓自己變成伸手黨等等,比賽期間是一個非常好的學習的過程,而且kaggle的討論區也是非常熱鬧的,只要臉皮夠厚,在討論區發一下自己相關困惑的問題(只要不是非常SB的問題),一般都有人很熱心的回答你。

     

  5. 充足的比賽時間,學生和上班族基本是一樣的,白天上班上課,晚上纔能有一些業餘的時間來放在比賽裏。我還在校時,經常在課堂裏拿着ipad觀察討論區,看相關論文,也是爲了能在白天積攢一些點子,晚上可以實施。我經常會在比賽的後半段期,會在凌晨調好鬧鐘起牀,觀察剛剛運行完程序的log,然後思考再做對應的修改繼續跑下一次,爲了就是不想浪費時間(當然可能比不過工作時加班到半夜的小夥伴)。當然不提倡,休息還是很重要的。

     

  6. 如果不是很滿足這些點,建議不要參加比賽哈,不要浪費這些時間,老老實實搬磚或者在校搞論文會更加好。

 

總結

 

  1. 以上分享的應該是不夠全的,比如一些視頻類/目標檢測類的技巧就沒有出現,只是因爲那些方面我還比較弱,所以就沒寫上去。

     

  2. 以上分享的tricks不一定work,只是一些常用的方法,最重要的還是隊數據的理解,針對這些問題來使用相對應的方法,會更加的高效同時也會得到更加多的收益。當然,這是需要長久下來積累的經驗與功力。

 

                                                                                          -END-

 

*延伸閱讀

 

 

 

                                                        

                                                                               △長按關注「邁微電子研發社」

 

                                                                              

                                                                        △長按加入「邁微電子研發社」學習輔導羣

 

                                              

 

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