競走馬のパドック画像から距離適性をディープラーニングで予測する

まだまだ改善したいですが競馬の祭典ダービー当日ということでいったん現状をまとめてみます。

やりたいこと

短距離馬と長距離馬は馬体の特徴が違うと言われています。 それをAIで判別できるようにしたい! というのが今回の試みです。

パッと見た瞬間に、胴が短いな、詰まっているなと思ったら、短距離馬の胴体である。反対に、胴が長く、窮屈なところがないなと感じたら、長距離馬の胴体である。 (ガラスの競馬場: 集中連載:「馬を見る天才になる!」第4回 より)

果たして、ウマくいくのか〜?! o(´Д`*)o

短距離馬 長距離馬
http://keibado.cplaza.ne.jp/keibabook/031006/images/pp08.jpg http://keibado.cplaza.ne.jp/keibabook/110516/images/pp09.jpg

(写真は競馬道のPHOTOパドックのサイトから)

学習データの生成

1. パドック画像の収集

入力となるパドック画像は競馬道のサイトからクローラで収集してきます。

2017年1/23時点で のべ頭数 8707頭、ユニーク頭数としては 2528頭分の画像を収集できました。

sanshonoki.hatenablog.com

2. ラベル(距離適性)の収集

次に画像に対してラベル(距離適性)をつけていきます。

Netkeibaの各馬のページの適性レビューのデータを使って距離適性のグラフから数値(0.0-1.0) として取得します。

sanshonoki.hatenablog.com

学習

いよいよ学習です。

CNN で 回帰(Regression)学習します。

  • input: パドック画像 (32 x 32)
  • target: 距離適性の値 (1.0 - 10.0): 0.0-1.0 を10倍にスケール
  • モデル f:id:sanshonoki:20170525051758p:plain
  • 学習最適化アルゴリズム: Adam
  • データセット
    • test: 2016年のGIレース8レース分
    • validation: テストを除く2016年のデータ
    • train: 2016年以外のデータ

いろいろやって現状の最善の学習結果は以下です。 validationエラーが全然下がってきません…。 (´Д`。)

f:id:sanshonoki:20170525054508p:plain:w400

どちらとも言えないのであれば、平均的な馬体の馬なのであろう。必ずしも、体型のみで短距離・長距離を見分けられるわけではなく、どっちつかずの体型の馬の方が圧倒的に多いのが実際である。 (ガラスの競馬場: 集中連載:「馬を見る天才になる!」第4回 より)

とのことなので仕方ないのでしょうか..

やったこと
  • 学習データを増やす
    • flip画像の生成
    • コントラストを少しずつ変えた画像の生成
  • 初期化アルゴリズム で He のアルゴリズム を使う
  • 平均画像(mean.npy)を作成して入力を正規化する

あと、最初はターゲットを0.0-1.0としていましたが性能がよくなかったです。誤差関数が MSE(mean squared error) ということで二乗することにより誤差がより小さく出るので誤差逆伝搬が効果的に働いてなかったのだと思います。

いろいろとお膳立てされていて試行錯誤を必要としないチュートリアルと違ってホント苦しんでいます・・その分勉強になってますが。 validationエラーはあまり下がりませんでしたが素人が予測するよりかはマシな印象はあります。

予測結果の例

以下は2016年のGIレースから6頭分の予測結果です。 みなさんの目による予測はいかがでしょうか。。? (´・с_・`)

画像 DL予測 正解
f:id:sanshonoki:20170525050551j:plain 0.254587 こちら
f:id:sanshonoki:20170525051022j:plain 0.336478 こちら
f:id:sanshonoki:20170525051135j:plain 0.472271 こちら
f:id:sanshonoki:20170525050830j:plain 0.513455 こちら
f:id:sanshonoki:20170525050658j:plain 0.603956 こちら
f:id:sanshonoki:20170525051236j:plain 0.705816 こちら

0.0に近いほど短距離、1.0に近いほど長距離です

改善のために…

果たしてこれでうまくいくのかは分かりませんが改善として今思いつくこと

  • Preprocess処理(特にハンドエンジニアリング)をがんばる
    • 馬体部分だけを抽出した画像で学習するとか..
  • 入力画像サイズを大きくして(64x64 etc..)転移学習をやってみる

引き続きやっていこうと思います。

デモサイト

Heroku上で試せるようにしました。 興味ある方は遊んでみてください。。

https://padock-photo-classify.herokuapp.com/

また今回使ったコードは以下にあります。

(学習) github.com

(Webアプリ) github.com

参考記事

性能改善のために参考になった記事です。 ブログ記事にも書いたAndrew Ng先生のNIPS2016での講義ももちろん参考になりました。(●´Д`●)