https://www.facebook.com/groups/TensorFlowKR/permalink/963838507290541/?sfnsn=mo

안녕하세요 캐글코리아!

DGIST 3학년에 재학중인 이해찬입니다.

저는 이번 2019 3rd ML month with KaKR에서 1st score을 기록했습니다. 혹시 공부하시는데 도움이 되실까봐 solution을 공유해 드리겠습니다.

(같은 내용으로 competition discussion에도 올려 두었습니다.)

***글이 길수도 있습니다.***

Baseline model : Efficientnet-B5

Preprocessing

Using Bounding Box :

저는 처음에 bounding Box로 crop된 image를 사용했지만 아래의 두 github글에서는 crop하지 않은 image를 input으로 주는 것이 성능이 더 좋다고 하였습니다.

https://github.com/jianshen92/stanford-car-grab-challenge

https://github.com/morganmcg1/Projects/tree/master/stanford-cars

하지만, Public score 0.93정도 이상에서는 그렇게 큰 효과가 없었습니다. 또한, cutout을 적용하면 crop된 image가 성능이 더 높은 모습을 보여주었습니다. 그래서 저는 Bounding box로 crop된 이미지를 input으로 사용했습니다.

Image를 resize하는 방식을 사용했는데 위의 github에서는 squeeze하는 방식을 사용하면 더 좋은 성능을 보여준다고 합니다. 하지만, 저는 이것을 구현하지 못해서 적용하지 못했습니다.

Augmentation :

(saewon님의 kernel을 참고하였습니다.)

Random Resized Crop, Random Horizontal Flip, Random Rotation, AutoAgumentation(CIFAR-10), Normalize, Random Erasing(cutout)을 적용하였습니다. 여기에 mixup을 적용시켰습니다.

Cutmix를 mixup대신 적용시켜 보았지만, 저는 mixup을 사용했을 때 성능이 더 좋게 나타났습니다.

mixup의 alpha값은 0.2, 0.4, 1.0을 사용해보았는데 1.0에서 성능이 가장 좋게 나왔습니다.

rotation은 30도를 주었고 resized crop은 (0.8, 1.0) 다른 것들은 default 값으로 적용시켰습니다.

Sampler :

Class의 이미지 수들의 불균형이 존재했습니다. 균형을 맞추기 위해서 oversampling 방식을 통하여 한 epoch을 당 주어지는 class의 image 수를 같게 맞추었습니다.

Loss :

FocalLoss를 gamma를 0.5, 2, 3을 시도해 보았습니다. gamma가 0.5일 때 성능이 가장 좋았습니다. 하지만, 이것보다 그냥 cross entropy loss가 더 좋은 성능을 보여주었습니다. (제가 구현을 잘못한 것인가요…ㅠㅠ Focal loss가 더 좋을 것으로 예상을 했었는데…) 그렇기에 저는 loss로 cross entropy를 사용했습니다.

Label smoothing을 적용해서 실험해 보았지만 그럴듯한 성능 향상을 보여주지 않았습니다.

(Triplet loss구현을 시도해 보았지만, 시간 부족을 구현을 완료하지 못했습니다. 혹시 해보신 분 있으면 결과를 남겨주시면 좋겠습니다.)

Model :

저는 Efficientnet-B7, B6, B5, PNASNet, NASNet을 사용했습니다. 각 model head에 dropout(0.4~0.5)을 추가해서 사용했습니다. (IIdoo kim님이 discussion에 올렸던 model은 너무 train하기에 무거워서 결국 사용하지 못했습니다.)

WS-DAN(Weakly Supervised Data Augmentation Network)이라는 아주 흥미로운 구조를 실험해 보았습니다. 이것을 Efficientnet-B7 model에 적용시켰습니다. Training 시간은 3배로 걸리지만 성능은 크게 개선되지 않아서 이 구조를 버리게 되었습니다.’

Scheduler :

초반에는 CosineannealingLR, MultistepLR, StepLR을 사용해 보았습니다. 이중에서 적절한 값을 찾아본 결과 MultistepLR이 가장 좋은 성능을 보여주어서 이것을 사용했습니다. 후반기에 최종 model을 train할 때는 SuperConvergence라는 scheduler를 사용하여 train을 하였습니다.

Optimizer :

다양한 optimizer를 baseline에 실험해 보았는데 AdamW가 가장 성능이 좋았습니다. Efficientnet모델에는 AdamW를 사용하게 되었습니다. PNAS, NAS에서는 SGD + momentum이 성능이 좋은 모습을 보여주어 이것을 사용하였습니다.

Train Process:

Efficientnet-B7, B6, B5는 lr=0.00028로 50 epoch train후 max_lr=0.00028로 SuperConvergence + AdamW로 60 epoch train했습니다.

PNAS, NAS는 lr=0.0042, max_lr=0.0042로 위와 같은 방식으로 optimizer만 바꿔준 후 train했습니다. weight저장은 valid set에서 F1-score가 가장 좋은 weight를 저장했습니다.

Test-Time-Augmentation :

tta를 5번 적용하였습니다. 적용한 augmentation은 Random Resized Crop, Random Horizontal Flip, Random Rotation입니다. Rotation은 5를 주었고 나머지는 train때와 같게 주었습니다.

Ensemble :

6 fold cross validation을 사용하였습니다. 또한 앞에서 언급한 Efficientnet-B7, B6, B5, PNAS, NAS model을 soft-voting을 하였습니다.

성능으로는 B7>B6>B5>PNAS>NAS 순이었습니다. (Public score 기준)

(결론적으로 총 30개의 weight를 사용했네요… 6.5G정도 되네요)

최종 score “ Public : 0.96604,  Private : 0.96058 ”
Posted by uniqueone
,