re:newalhttp://blog.flect.co.jp/cloud/からさらに引っ越しています2019-12-23きゅうり画像で回帰問題を解いてみたみなさんこんにちは。技術開発室の岡田です。re:invent2019のレポートをしました。いやー、楽しいイベントだったなー。来年も行きたいなー(と書き続けたら行かせてもらえないだろうか。ちなみに増員はしてもらえそうな雰囲気だった。)cloud.flect.co.jpさて、今回から私の担当している機械学習に関する投稿に戻りますが、今回は「画像から回帰問題を解く」をテーマにしたいと思います。はじめに画像を用いた機械学習といえば分類問題(Classification)が一般的ですが、実は回帰問題(Regression)を解くこともできます。有名なところでは「顔の画像から年齢を推定する」というものが有ります。こちらの記事で詳しく紹介されている方がおられますので、ご参照ください。FLECTでも同様の技術を用いたソリューションを提供しています。詳しくは述べられないのですが、ざっくり一例をご紹介しますと、下記の図はとある工業製品の摩耗状態を画像から判定するモデルになります。この工業製品の摩耗状態はとある指標で定量的に10段階で計測できるのですが、図の横軸が計測した正しい摩耗状態、縦軸が画像から推定した摩耗状態となります。推定ができているように見えると思います。上図ではテストサンプルの件数が多くわかりにくいですが、推定した摩耗状態と実際の摩耗状態の誤差をバイオリンチャートで表現すると次の図のようになっています。縦軸が0を中心に摩耗状態の段階誤差の範囲を示しています。1段階以内の誤差で推定することができています。(自画自賛ですがすごいと思ってる!興味のある方はご連絡を。)この回帰の技術に関連して、ちょっとした実験をしてみましたのでご紹介します。実験の動機まず、実験をしてみた動機からご説明します。みなさんもGoogleなどで検索していただくとわかると思いますが、画像で回帰問題を解くことについてWeb上にはそれほど多くの情報がありません。大体が上記ブログと同様に年齢推定の話です。FLECTでも回帰問題を扱うことになりブログで情報発信をしようと思ってその時にその理由がわかったのですが、業務上扱っているデータは当然あるのですがブログで扱えるような公のデータがないのです(私の観測範囲では)。実験的に何かをしてブログを書くというのが難しかったのではないかと考えています。我々も同じ理由でだいぶ長い間ブログを書けずにいたのですが、あるとき、ぱっと、あることを思い出しました。いえば、昔、きゅうりの仕分け(ランクづけ)を画像分類でやっていた人がいたなぁ、と。それからずっと、このきゅうりのランクを回帰で推定できないか?というのが頭から離れずにいたのですが、この年末幸運にも少し時間が空いたので早速実験をしてみた、ということになります。いうことで、以下、きゅうりのランクを回帰で推定する話をつらつらと書いていきます。repositoryに格納しておきます。Learningを用いてきゅうりの仕分けをするシステムを作りました。当時だいぶバズって、Googleのブログにも特集されています。詳細はこの記事を見ていただくのが良いかと思います。cloudplatform-jp.googleblog.comこの仕分けシステムでは、2LからCまで、きゅうりを9つのランクに仕分けることができるそうです。ありがたい!github.com今回は、この中でもprototype_2の学習用のデータを用いて実験を行いました。このprototype_2は上下側面の3方向からの撮影したデータとなっていますが、今回は上から撮影したもののみを用いることにしました。画像の中には、手が写り込んでいたりする写真などが含まれていますが、これらは事前に取り除きました(OTHERラベルがついている)。一応、分布を確認するとこんな感じに各クラス800枚前後でまんべんなく格納されています。ちなみに横軸の数値は2L〜Cまでのランクに対応づいています。repositoryを参考にしてください。v2を用いてやってみました。ポイントはFlatten()のあとにsoftmaxではなくreluを活性化関数とした全結合層を置くことです。今回はCIFAR10と同じ画像なので、Inputのサイズは32x32x3になります。Dense(1)(x)モデル全体は次のような感じです。ある程度エイヤで作っているネットワークなので、チューニングの余地は有りますので、興味のある方は適当にいじってみるといいと思います。5,216__________________________________________________________________________________________________トレーニングネットワークを定義できたら、トレーニングを開始します。損失関数は今回はMSEにしています。Testでそれぞれ6:2:2に分割しています。こちらもエイヤですがエポック数は200にしています。トレーニングの結果は次の通り。青線がlossでオレンジ線がval_lossです。大体130エポックで収束しているようですね。評価では、トレーニングしたモデルで評価してみましょう。推定ランクをプロットした図です。うまく推定できているように見えます。サンプル数が多いのでどの程度分散しているのかわかりにくいですね。こちらのバイオリンチャートを見ていただきましょう。ご覧になっておわかりになると思いますが、ほぼ正しいランクの位置をてっぺんに正規分布していますね。裾が重いところがあり、他のクラスと認識されてしまっているものが有るようですが、そこそこ正しく推定されたと見て良いと思います。(作成者の方もおっしゃっていますが、人間がやっているのでランク付けもある程度えいやなところがあるらしいので。Workpiles今回の場合は、各分類クラス間が離れていないため、人間がやっても“2LとL”や“LとBL”の判別は難しい(けっこう適当)だったりします。といことで、今回の実験はひとまず成功したかなと思います。画像からの回帰、みなさんもチャレンジしてみてはいかがでしょうか。結果をシェアしてもらえるとありがたいです。推定されたランクは浮動小数点となっていますが、実際のランクは整数値です。この整数値に変換するためにしきい値を決める必要が有ります。デフォルトで小数点第1位が5のところでしきい値にしてもいいですが、このしきい値をいい感じに調整してくれる方法も有ります。今回は画像から回帰をすることろまでが主題となりますので、そこまでは踏み込みません。機会があればご紹介します。v2でクラス分類させたら、全然クラス分類のほうが精度が高かったです。タスクによって解き方をしっかり使い分けることが重要です。この辺の話も機会があれば別途。最後に今回は、きゅうりの画像のランク付けを題材に、画像から回帰問題を解く方法についてご紹介しました。最初にご紹介したとおり、画像から連続値を推定する技術は様々な分野に応用可能であり、FLECTでも実績があります。ご活用いただければありがたいと思います。次回は、また別の技術をご紹介する予定です。EventBridgeにトラスト構想の夢を見るこんにちは、遠藤@Cariot事業部です。