AWSに400ドル使ってkaggleでSilverメダルを取ってみた

はじめに

毎年11月ころに将棋電王トーナメントがあって、そこに向けて将棋ソフトを強くするのが、目標の一つだったのですが、残念ながら昨年で終了してしまいました。

dwango.co.jp

そうして目標の一つが消えてしまった上に、最近は人生に迷走気味というのもあり、新たな何かをしてみようかなという安易な気持ちでkaggleをやってみました。

 

kaggleに詳しくない場合は、以下のブログとか読んでみるとよいかもです。コンペの説明や用語も丁寧に解説されていてすごい!

www.topgate.co.jp

kurupical.hatenablog.com

 

スタートライン

まずは、いくつかある開催中のコンペの中からどれに参加するかを探しました。やっぱり、DeepLearningかなということで画像コンペにしてみることにしました。終わりまでまだまだ余裕があるコンペがよかったので、以下のコンペに参加してみることにしました。

Human Protein Atlas Image Classification | Kaggle

 

DeepLearningについてはまったくの素人で、サンプルを動かした程度の知識でした。持っているPCはsurface Proのみのため、DeepLearningはなかなかハードルが高いなあという印象でした。

まあでも今どきはGoogle ColaboratoryなんていいものがありGPUがなくてもDeepLearningができるようになっているので、こちらのみを使って無課金でゆるゆると楽しもうかなという感じで、最終的に半分より上にいればいいかなくらいの気持ちでした。

 

Google Colaboratoryをkaggleで使うために以下を参考にさせていただきました。

qiita.com

 

qiita.com

  

前半

とりあえず少ない知識を総動員したところ「ImageNet」「Pretrained」「Finetuning」という言葉が下りてきたのでまずはこのあたりからスタートしようかなと思いました。Kernelを探せばそんな感じのがありました。

Pretrained InceptionResNetV2 base classifier | Kaggle

 

まずは、上記のkernelをほぼコピペしたものをsubmitしてみたのですが、Public Leaderboardで0.17くらいでした。とりあえずベースはできたのでこれを手掛かりにいろいろ適当に試しつつ、しばらく遊んでいました。

最終的には、512 x 512の画像をランダムに切り出して299 x 299にして学習させたのが一番成績がよく、Public Leaderboardで0.39くらいになりました。順位にして全体の50%程度。まあ、初めてなのでそんなもんですよね。

 

中盤

Discussionとかいろいろ眺めると解像度が重要で、512 x 512の画像じゃないと勝負にならなそうです。まあ、いままでの感触からそんな雰囲気です。

Pretraindモデルには見切りをつけて、0から学習させてみようと思い検索すると以下の実装が見つかったので、これを使ってResnet34で学習させることにしました。

github.com

 

Public Leaderboardで0.49となり、なんと、ぎりぎりSilverメダルあたりまで行きました。

となるとちょっと欲がでてきて、目標をただ参加することから最低でもSilverメダルを取ることに変更しました。

そうなると解禁するのが課金です。圧倒的課金で足りない実力をカバーしに行くことにしました。何がいいのか試してみなければよくわからないのに、環境が貧弱ではできることが限られてしまいます。

GCPを使うのがkaggleでは王道なのかなとか、GPUをつかうにはGCPの方がいいのかなとか思っているのですが、面倒だったのでさっさとAWSでやりました。使い慣れているし、惰性です。

AWSを使うのに特に参考にしたものはなく、Spot InstanceでDeepLearningのAMIを適当に検索して使いました。 

 

この時期は、以下の実装を参考にGAPNetを色々変えて試してみたり、

GapNet-PL [LB 0.385] | Kaggle

ResNet34をちょっとずつ変えて色々試したり、GRBYの4chで学習させてみたりとしていました。

GAPNetはResNet34を超えることができずに断念しました。4chでも3chでもそれほどスコアに差はありませんでした。

色々試しましたが、Public Leaderboardで0.54くらいで頭打ちな雰囲気が漂ってきました。順位も80位くらいまで落ちてきました。

このままではBronzeメダルも怪しくなってきたので、AWSインスタンスを2つに増やし、重課金状体制を構築しました。他にもコンピューター将棋用のc4.8xlargeを常に1インスタンス回していたので、お金がどんどん飛んでいきました。つらい。

 

終盤

Discussionを読むとPretraindモデルを使っている人が多そうなので、試してみることにしました。うーん、そうなのですか。

kerasだと以下のが手軽に試せそうなのでやってみました。

github.com

 

Resnet18でとりあえず試してみたところ、0.554になりちょっとだけ改善しました。というわけで再びPretrainedモデルに戻ってきてしまいました。

まずは、単体のモデルで精度が出ないとどうしようもないかなと思い、12月いっぱいくらいまで単体モデルの精度向上を試していました。入力画像をRGB以外にも試してみたり、損失関数を変えてみたりとか試していたのですが、それほど成果はあがりませんでした。

ただ、以下のDiscussionを見る限りでは同じくらいのみんな同じような感じだったのでそれほど悪くはないのかなと思っていました。

Best single model without leak | Kaggle

 

 年末年始の休みに入ってから、p3.2xlargeに変更しさらに課金力を上げました。ちょっとお金かけすぎかなと思ったのでコンピューター将棋用のインスタンスを止めました。最後は力ずくで伸ばしてやろうと思いました。

アンサンブルをどうすればいいかよくわからなかったのですが、とりあえず単純平均すれば悪くはならないだろうと思い、各モデルの出力を単純平均しました。それなりに向上していき、Public Leaderboardで0.6を突破し40位前後をうろうろするようになりました。

 

結果

結局、ResNet34、ResNet50、Xception、InceptionV3、InceptionResNetV2をRGB、YGB、RGYの画像で学習して、各出力の単純平均を取りました。閾値の決め方もよくわかんなかったので、検証用のデータセットで一番スコアがよくなるような値を採用しました。最終的な良し悪しの判断をPublic Leaderboardに任せてしまったのですが、よくなかったかもしれません。

Public Leaderboardでは、36位だったのですが、Private Leaderboardで大幅に順位を下げて68位でした。残念。なんとかSilverメダルを確保できて目標達成ではあるのですが、うーん、もっと上に行きたかった。というか爆下げはダメージがでかい。

そして、AWSへは400ドルくらい貢いだような気がします。400ドル貢いでSilverメダルなのでコンピューター将棋より少しマシなくらいですか。。。

 

おわりに

Kernelを読んで何してるのかある程度わかるくらいの知識があれば、スーパーソフトウェアエンジニアではなくても、それなりに頑張れば初心者でもSilverメダルまたはBronzeメダルくらいまではいけそうです。

Kernelの意味があんまり何やってるかわからなくても、たくさん実験すれば何とかなるような気がしました。

Silverメダルくらいまでは運が向けば行けそうな雰囲気ですが、Goldメダル以上を目指すならきちんとした実力を身につけないと難しそうです。

 

kaggleやりたいと思っている人はタイタニックじゃなく開催中のコンペにいきなりチャレンジしてもいいのかなと思いました。開催中のものの方が単純に楽しいですし。

 

kaggleはもうすこしちゃんとやってみようかなと思います。コンピューター将棋にも少しはプラスになるといいのですが、今のところあまりプラスにならなそうです。

あと、課金はつらい。だれかGPUのマシンをください。