久しぶりのブログ投稿です!!!
最近はデータサイエンスのコンペとか出てちょいちょい出てます。そして少しずつ結果も出るようになってきました。これからはそのあたりのことをブログにも書いていこうかなと思ってます。
今回は6月〜7月上旬に行われたFUJIFILM社主催のデータチャレンジコンテストです。こちらなんとか駆け込みで入賞できました!ので、その時の感想をつらつらまとめます。
コンペ概要
こちらどういうコンペかといいますと‥写真に写っている日付を予測するというものです。
与えられたのは日付が入っている写真と入ってない写真。入っているものについてはJSONファイルで正解ラベルとそれぞれの数字と記号のbboxが与えられていました。記号とは例えば「'92 5月16日」とかだと「'」や、「月」は「mm」、「日」は「dd」のように与えられていました。
予測値として求めるラベルは...たとえば、「2019年7月15日」という日付が写真に印字されていたとします。その時の予測する正解ラベルは「2019 7 15」という文字列になります。ラベルとして出力するのは数字だけで年月日のところにはスペースが入ります。
スコアは各予測ラベルに対して正解ラベルとの違いをdiffコマンドを使ってまず一致している数を出します。そして、その一致している数の2倍を、予測の要素数+ラベルの要素数で割ります。要素数0のものは1です。最後に、その値の平均をとってスコアとなります。0〜1の値でスコアが良いほど1に近づきます。
どうやって解こうかな・・・
この問題をぱっと見てbboxラベルであるから、物体検出を使うのかなって思ってました。
どうしようかなと考えていたところ、このコンペのちょっとした企画でコンペが始まって1週間後くらいに、オフラインもくもく会が開催されるとの情報が。しかも、そこでベンチマークコードを紹介されるという、なんとも初心者にも優しいコンペでした。
東京だったのでモクモク会は参加できませんでしたが、公開されたコードで勉強しながらやってみるかって思いました。
いざコードが公開されてnotebookを読んでみたところ、使われていた手法は物体検出ではなくイメージキャプションでした!しかもスコアは0.85以上でけっこう高い。これは予想外、そんな解き方があるんですね。イメージキャプションもやったことなかったのですが、自分の興味としては物体検出かなってことで物体検出をやることに。
...全くやったことない手法ってなかなか手が動かないですよね。物体検出ってどうやったらできるのかな〜って考えてたら、気がついたら7月になってました(笑)
ちょうどその頃、創薬コンペも始まって、なんかそっちは良い感じのスコアが出てたので、富士フィルムのコンペは諦めようかな...と思ってたのですが、ここでやめたら一生、物体検出とご縁がなくなる気がしました。スクラッチから物体検出を実装するのは無理でもとにかく1サブできるように頑張るか!ってことで残り4日から物体検出スタートさせる決意をしました。
物体検出
物体検出ってどうやるのかな〜って調べてたら、たまたまtorchvisionに出くわしました。なんかこれ使ったらできるんじゃね?ってことでPyTorchほとんど触ったことなかったけど、torchvisionの物体検出のチュートリアルをやることに。結論から言いますと、なんか駄目でした。21時頃から初めて3時間位いろいろやってたんですがなんか駄目でした。ここで疲労感もあり報われなかった感もあり、一瞬心が折れかけました。
が、ここもなんとか踏みとどまって、一つくらいGithubを試してみるかってことに。
そこで見つけてきたGithubがこちら。
github.com
苦労したのはラベルをxmlファイル形式にラベルを書き換えるとこです。ドキュメントを参考にVOC形式に書き換えて行きました。
docs.python.org
いくつかのエラーと心が折れそうになるのを乗り越えて、ついにYolo3の学習が回り始めました!!!!!
計算が終わるのをウキウキしながらその日は寝ました。翌朝、計算中。ラボから帰宅して、計算中。翌朝、計算中。...あれ、これ計算間に合わない?とドキドキしながら待つこと2日半。サブミット締切の当日の朝に無事計算が終了してました!
なんとか、物体検出ができたのであとはラベルを予測するのみです。
ラベルの予測
ラベルの予想は、はじめは数字の距離で行おうと思いました。しかし、これが全然うまく行きません。「1」のbboxが細かったりして数字間の距離がそんなに一定じゃなかったからです。
いい手法が思いつかず時間もなかったのでヒューリスティックにやることにしました。
『「’」があったらその後ろ2つは年代で、さらにその後ろに文字が4つあったらその間に空白を入れて...』
などなど1つずつルールを記述していってスコアをチェックしてを繰り返して、最終的なスコアは0.92ちょいくらいでサブミッションを終了しました。
結果
このコンペはラスト1週間はリーダーボードが更新されず結果の連絡が来るまで自分の順位はわかりませんでした。上位陣が0.99台をマークしていましたので、入賞は厳しいかなと思っていたのですが、なんとか10位くらいで入賞できていたようで、結果を聞いた時は素直に嬉しかったです。
上位陣の解法
表彰式では上位3名の方の手法紹介があったので簡単にご紹介します。
上位3人のうち物体検出を使われていたのは2位の方だけでした。モデルはResNet152をベースにしたRetinaNetを使われていました。検出しにくい文字を閾値を変えたり、ラベル方法を変えたり色々されていました。
データ拡張では最新の方法を取り入れられており、その中でもヒストグラム補正が効いたとのこと。
arxiv.org
空白をどう入れるかなのですが、2位の方もやはりヒューリスティックに解かれていました。ですが、そこにも数多の工夫がありとにかくスゴイなと思いました。
1位、3位の方はイメージキャプションを使われていました。
3位の方は運営の方が公開してくださったベースラインのモデルから、様々な工夫を施して0.99越えまでもっていかれていました。うまくいったものから失敗したものまで、様々なものを試されていて、強い人は打つ数が違うなと思いました。
1位の方はbboxの情報をうまく使って、数字があるところをセグメンテーションでくり抜いて、そしてイメージキャプションの精度を上げられていたのがすごく印象的でした。
上位の方の解法を聞いた感想として、イメージキャプションでここまで正確にラベルが予測できるっていうのは単純に驚きでした!
感想
このコンペでは前から使ってみたかった物体検出を使ういい機会になったのでとても良かったです。また、上位陣の手法も知れたし、入賞の商品としてチェキももらえたので頑張って挑戦してよかったなと。次回あればまた上位入賞を目指して頑張りたいなと思いました!!!
余談ですが、今回の授賞式では往復の交通費も支給していただけるということだったのですが、実は入賞した直後、ちょうど奇跡的にkaggle tokyo meetupに繰り上がり当選していたということもあり、交通費がうまく浮いてくれました!おかげさまで、幸運続きの良い週末を過ごすことができました。