APTOS 2019 Blindness Detection コンペ反省会

失明にいたる病気を眼の画像から判定する(5段階)コンペ。初めての画像コンペ。画像コンペでは大きくマシンリソースを使うというイメージで敬遠していたがそこまでもなかった。チームで挑み結果は804/2987。public から375もランクダウン。Shake up の原因と対策はあとでまとめる。

学び

PyTorch

コンペの途中で Keras が deterministic results を出してくれないことに悩み PyTorch にスイッチ。PyTorch 公式のチュートリアルを写経するだけで十分だった。以前から PyTorch カーネルを読み込んでいて一番気になったのが train 時に back prop の伝播の一部を明示的に書かないといけないこと。やってみたらそれほど気にならなかった。それよりも PyTorch API と画像コンペとの相性のよさが際立っていた。これまで Tensorflow -> Keras -> PyTorch と流れてきたが PyTorch がちょうどよい。Define by Run も気軽で良い

ただ気になっていたのが高 Score Kernel が fast.ai で書かれていたことだ。次の波が来ている?

Augmentation

CNN などでの画像分類において training data が少ない場合に argumentation が効く。という教科書的な知識はもちろん知っていたが。どう apply するのか全くわからず困惑した。rotation の角度の範囲は?horizontal/vertical flip が起こる確率はいくつが良いのか? augmentation は組み合わせるもの?単体で使うもの? training epochs への影響は?など分からないまま後半に突入してしまった。上位カーネルで勉強したいところ。

4th solution によれば

Augmentations We used a lot of augmentations, at least more than I ever used before :) All from the wonderful albumentations library: Blur, Flip, RandomBrightnessContrast, ShiftScaleRotate, ElasticTransform, Transpose, GridDistortion, HueSaturationValue, CLAHE, CoarseDropout. とのことだったので知識も手数も足りなかった模様。

Ensemble

Ensemble が手元でほとんど効かなくて困惑した。まだ原因がわかっていない。

チーム

チームでやってみて良かったのは、各人の「やって当たり前」の前提が違うこと。例えば D 氏はとりあえず論文をいくつか読んだから実装してみる。と言って僕を驚かせた。自分は Discussion 読んで Kernel を書いて手を動かしがちなのとは対象的だ。M氏はクラウドリソースを用意してくれて、それがいかに素晴らしいものか教えてくれた。何度作業効率の上がることか。あとチーム内で最高スコアのカーネルをぱっと出してくれたのも M 氏である。コミュニケーションはまだまだ課題があると思った。チーム doc を用意したが最低限しか機能してなかったように思う。

コミュニティへの貢献

このコンペは submission がコケたときにヒントが少なすぎるという問題があって多くの人がハマっていた。How to debug "Kernel Threw Exception" with binary search というトピックでデバッグ方法を書いたら評判が良く、コンペ運営側の目にもとまって紹介されたのは良かった。上位ランカーがどこかで書いていたが、コミュニティーに自分の学びを共有すると結果的に自分が成長するということがよくあるらしいのでがんばりたい(因果関係かどうかはわからないけど)

反省

いまだに自分の時間をどう配分するかに迷いがある。順位が振るわないので改善の余地があるのだと思う。自分の書いたカーネルにこだわりすぎたのは本当に良くない。public kernel を少し改造しただけのもののほうが Score が良かった。時間のなさを言い訳にしたくなるが Neuron Engineer 氏は3歳のお子さんがいるらしいので。

pseudo-labeling を学ぼう。

top solution からのメモ

  • pseudo labeling
  • Downsampling
  • (480, 600) など。各種データサイズを試している。

