世界一のデータサイエンティストを目指して 〜Kaggle参加レポート2〜

こんにちは!株式会社キスモの大越です。

以前初めて本格的に参加したKaggleコンペについてブログを書きました。

kysmo.hatenablog.jp

結果的には史上最も多い5169人という参加者の中で、312位になり、ブロンズメダルを取ることができました!以来Kaggleにはまり、空き時間に勉強がてら取り組んでいます。そこで今回は、つい先日終わったKaggleのコンテストについてブログを書こうと思います!


アプローチをまとめたGithub: github.com

コンテスト概要

テーマ:衛星画像に写っているものが船か氷山かを認識する。

背景:通常氷山のリスクは航空偵察と海岸からの監視で行われるが、厳しい天候の遠隔地ではそれができず、衛星画像から判断するしかない。機械学習を用いて、その精度向上を目指す。

評価指標:logloss

データ

f:id:kodamayu:20180305150053p:plain このように氷山と船の画像が与えられます。この例では船が細長くわかりやすいですが、中には船か氷山か見分けるのが難しいものも混ざっています。

詳細は割愛しますが、データには画像と合わせてinc_angleという重要な値が与えられています。

これらを組み合わせて分類を行うのが今回のテーマです。

アプローチ

1.より精度の高いモデルを作る

コンテストが始まってから、終盤に差し掛かるまでは、とにかく単体で精度が高いようなモデルを作ることを目標に取り組みました。以下に用いた手法をまとめます。

  • モデル(gitのmodelにまとまっています)

    • small cnn
      まずはじめに試したkernelで公開されているモデル。簡単なわりに、性能は1番良かった。
      https://www.kaggle.com/cbryant/keras-cnn-statoil-iceberg-lb-0-1995-now-0-1516

    • vgg like
      Vggをベースにコンパクトにしたモデル。手軽に試せるモデルなので、普段から重宝している。
      https://arxiv.org/pdf/1409.1556.pdf

    • resnet like
      ResNetをベースにコンパクトにしたモデル。ResNetでは、入力画像をSkip Connectionを使いながらできるだけそのままの値で出力まで影響させるようにしている。
      https://arxiv.org/abs/1512.03385
      詳しく知りたい人はcouseraで学ぶのがおすすめ。
      www.coursera.org

    • densenet like
      DenseNetをベースにコンパクトにしたモデル。
      https://arxiv.org/abs/1608.06993

    • vgg16 fine tuning
      Image Netの学習済みモデルを初期値としたもの。freezeするlayerは色々試した結果、全てfreezeさせないものが最もよかった。また、他の小型モデルと比較して精度が悪かった。
      これらの原因は、今回のデータがImage Netのデータと質が違いすぎることだと考えられる。Fine Tuningする際は、データの傾向が似ている方が精度が向上する。
      https://qiita.com/icoxfog417/items/48cbf087dd22f1f8c6f4

    • jirkamodel
      kernelで公開されているモデル。精度が良いと報告されていたので使ってみたが、言われているような精度にはならなかった。
      https://www.kaggle.com/jirivrany/my-best-single-model-simple-cnn-lb-0-1541

    • small anglenet
      最も精度が良かったsmall cnnにinc_angleの情報を加えたモデル。

  • 検証方法

    • 交差検証 はじめ5foldsで交差検証を行なったが、途中から10foldsに変更。ただ、時間の関係で10foldsできなかったものもある。

2.アンサンブル

コンテストの終盤は上記モデルをアンサンブルして、精度向上を目指しました。

まず自分で作った7つのモデルを使用してアンサンブルさせたところ、publicLBで0.1514、privateLBで0.1535でした。 アンサンブルの方法は下記kernelが参考になります。
Explore Stacking (LB 0.1463) | Kaggle

注目すべきはただ単に7つのモデルの平均をとるのではなく、中央値を取ったり、最小値と最大値で1部を置き換えることでスコアが向上する点です。 しかし、これは過学習の危険性もあったので、最終的な提出では平均を取ったアンサンブルとkernelのような特殊なアンサンブルの2種類を提出しました。この戦略は功を奏し、最高スコアを出したのは平均を取ったモデルでしたね。

また、kernelでpublicLBが0.1327というアンサンブルがあったので、それも自分のアンブルに取り入れました。
Submarineering.EVEN BETTER PUBLIC SCORE until now. | Kaggle

結果

結果は3343人中345位。top10%には惜しくも入れず、メダルを逃しました…

反省

今回足りなかったのは以下の点でした。

  • inc_angleを含めたモデルを1つしか作れなかった。
  • CNNのモデルも上位の人が100種類とか試す中、6種類の作成+チューニングで終わってしまった。単純に手数が足りませんでした…

1点目については特に、inc_angleは重要な要素だというのはdiscussionされていたので、もっと組み込みたかったです。 ただ、今回のコンテストでは初めてkernelを公開することができました!小さな一歩ですが、世界中のデータサイエンティストと知見を共有しながら、これからも勝負していきたいです!

上位者のアプローチ

Kaggleのいい点は、終わった後に上位者がアプローチを公開してくれることです。自分が参加したコンテストだと、それらのアプローチが手に取るように理解でき、とても勉強になります。

4位のアプローチ

Statoil/C-CORE Iceberg Classifier Challenge | Kaggle

f:id:kodamayu:20180305152154p:plain 論文で同じような画像サイズにおいて高性能だと報告されているモデルを使用していたのが特徴でした。

1位のアプローチ

Statoil/C-CORE Iceberg Classifier Challenge | Kaggle

f:id:kodamayu:20180305152231j:plain 1位のアプローチでは200以上のCNNを作ったというのも驚きですが、それよりもinc_angleの分布によって、氷山しかない領域と氷山の周りに船が分布している領域に分かれている点に着目したアプローチを取っていた点でした。上位の方々はinc_angleの重要性をとても意識したアプローチを取っていましたが、こうして分布を見せられると衝撃的ですね。ここに気づけるというのが素晴らしいです…

また、上位の方々はlog lossがリスクなくより高くなるようなclipの方法を計算から導いていました。自分はこういったアプローチはしたことがなかったので、新しい発見になりました!

次回に向けて

次回と言いつつ早速次なるコンテストには参加しているのですが、画像分類含めとりあえず手札を増やすことを意識すべきだと感じています。 次なるコンテストではメダル(あわよくばシルバー)を目指して頑張っていこうと思います!

また、Kaggleに参加して良かったなと思うのは、多くの方が持つ知識を盗むことができ、業務に役立つことがたくさんあるという点です。 自分の場合、最近の業務はKaggleの知見を総動員させながら取り組んでいます! みなさんもぜひ参加してみてください!