Djangoで「名古屋/東京」の画像分類アプリを作った
Djangoで簡単な画像分類アプリを作ってみた。Flickrから「名古屋」「東京」で画像を400枚ずつ収集して、KerasのVGG16使って分類器を学習。推論したい画像を渡して、結果を表示するところまで。分類器が適当でAUCが.65くらいなのはご愛嬌。 pic.twitter.com/E4EHlliTYh
— u++ (@upura0) July 27, 2019
はじめに
Djangoを使って「名古屋/東京」を判定する画像分類アプリを作ってみました。下記の記事で学んだことを活かして、自分で手を動かしてみたという経緯です。
インターフェイス
index.html
この画面で、画像を選択します。「推定する」ボタンを押すと、result.htmlに推移します。
result.html
推論結果の画面です。前画面で選択したファイル名・画像ファイル・推論結果・推論確率を表示しています。
分類器
機械学習モデル
KerasのVGG16使って転移学習させています。AUCは.65程度でお世辞にも良い精度とは言えませんが、今回はWebアプリ化が目的だったのでハイパーパラメータなどを少しだけチューニングして終わりました。
大相撲のデータ収集は「Sumo Reference」が便利
まだ全然用意してないですが「機械学習を用いた大相撲千秋楽の勝敗予想」でLTしようと思います。LT枠空いているので、気軽に是非!「スポーツ×データ分析」に関係あれば競技問わず何でもOKです。 #spoana pic.twitter.com/9DPdyc9Tu2
— u++ (@upura0) July 22, 2019
8月24日(土)に開催予定の「Sports Analyst Meetup #4」で大相撲関連の分析をするに当たって、まずはデータ収集に取り組んでいます。
Sumo Reference
筆者は「Sports Analyst Meetup #2」のtomi_ さんのLTで知ったのですが、大相撲のデータ収集は「Sumo Reference」が便利です。
おわりに
本記事では「Sports Analyst Meetup #4」でのLTに向けて、大相撲のデータを収録している「Sumo Reference」を紹介しました。次回は、収集したデータの簡単な探索的分析・可視化をしていく予定です。
Udemy講座「【Python・Django・TensorFlow + 転移学習】画像分類AIアプリ自作入門」をやった
Udemy講座「【Python・Django・TensorFlow + 転移学習】画像分類AIアプリ自作入門」をやりました。タイトル通り、PythonのTensorFlowで作成した機械学習モデルをDjangoを用いてWebアプリ化する講座です。全3.5時間を一晩で流し見しながら追体験しましたが、個人的に求めていた内容にピンポイントで合致して満足しています。
https://www.udemy.com/django-ai-app/
受講の動機
受講した理由は、機械学習モデルをWebアプリに組み込む方法をザックリと知りたかったためです。最近、Kaggleなどで機械学習モデルの構築に取り組んでいる中で、Webアプリなど自分・他人が扱いやすい形で表現する必要性を感じていました。普段からPythonを使っているので、Djangoが選択肢となりました。
下記の講座の受講を経て、Udemy講座には好印象を持っていたのも大きかったです。
各セクションの雑感
基本的に、全部1.5〜2倍速で観ていました。聞き逃した際には15秒戻る機能があるので、ある程度自信がある内容なら講師の話し方に合わせた早回しで受講して問題ないと考えています。
イントロ
概要です。一応聞いておいた方が良いと思いますが、事前の講座説明に書いてある通りです。
環境構築(既修者はスキップOK)
セクション名にある通り、飛ばしました。
転移学習でスコアアップを図ろう!
同上。
おわりに
Udemy講座を通じて、機械学習モデルをDjangoを用いてWebアプリに組み込む方法を学びました。次は今回学んだ内容を用いて、自分なりの簡易的なWebアプリを作っていこうと思います。
web開発力を身に付けるぞ、2019年夏〜
— u++ (@upura0) July 10, 2019
Kaggle Jigsawコンペ32位でした
KaggleのJigsawコンペにチーム参加して、32位で銀メダルでした。public 58位からは上昇しましたが、金メダル圏内にはもうひと押し足らずという結果でした。
discussionにチームメイトのKazSappさんが投稿した通り、解法は6モデルの重み付き平均です。
1. bert base uncased 2. rnn 3. rnn (data augmented by translation) 4. rnn (data augmented by old toxic competition) 5. bert base cased 6. bert base multilingual cased w = [0.39193463, 0.14464678, 0.03892303, 0.06871146, 0.317778, 0.038006]
重みは、Kaggle Tokyo Meetup #5 の「Home Credit Default Risk - 2nd place solutions」で知った Scipy Nelder-Mead を用いて CV 最適化しています。
public kernel含めて多くのチームはidentity_columnsの欠損値を0で穴埋めしていたと思いますが、僕らのチームに特徴的なアプローチとしてRNNで予測した値で欠損値を補完していました。今回のデータセットにおける identity_columns の欠損値は単にアノテータ(評価者)がいなかったという意味で、必ずしも0を意味しないと考えたからです。このアイディアはKazSappさんが思いついたもので、こういった自分の手持ちにはなかった手法に辿りつけるのがチーム戦の良いところだなと改めて感じました。
同じくチームメイトのtakuokoさんも、embeddingに関する知見をdiscussion投稿しています。
金メダルを取れなかった点は悔やまれますが、Bertの強さを身に沁みて実感するなど、学びが多いコンペでした。
LightGBMでtargetをsqrt(target)に変換して予測する「reg_sqrt=True」
機械学習の教師あり学習における一つのテクニックとして、学習時の target 変換があります。昨晩に LightGBM の documentation を読んでいたところ、sqrt 限定ですが、target の変換を自動で処理してくれる parameter "reg_sqrt" を(恥ずかしながら初めて)知りました。
本記事では、学習時の target 変換の概要を述べ、LightGBM の parameter "reg_sqrt" を紹介します。
学習時の target 変換とは
target の分布が偏ったり過度に広がっている場合などに効果を発揮し得る手法です。target の各データに対して、log, sqrt を取るなどの変換を加えることで、全体の分布を整える狙いがあります。
例えば筆者が先に参加した地震コンペでは "time_to_failure" という連続値が target になっていました。この target は小さい値のデータが多く、各データに対して sqrt を取ることで、全体の分布を正規分布に近づけることが可能でした。
学習時に target を変換した場合は、当然ですが test の値を予測した後に逆変換の処理が必要になります。例えば sqrt の場合は、予測値を二乗することになります。
target を変換した場合とそうでない場合では、予測の得意・苦手が変わってくる印象があります。例えば地震コンペの場合、sqrt を取った場合は高めの予測値が出づらくなっていました。学習時の target 変換は予測の多様性も生み出すので、アンサンブルの種を作る意味でも試す価値がある認識をしています。
LightGBM の parameter "reg_sqrt"
学習時の target 変換の処理は自分で書いてもさほど難しくないですが、そのせいもあってLightGBM に parameter が用意されているのを知りませんでした。予測値を二乗する処理も自動で行ってくれるので、処理し忘れで的外れなスコアを出すミスも避けられそうです。
- reg_sqrt 🔗︎, default = false, type = bool
- used only in regression application
- used to fit sqrt(label) instead of original values and prediction result will be also automatically converted to prediction^2
- might be useful in case of large-range labels
https://github.com/microsoft/LightGBM/blob/master/docs/Parameters.rst#reg_sqrt
おわりに
本記事では、学習時の target 変換の概要を述べ、LightGBM の parameter "reg_sqrt" を紹介しました。頻繁に使っている LightGBM ですが、改めて documentation を眺めると意外と認知していない parameter や機能追加に気付けるので面白いなと感じました。
「長さの近いデータを同じbatchに入れる」の性能劣化と速度
先のKaggle Tokyo Meetup #6 でのtksさんの発表で触れられた「長さの近いデータを同じbatchに入れる」について、チームで参加した「Jigsaw Unintended Bias in Toxicity Classification | Kaggle」にて同じような取り組みをしていました。
本記事では、Jigsawコンペにおける「長さの近いデータを同じbatchに入れる」処理について、性能劣化と速度の数字を紹介します。なお、あくまで筆者の事例に過ぎない点にはご留意ください。
TL;DR
「長さの近いデータを同じbatchに入れる」処理で、性能は多少落ちるが、速度が大きく向上する
JigsawコンペでのBERT学習時 | 性能(CVスコア) | 速度(s) |
---|---|---|
処理前 | 0.9372215615637538 | 28000 |
処理後 | 0.9365093209503504 | 14000 |
「長さの近いデータを同じbatchに入れる」とは
deep learningなどの機械学習アルゴリズムでは、扱うデータの長さが均一である必要があります。テキストデータは長さがバラバラなので、最大長のデータに合わせて適当な値でデータを埋める(padding)処理が実行されます。この処理は一般に、(下図の例では角丸四角で囲まれた)batch単位で行われます。
下図の左の例は、batch単位でのデータの長さがバラバラの場合を示します。このとき、長さの大小が様々なデータが同一のbatchに含まれており、長さの小さいデータでは最大長までpaddingが実施されています。
ここで事前に各データを長さ順にsortし「長さの近いデータを同じbatchに入れる」場合を考えましょう。各batchでの長さが比較的揃うことで、必要なpaddingの処理が少なくなっています。
メリット
デメリット
- 一方で、長さの近いデータのみを同一のbatchに収めてしまうことで、データに偏りが生じて性能劣化に繋がる可能性があります
実装・解説など
次のブログに、日本語での実装・解説が記載されています。なお末尾に次の文があり、本記事は数値検証の一つの実例としてまとめた側面があります。
余力があれば、
1 ) 精度面でどれだけ悪化するのか
2 ) どれだけ早くなるのか
を比較実験した記事も書きたいなと思います。
数値検証
Jigsawコンペの場合
学習時
冒頭に記載した通り、性能は多少落ちるが、速度が大きく向上するという結果になりました。
BERT学習時 | 性能(CVスコア) | 速度(s) |
---|---|---|
処理前 | 0.9372215615637538 | 28000 |
処理後 | 0.9365093209503504 | 14000 |
なおJigsawコンペではAUCを拡張した少し複雑な評価指標が使われていました。AUCと同様に0-1の値を取り、大きいほど優れた評価指標になっています。
https://www.kaggle.com/c/jigsaw-unintended-bias-in-toxicity-classification/overview/evaluation
推論時
Jigsawコンペでは、モデルの推論をKaggle Kernel内でGPU 2時間 (7200s) に収める必要がありました。推論時にもデータのソートを実施したところ、推論時間が58min -> 25min に短縮されました。
Quoraコンペの場合
tksさんがMeetup後に数値検証した結果、性能は悪化したとのことでした。
昨日の私の発表で「長さ近いのバッチに入れるべき」と述べましたがまちがいでした。長さ近いバッチと普通バッチをsubmitしたら、前者の方が悪かったです。皆さんご指摘ありがとうございました。 pic.twitter.com/JNT1ZFtJiT
— tks0123456789 (@tks0123456789) July 14, 2019
おわりに
本記事では、Jigsawコンペにおける「長さの近いデータを同じbatchに入れる」処理について、性能劣化と速度の数字を紹介しました。あくまで筆者の事例における結果なので一概に結論を述べるのは難しいですが、一定の性能を犠牲にして高速化が実現できた結果となっています。
最近はKaggleにおいても実行時間の制限があるコンペが増えており、学習・推論の実行時間を短縮できるのは十分に価値のあることだと思います。単体モデルとしては性能劣化が生じるものの、例えば浮いた実行時間で複数モデルをアンサンブルするなど、総合的な性能向上が見込めそうです。実サービス運用においても、多少の性能を犠牲にして実行速度を改善したい場面はあり得るので、選択肢の一つに入ってくるかなと考えています。
ありがとうございます!なるほどKaggle的には得られた時間で他のことやるほうが総合的には高スコアになりそうですね〜。
— Nomi (@nyanp) July 14, 2019
Kaggle Tokyo Meetup #6 にて「PetFinder 2nd Place Solution」の題目で発表しました
「Kaggle Tokyo Meetup #6」に参加し、チーム Wodori の一員として「PetFinder 2nd Place Solution」の題目で発表もしました。
本記事では、各発表の簡単な感想などを述べます。twitterの #kaggle_tokyo や kaggler-ja slackの #event-live にも情報が転がっています。
- 「PetFinder 2nd Place Solution」(Wodori)
- 「iMet 7th Place Solution & 画像コンペのアプローチ」(phalanxさん)
- 「Quora Insincere Questions 10th Place Solution & 昔話」(tksさん)
- 「PLAsTiCC 3rd Place Solution」(nyanpさん)
- スポンサーセッション
- LT①「Neural Network のご機嫌取りがしたい」(tawatawaraさん)
- LT②「NLPチュートリアル」(tamakiさん)
- LT③「Freesound Audio Tagging 2019 4th Place Solution」(OUMed: Osciiartさん、jsatoさん)
- LT④「Google Landmark Retrieval 2019 1st Place Solution」(smlyさん)
- LT⑤「Santander Customer Transaction Prediction 2nd Place Solution」(onoderaさん)
- おわりに
「PetFinder 2nd Place Solution」(Wodori)
「iMet 7th Place Solution & 画像コンペのアプローチ」(phalanxさん)
- 後半で述べていたphalanxさんなりの汎用的なmodel pipelineが素晴らしかった
- yamlを書き換えるだけで学習・推論・ログ出力などが自動化されているらしい
- 懇親会で別の画像の強い人とも話したが同様のpipelineを持っているらしく、自分もきちんとコードを整備したいと感じた
「Quora Insincere Questions 10th Place Solution & 昔話」(tksさん)
- jigsawのsolutionとして公開されて気になっていた「exponential moving average」について話題になって、個人的にとても勉強になった
- Kaggle昔話も、知らないことが多くて面白かった
「PLAsTiCC 3rd Place Solution」(nyanpさん)
- コンペの意義から具体的な解法まで、情報量多い解説だった
- 有効だが生成に時間がかかる特徴量を大量にインスタンスを立てて作成するなど、勝負どころでの力強さを感じた
- adversarial pseudo labeling や カテゴリ変数がない場合のCatboostの利用など、将来のコンペで使ってみたいアイディアが多かった
LT①「Neural Network のご機嫌取りがしたい」(tawatawaraさん)
LT③「Freesound Audio Tagging 2019 4th Place Solution」(OUMed: Osciiartさん、jsatoさん)
LT④「Google Landmark Retrieval 2019 1st Place Solution」(smlyさん)
LT⑤「Santander Customer Transaction Prediction 2nd Place Solution」(onoderaさん)
To Be Written.
おわりに
昨年12月に開催された前回は、Kaggle Expertとして参加し、LTをしました。
その後なかなかコンペで良い成績が出せず落ち込んでいた時期もあったのですが、良いチームメイトに恵まれ金メダルを獲得してmeetupで発表できたことは、本当に嬉しいです。
日本でのKaggleの人気・実力が高まっていてmeetup参加の難易度が上がっていますが、ぜひ次回も参加できるようKaggleに精進していきたいと思います。
Kaggle、現状だとmeetup参加する資格ないな( ゚∀゚)・∵.
— u++ (@upura0) February 14, 2019
運営の皆さん、会場スポンサーのDeNAさん、ありがとうございました!