```` Compose([ BensCrop(img_size), #from 2015 solution RandomHorizontalFlip(), RandomVerticalFlip(), RandomRotation*1, ), ])

for EfficientNet B5 Compose([ Resize(img_size), HorizontalFlip(), VerticalFlip(), Rotate(), RandomContrast(0.5), IAAAdditiveGaussianNoise(p=0.25), ]) ````

train_transform = transforms.Compose([ transforms.ColorJitter(brightness=0.45, contrast=0.45), transforms.RandomAffine(degrees=360, scale=(1.0, 1.3)), transforms.RandomHorizontalFlip(), transforms.RandomVerticalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])

*1:-120, 120

Jigsaw Unintended Bias in Toxicity Classification 記録 - Kaggle

Jigsaw Unintended Bias in Toxicity Classification | Kaggle に取り組んだときの感想。コンペは終了していないが submission の受付が完了。ランキング発表を待つだけなので忘れないうちにメモを残す。

過去に経験のある text の classification 系。LSTM, GRU などがすぐに解法として浮かぶ。今回は benchmark となるカーネルが公開されていたので、そのカーネルにスコアで並ぶまでは discussions / kernels を見ないと決めて取り組んだ(=他人の解法やヒントを見ずにある程度自分だけで進める)。これは良い決断だったと思う。また kibela に自分しか見られないメモを書いてスコアや進捗を管理した。kernel の stdout も kibela に貼ることを前提の format とした。

時系列

  1. 過去に書き溜めたコードから end to end で動くカーネルを作る
  2. text preprocessing と model の両方から benchmark カーネルに少しずつ近づく
  3. benchmark kernel に追いついたあとは discussions / kernels を丁寧に読みはじめる
  4. target だけではなく別の指標もモデルの output ととして training する multi output モデルに感心。勉強になった。
  5. レーニング時間を短くするために任意長の text を input として使えるようにモデルを修正。keras の fit_generator で動かすのに苦労する。苦労が報われてかなり短縮。
  6. この時点で keras よりも torch の方を使う kernel が多くやきもきした。時間がないので torch はこのコンペでは追わないことを決断。
  7. public kernel の best score が超えられなかったので自分の実装を捨てて keras best score カーネルをもとに改善していくことに。
  8. 細かい改善で向上するが決め手にならず。
  9. 期日が近づき始めたので training と prediction の kernel を分けることに。embedding を model save/restore に含めない部分が初めてだったので慎重に実装。
  10. ↑で model restore が簡単になったので ensemble に着手。LSTM, GRU ベースの model を average するだけでスコア向上。
  11. 無視していた bert に着手。例の vanila kernel を理解して training 時間の短縮などに取り組み。LSTM model より高スコアに。fine tuning するだけであっというまに LSTM モデル超え。
  12. ensemble すると一気にスコアが向上
  13. Stacking を試してみたが prediction にそれなりに時間がかかるわりにスコアは上がらず。xgboost のチューニングの問題かもしれない。
  14. XlNet が出たが流石に間に合わないだろうと諦め。
  15. そうこうしているうちにタイムオーバー。最高スコアのものを 2 つ提出した。

どうやったらもっと上に行けたか?

  • チームを組む(これは作戦を考え中)
  • 各入力の loss weight の深掘り。

結果

  • 288/3,167 in public LB
  • 終結果はまだ未確定

最近の読書

「凍りのクジラ」、「旅人」、「羊と鋼の森」が特に良かった。今年は当たりが多い。


凍りのくじら (講談社文庫)

凍りのくじら (講談社文庫)

旅人  ある物理学者の回想 (角川ソフィア文庫)

旅人 ある物理学者の回想 (角川ソフィア文庫)

首折り男のための協奏曲 (新潮文庫)

首折り男のための協奏曲 (新潮文庫)

スコーレNo.4 (光文社文庫)

スコーレNo.4 (光文社文庫)

太陽のパスタ、豆のスープ (集英社文庫)

太陽のパスタ、豆のスープ (集英社文庫)

たった、それだけ (双葉文庫)

たった、それだけ (双葉文庫)

終わらない歌 (実業之日本社文庫)

終わらない歌 (実業之日本社文庫)

よろこびの歌 (実業之日本社文庫)

よろこびの歌 (実業之日本社文庫)

時を刻む湖――7万枚の地層に挑んだ科学者たち (岩波科学ライブラリー)

時を刻む湖――7万枚の地層に挑んだ科学者たち (岩波科学ライブラリー)

羊と鋼の森 (文春文庫)

羊と鋼の森 (文春文庫)

Stacking 実装中

ちょうどよい加減に抽象化された Stacking の例が意外と見つからない。base models での CV、meta model での CV それぞれどうやるべきなのか。meta model は linear で良いのか。 tree base が良いのか。実践的な例をがんばって探してみている。このコンペが終わったらコードを公開しようかな。

Kaggle Ensembling Guide + 実装例

Kaggle Ensembling Guide | MLWave という良記事を読み込む。そして1ミリもごまかさずに理解する過程をメモ。

Creating ensembles from submission files

Voting ensembles

これは分かりやすい。モデルが3つ以上あるときに prediction 結果の多数決をとって精度を上げる方法。 Simple Voting Ensemble for the Titanic | Kaggle に実装例がある。4 つのモデル(train前)を sklearn.ensemble.VotingClassifier に渡して training すると精度が向上するのがわかる。VotingClassifier のドキュメントを読むと voting には hard(class label の voting) と soft(predicted probablitiesの argmax) の種類があるようだ。

Correlation/相関

相関があまりないモデルを組み合わせたほうが精度が上がるという話。これは直感的にも理解できる。

Weighing

モデルが同程度に精度が良いとは限らないので、より良いモデルの voting に weight をかける方法。例:Better predictions: stacking with VotingClassifier | Kaggle

eclf = VotingClassifier(estimators=[
    ('rf1', rf1), ('rf2', rf2), ('gbc', gbc), ('xgb',xgb)], voting='soft', weights = [3,1,1,1])

Averaging

bagging submissions ともいわれる。モデルの prediction を平均する。classification と regression どちらでも使える。例:Titanic using ensemble average | Kaggleにて下記のように各モデルのpredictionを単純に足し合わせているのがわかる。4 で割るかわりにしきい値が 2 にしていることに注意。

mix_predict=logreg_predict+RDM_predict+Tree_predict+svm_predict
mix_predict[mix_predict<2]=0
mix_predict[mix_predict>=2]=1

Rank averaging

models が同様に calibration されているとは限らない(over-confident だったり under-confident) なので直接比べて average するのは良くない。それぞれのモデルの submission ないで各行の probability が何番目に大きいかのフィールドを作って、それらを複数のモデルで average する。例:Rank Averaging script | Kaggle

Historical ranks 

前述の Rank はある test set の prediction 内の rank なので、また新しく別のデータに対する prediction が必要になったらどうするのという話。Rank をとっておいて似たような確率値の rank を使えばよいという話。例は見つけられなかったけど難しくないので良いと思う。

Stacked Generalization & Blending

Stacked generalization

説明を読んでもさっぱり分からなかった。いくつかの解説サイトを読んだが、結局 Stacking - Ensembling | Coursera この動画が一番わかりやすかった(というかこのクラスとったのに覚えてない。やはり実践しないとだめだね)。level 0 で各モデルの predction for valid を training データとして新しいモデルを train するということなのね。例: 2-Level Stacked Generalization | Kaggle

level 1 の model は weight 付きの averaging が best だと学習するかもしれない(しないかもしれない)。

Blending/Stacked Ensembling

out-of-fold でななくて train data で holdout set (10%) を level 0 の training に使う部分が違う。

Feature weighted linear stacking

。abstract しか読んでない。

力尽きた。続くかもしれない。