ホーム » Inception

Inception」カテゴリーアーカイブ

TensorFlow (Hub) : Tutorials : Images : 画像分類器を新しいカテゴリーのためにどのように再訓練するか


TensorFlow (Hub) : Tutorials : Images : 画像分類器を新しいカテゴリーのためにどのように再訓練するか (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
更新日時 : 07/16/2018 (v1.9)
再作成日時 : 04/04/2018

* TensorFlow 1.9 でドキュメント構成が変わりましたので調整しました。
* TensorFlow Hub の画像再訓練についてのチュートリアルの翻訳です。これは TensorFlow 全体のチュートリアルの位置づけにもなっていて、転移学習による画像分類器の再訓練を Hub を利用して遂行しています
* 本ページは、TensorFlow の本家サイトの Tutorials – Images – How to Retrain an Image Classifier for New Categories を
翻訳した上で適宜、補足説明したものです:

* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

現代的な物体認識モデルは数百万のパラメータを持ちます。スクラッチからの訓練はラベル付けされた多くの訓練データと多くの計算パワーを必要とします (数百の GPU-hours あるいはそれ以上)。転移学習は関連タスク上で既に訓練されたモデルのピースを取り新しいモデルでそれを再利用することによりこれらの多くをショートカットするテクニックです。このチュートリアルでは、ImageNet 上で訓練されたパワフルな画像分類器から特徴抽出機能を再利用して単純にその上で新しい分類層を訓練します。このアプローチの更なる情報については Decaf のこのペーパー を参照できます。

完全なモデルを訓練するほどには良くありませんが、これは多くのアプリケーションに対して驚くほど効果的で、中くらいの総量の訓練データ (ラベル付けされたデータの数千です、数百万ではありません) でも動作し、そして GPU がないラップトップ上で 30 分程度と少ない時間で実行できます。このチュートリアルは貴方自身の画像でサンプルスクリプトをどのように実行するかを示し、そして訓練プロセスを制御するためのオプションの幾つかを説明します。

このチュートリアルは事前訓練されたモデルのピース、あるいはいわゆるモジュールを摂取するために TensorFlow Hub を利用します。手始めに、ImageNet 上で訓練された Inception V3 アーキテクチャを持つ画像特徴抽出モジュールを使用し、後で NASNet /PNASNet そして MobileNet V1 と V2 を含む、更なるオプションへと戻ります。

 

花の(画像の)上で訓練する

どのような訓練を開始する前でも、ネットワークに認識させたい新しいクラスについて教えるための画像のセットが必要です。どのように貴方自身の画像を準備するかを説明する後のセクションがありますが、最初の利用を簡単にするために creative-commons license の花の画像のアーカイブを作成しました。花の画像のセットを得るためには、これらのコマンドを実行してください :

cd ~
curl -O http://download.tensorflow.org/example_images/flower_photos.tgz
tar xzf flower_photos.tgz

画像をひとたび得たのであれば、サンプルコードを GitHub からダウンロードできます (それはライブラリ・インストールの一部ではありません) :

mkdir ~/example_code
cd ~/example_code
curl -LO https://github.com/tensorflow/hub/raw/r0.1/examples/image_retraining/retrain.py

最も単純なケースでは retrainer はそれからこのように実行できます (およそ 30 分ほどかかります) :

python retrain.py --image_dir ~/flower_photos

このスクリプトは多くの他のオプションを持ちます。以下で完全なリストを得ることができます :

python retrain.py -h

このスクリプトは事前訓練されたモジュールをロードしてその上で新しい分類器を貴方がダウンドードした花の画像のために訓練します。完全なネットワークがその上で訓練された元の ImageNet クラスの中にどの花の種もありません。転移学習の魔法は、幾つかのオブジェクト間を識別するために訓練されたより低い層は多くの認識タスクのために変更なしに再利用可能なことです。

 

ボトルネック

貴方のマシンの速度に依存して、スクリプトは完了するのに 30 分かそれ以上かかるでしょう。最初の段階はディスクの全ての画像を解析してそれらの各々についてボトルネック値を計算してキャッシュします。「ボトルネック」 は、実際に分類を行なう最終出力層のすぐ前の層のためにしばしば使う非公式な用語です。(TensorFlow Hub はこれを「画像特徴ベクトル」と呼びます。) この最後から2番目 (= penultimate) の層は、認識するために問われる全てのクラス間を識別するために使用する分類器のために十分に良い値のセットを出力するために訓練されています。それは画像の意味あるコンパクトな要約でなければならないことを意味しています、何故ならばそれは分類器が値の非常に小さなセットにおいて良い選択を行なうために十分な情報を含まなければならないからです。最終層の再訓練が新しいクラスで動作できる理由は ImageNet の全ての 1,000 クラス間を識別するために必要な情報の類が新しい種類の物体間の識別のためにもしばしば有用であることが判明していることです。

訓練の間全ての画像は複数回再利用されて各ボトルネックの計算はかなりの時間がかかるので、繰り返し再計算する必要がないようにディスク上にこれらのボトルネック値をキャッシュすることで高速化します。デフォルトではこれらは /tmp/bottleneck ディレクトリにストアされ、そしてスクリプトを再実行するならばそれらが再利用されるのでこのパートについては再び待つ必要がありません。

 

訓練する

ボトルネック (の計算) が完了したら、ネットワークのトップ層の実際の訓練が始まります。貴方はステップの系列の出力を見るでしょう、各々の一つは訓練精度、検証精度、そして交差エントロピーを示します。訓練精度は現在の訓練バッチで使用されている画像の何パーセントが正しいクラスでラベル付けされたかを示します。検証精度は異なるセットからのランダムに選択された画像のグループ上の精度です。主な違いは訓練精度はネットワークがそれから学習可能な画像を基にしていることでそのためネットワークは訓練データのノイズに過剰適合 (過学習) する可能性があることです。ネットワークのパフォーマンスの真の尺度は訓練データに含まれないデータセット上のパフォーマンスを計測することです — これは検証精度によって測られます。 訓練精度が高いがしかし検証精度が低いままである場合には、これはネットワークが過剰適合してより一般的には役に立たない、訓練画像の特定の特徴を記憶していることを意味します。交差エントロピーは損失関数で学習プロセスが上手く進んでいるかの一見 (= glimpse) を与えてくれます。訓練の目的は損失をできるだけ小さくすることですから、短期のノイズは無視して、損失が下落傾向を保持しているかどうかを注視することにより学習が動作しているかを識別することができます。

デフォルトではこのスクリプトは 4,000 訓練ステップを実行します。各ステップは訓練セットから無作為に 10 画像を選択し、キャッシュからそれらのボトルネックを見つけて、そして予測を得るための最終層へとそれらを供給します。それからそれらの予測が実際のラベルと比較されて back-propagation プロセスを通して最終層の重みを更新します。プロセスが続くにつれてレポートされる精度が改善されることを見るはずです、そして全てのステップが終わった後で訓練と検証写真から分離されていた画像のセット上で最終的なテスト精度評価が実行されます。このテスト評価は訓練されたモデルが分類タスクでどのように遂行されるかの最良推定値です。訓練プロセスにランダムネスがあるので正確な値は実行毎に変わりますが 90% と 95 % の間の精度値を見るはずです。この数字は、モデルが完全に訓練された後で正しいラベルが与えられたテストセットの画像のパーセントを基にしています。

 

再訓練を TensorBoard で可視化する

スクリプトは TensorBoard summaries を含みます、これは再訓練を理解し、デバッグし、そして最適化することをより容易にします。例えば、重みあるいは精度が訓練の間にどのように変わるか、グラフと統計を可視化できます。

TensorBoard を launch するためには、再訓練の間またはその後でこのコマンドを実行します :

tensorboard --logdir /tmp/retrain_logs

TensorBoard が実行されたら、TensorBoard を見るために web ブラウザを localhost:6006 に navigate してください。

retrain.py スクリプトは TensorBoard summaries をデフォルトでは /tmp/retrain_logs にログ出力します。ディレクトリは –summaries_dir フラグで変更可能です。

TensorBoard の GitHub レポジトリ は TensorBoard 使用法について、チップ (tip) & トリック、そしてデバッギング情報を含むより多くの情報を持ちます。

 

再訓練されたモデルを使用する

スクリプトは貴方のカテゴリー上で訓練された新しいモデルを /tmp/output_graph.pb に、そしてラベルを含むテキストファイルを /tmp/output_labels.txt に書き出します。新しいモデルはそれにインライン化された TF-Hub モジュールと新しい分類層の両者を含んでいます。2つのファイルは両者とも C++ と Python 画像分類サンプル が読み込めるフォーマットにあるので、貴方の新しいモデルを直ちに使用開始することができます。トップ層を置き換えたので、label_image を使用している場合には例えばフラグ –output_layer=final_result によってスクリプトで新しい名前を指定する必要があります。

ここに label_image サンプルを貴方の再訓練したグラフでどのように実行するかのサンプルがあります。慣習的に、総ての TensorFlow Hub モジュールは固定範囲 [0, 1] のカラー値を持つ画像入力を受け取りますので、–input_mean や –input_std フラグを設定する必要はありません。

curl -LO https://github.com/tensorflow/tensorflow/raw/master/tensorflow/examples/label_image/label_image.py
python label_image.py \
--graph=/tmp/output_graph.pb --labels=/tmp/output_labels.txt \
--input_layer=Placeholder \
--output_layer=final_result \
--image=$HOME/flower_photos/daisy/21652746_cc379e0eea_m.jpg

花のラベルのリストを見るはずです、多くの場合トップはひなげし (daisy) です (各再訓練されたモデルは少し異なるかもしれませんが)。–image パラメータを貴方自身の画像でそれらを試すために置き変えることができます。

貴方自身の Python プログラムで再訓練したモデルを使用することを望むのであれば、上の label_image スクリプトは合理的な開始ポイントです。label_image ディレクトリはまた C++ コードを含み、tensorflow を貴方自身のアプリケーションと統合するためにこれをテンプレートとして使用できます。

もしデフォルトの Inception V3 モジュールが貴方のアプリケーションにとって巨大過ぎたり遅過ぎたりする場合には、貴方のネットワークをスピードアップしてスリムにするためのオプションのために後述の「他のモデル・アーキテクチャ」セクションを見てください。

 

貴方自身のカテゴリ上で訓練する

花のサンプル画像上でスクリプトを何とか動作させたならば、代わりに貴方がケアするカテゴリをそれに認識することを教えることに目を向け始めることができます。理論的には必要なことの全てはそれにサブフォルダのセットをポイントさせることで、各々はカテゴリの一つから名前付けられていてそのカテゴリからの画像のみを含みます。それを行なってサブディレクトリ (群) のルート・フォルダを –image_dir への引数として渡せば、スクリプトは花のために行なったように訓練するはずです。

以下が花のアーカイブのフォルダ構造がどのように見えるか、スクリプトが求めるレイアウトの種類の例を与えるものです :

 

 
実際には望むような精度を得るためにはある程度の作業がかかるでしょう。貴方が出会うかもしれない一般的な問題の幾つかを通して下でガイドしてみます。

 

訓練画像のセットを作成する

始める最初の場所は集めた画像に目を向けることです、何故ならば訓練で見る最も一般的な問題は供給されるデータに由来するからです。訓練が上手くいくためには、認識したい物体の各種の 100 の写真は少なくとも集めるべきです。集めれば集めるほど、訓練モデルの精度はより良くなりがちです。写真はアプリケーションが実際に遭遇するものの良い表現であることも確実にすることも必要です。例えば、全ての写真をインドアで開口部のない壁 (= blank wall) に対して撮りそしてユーザが物体をアウトドアで認識しようとするならば、デプロイした時に良い結果を見ることはおそらくないでしょう。回避すべきもう一つの落とし穴は、学習プロセスはラベル付けされた画像が互いに共通に持つ任意のものを拾ってしまうことで、それに注意を払わないのであれば有用ではないものになるでしょう。例えば物体の一つの種類を青い部屋で、他のものを緑色の部屋で撮れば、モデルはその予測を実際に大事にしたい物体の特徴ではなく、背景に基礎を置く結果になります。これを回避するためには、できる限り状況の多様性を広くして、違う時間、そして異なるデバイスで写真を撮ってみてください。

使用するカテゴリについて考えることもまた望むかもしれません。多くの異なる物理的な形をカバーする大きなカテゴリをより視覚的に明確な小さなものに分割する価値はあるかもしれません。例えば、貴方は「乗り物 (vehicle)」の代わりに「自動車 (car)」、「motorbike (バイク)」、そして「トラック (truck)」を使用するかもしれません。あなたは「閉じた世界 (closed world)」を持つのか「開いた世界 (open world)」を持つのかという問題についてもまた考える価値があります。閉じた世界では、カテゴリ分けを要求されるもの全ては既知の物体のクラスです。これは植物認識アプリケーションにも適用されるでしょう、そこではユーザは花の写真を多分撮るであろうことを知っており、従って行なわなければならないことの全てはどの種かを決定することです。対照的に歩き回るロボットは世界をさまよう時にそのカメラを通してあらゆる種類の異なるものを見るでしょう。そのケースでは見たものが不確かであるかを分類器がレポートすることを望むでしょう。これは上手くやるのは難しいですが、しかししばしばもし関連する物体のない数多くの典型的な「背景」写真を集めれば、画像フォルダの特別な「未知の (unknown)」クラスにそれらを追加できるでしょう。

画像全てが正しくラベル付けされていることを確かにするために確認することも価値があります。しばしばユーザ生成タグは私達の目的のためには当てになりません。例えば : #daisy とタグ付けされた写真は Daisy という名前の人々やキャラクターを含むかもしれません。画像を通してどのようなミスも取り除けば全体的な精度に貴方は驚くかもしれません。

 

訓練ステップ

画像に満足するならば、学習プロセスの細部を変更することで結果を改善することに目を向けられるでしょう。試すべきもっとも単純なものは –how_many_training_steps です。このデフォルトは 4,000 ですが、それを 8,000 に増やせば2倍の長さの間訓練します。精度の改善のレートはより長い間訓練すればゆっくりになりますが、あるポイントで全体として止まるでしょう (あるいは overfitting により下がりさえします)、しかし貴方のモデルについてベストで動作するものを見ることを経験できるでしょう。

 

歪める (Distortions)

画像訓練の結果を改善する一般的な方法は訓練入力をランダムな方法で変形し、クロップし、あるいは明るくすることによります。これは同じ画像の全ての可能なバリエーションのおかげで訓練データの効果的なサイズを拡張する優位点を持ち、分類器の現実的な利用で起きる歪みを処理することをネットワークが学習することを助ける傾向にあります。スクリプトでこれらの歪みを有効にする最大の不利益はボトルネック・キャッシングがもはや利用できないことです、何故ならば入力画像はもはや正確には再利用できないからです。これは訓練プロセスが非常に長くなる (数時間) ことを意味しますので、合理的に満足できるモデルを一度得てからモデルの再調整の方法としてこれを試すことを推奨します。

これらの歪みはスクリプトに –random_crop, –random_scale そして –random_brightness を渡すことで有効になります。これらは全てパーセント値で各画像に歪みの各々をどのくらい適用するかを制御します。それらの各々について 5 あるいは 10 の値から始めるのが合理的でそれからどれがアプリケーションに有用であるかを見る実験をします。–flip_left_right はランダムに画像の半分を水平に反転します、これはアプリケーションでそれらの反転が起こりがちであるならば意味があります。例えば文字を認識しようとしているならばそれは良い考えではありません、それらを反転することは意味を破壊しますので。

 

ハイパー・パラメータ

結果に有用であるかを見るために調整を試すことができる幾つかの他のパラメータがあります。–learning_rate は訓練の間に最終層への更新の大きさを制御します。直感的にはこれがより小さければ学習はより長くかかりますが、全体的な精度を助ける結果になります。けれどもいつも事実であるとは限りませんので、貴方のケースで何が動作するかを見るには注意深く実験する必要があります。–train_batch_size は最終層への更新を見積もるために各訓練ステップの間にどれだけの画像が検査されるかを制御します、

 

訓練、検証、そしてテストセット

スクリプトが内部で行なうことの一つは画像のフォルダをポイントさせる時に3つの異なるセットに分割することです。最大のものは通常は訓練セットで、これは訓練の間にネットワークに供給される全ての画像で、その結果はモデルの重みを更新するために使用されます。訓練のために全ての画像を何故使わないのか不思議に思うかもしれませんね?機械学習を行なう時の大きな潜在的な問題はモデルは正しい答えを出すために訓練画像の不適切な詳細を単に記憶してしまうかもしれないことです。例えば、見せられた各写真の背景のパターンを覚えてしまい物体とラベルをマッチさせるためにそれを使用してしまうネットワークを想像できるでしょう。それは訓練の間に前に見た全ての画像上では良い結果を生成できるでしょう、しかし新しい画像では失敗します、何故ならばそれは物体の一般的な特徴を学習しておらず、単に訓練画像の重要でない詳細を記憶しているからです。

この問題は過剰適合 (過学習) として知られ、これを回避するためにデータの一部を訓練プロセスから外へ保持しておき、モデルがそれらを記憶できないようにします。そして過剰適合が起きていないことを確認するためにそれらの画像をチェック用に使用します、何故ならばそれらの上で良い精度を見るならばネットワークが過剰適合してないことの良い兆候ですから。通常の分割は画像の 80% を主要な訓練セットに置いて、10 % を訓練の間に頻繁に検証として実行するために取り分け、そしてそれから最後の 10% を保持しておきます。これは分類器の現実的なパフォーマンスを予測するために頻度は低いですがテストセットとして使用されます。これらの比率は –testing_percentage と –validation_percentage フラグを使用して制御可能です。一般的にはこれらの値はそのデフォルトのままにしておくことが可能です、何故ならばそれらを調整することは訓練へのどのような優位点も通常は見出せないからです。

スクリプトは訓練、検証、そしてテストセットの中で画像を分割するために (完全にランダムな関数よりも) 画像ファイル名を使用することに注意してください。異なる実行において画像が訓練とテストセット間で移動しないことを保証するために行なわれます、何故ならばもしモデルを訓練するために使用された画像が続いて検証セットでも使用されるならば問題となるからです。

検証精度は反復の間に変動することに気がつくかもしれません。この変動の多くは検証セットのランダムなサブセットは各々の検証精度測定のために選択されるという事実から発生します。変動は –validation_batch_size=-1 を選択することにより、訓練時間のある程度の増加を犠牲にして、大きく減じることが可能です。これは各精度計算のために検証セット全体を使用します。

ひとたび訓練が完了したら、テストセットの誤分類された画像を検証することは洞察に満ちていることとして見出すかもしれません。これはフラグ –print_misclassified_test_images を追加することで成されます。これは、画像のどのタイプがモデルにとって最も紛らわしいのか、どのカテゴリが最も識別するのが難しいのかについての感覚を得る手助けとなるでしょう。例えば、特定のカテゴリのあるサブタイプ、またはある通常でない写真角度が特に識別が難しいことをを発見するかもしれません、これはそのサブタイプの更なる訓練画像を追加をすることを奨励するかもしれません。しばしば、誤分類された画像の検証は誤ったラベル付け、低い質、あるいはあいまいな画像のような入力データセットにおけるエラーを指し示すこともあります。けれども、一般的にはテストセットの個々のエラーのピンポイントな修正は回避すべきです、何故ならばそれらは多分 (遥かに大きな) 訓練セットのより一般的な問題を単に反映しているだけだからです。

 

他のモデル・アーキテクチャ

デフォルトではスクリプトは Inception V3 アーキテクチャの事前訓練されたインスタンスを持つ画像特徴抽出モジュールを使用します。これは始めるには良い場所です、何故ならばそれは再訓練スクリプトに対して中くらいの実行時間で高い精度の結果を提供するからです。しかし今 TensorFlow Hub モジュールの更なるオプションを見てみましょう。

一方では、そのリストは NASNet (特に nasnet_large と pnasnet_large) のようなより最近の、パワフルなアーキテクチャを示します。これはある程度特別な精度を与えるでしょう。

その一方で、モバイルデバイスや他のリソースが制限される環境上で貴方のモデルを配備することを意図する場合、遥かにより小さなファイルサイズやより高速なスピード (訓練でもまた) のために少しの精度を交換することを望むかもしれません。そのためには、MobileNet V1 か V2 アーキテクチャを実装する異なるモジュール、あるいはまた nasnet_mobile を試してください。

異なるモジュールでの訓練は簡単です : 単に –tfhub_module フラグをモジュール URL と一緒に渡します、例えば :

python retrain.py \
    --image_dir ~/flower_photos \
    --tfhub_module https://tfhub.dev/google/imagenet/mobilenet_v2_100_224/feature_vector/1

これは MobileNet V2 のベースライン・バージョンを使用するモデルを持つ 9 MB モデルファイルを /tmp/output_graph.pb に作成するでしょう。ブラウザでモジュール URL を開けばモジュール・ドキュメントに案内するでしょう。

もしそれを少しだけ早くすることを望むのであれば、入力画像のサイズを ‘224’ から ‘192’, ‘160’, あるいは ‘128’ ピクセル四方に、あるいは ’96’ (V2 のみ) にまでも削減することができます。より積極的な節約のためには、”特徴 depth” か位置毎のニューロン数を制御するためにパーセント ‘100’, ‘075’, ‘050’, or ‘035’ (それは V1 のためには ‘025’) を選択することができます。重みの数 (そしてそれ故にファイルサイズとスピード) はその分数の自乗で縮小されます。MobileNet V1 ブログ投稿GitHub 上の MobileNet V2 ページ は Imagenet 分類に対するそれぞれのトレードオフについてレポートしています。

Mobilenet V2 は特徴 depth パーセンテージをボトルネック層には適用しません。Mobilenet V1 は行ないました、それは分類層のジョブを小さな depth についてはより厳しいものにしました。タイトなボトルネックの代わりに誤魔化して元の 1001 ImageNet クラスのためのスコアを使用することは役立つでしょうか。モジュール名において mobilenet_v1…/feature_vector を mobilenet_v1…/classification で置き換えることにより単純に試すことができます。

前のように、label_image.py で再訓練されたモデルの総てを利用できます。貴方のモデルが期待する画像サイズを指定する必要があります、例えば :

python label_image.py \
--graph=/tmp/output_graph.pb --labels=/tmp/output_labels.txt \
--input_layer=Placeholder \
--output_layer=final_result \
--input_height=224 --input_width=224 \
--image=$HOME/flower_photos/daisy/21652746_cc379e0eea_m.jpg

再訓練されたモデルのモバイルデバイスへの配備についての更なる情報については、このチュートリアルの codelab バージョン を、特に パート 2 を見てください。これは TensorFlow Lite と (モデル重みの量子化を含む) それが与える追加の最適化について記述しています。

 

以上


TensorFlow : Mobile : TensorFlow Lite へのイントロダクション

TensorFlow : Mobile : TensorFlow Lite へのイントロダクション (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 12/10/2017

* 本ページは、TensorFlow の本家サイトの Mobile – Introduction to TensorFlow Lite を翻訳した上で
適宜、補足説明したものです:

* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

TensorFlow Lite はモバイルと組み込みデバイスのための TensorFlow の軽量ソリューションです。
それは低レイテンシーと小さなバイナリ・サイズで、モバイル機械学習推論を可能にします。
TensorFlow Lite はまた Android Neural Networks API によりハードウェアアクセラレーションもサポートします

TensorFlow Lite は低レイテンシーの獲得のために多くのテクニックを使用します。それはモバイル・アプリのためのカーネルの最適化、事前融合 (pre-fused) された活性化、そして量子化されたカーネルのようなテクニックで、より小さく高速な (固定小数点数学) モデルを可能にします。

TensorFlow Lite ドキュメントの多くは当面は GitHub 上 にあります。

 

TensorFlow Lite は何を含みますか?

TensorFlow Lite は、モバイル・プラットフォームのために調整された、量子化されかつ浮動小数点であるコア演算子のセットをサポートします。それらは性能と量子化された精度を更に拡張するために事前融合された活性化とバイアスを組み込みます。更に、TensorFlow Lite はモデルのカスタム演算を使用することもまたサポートします。

TensorFlow Lite は FlatBuffers に基づく新しいモデルファイルフォーマットを定義します。FlatBuffers はオープンソースの、効率的なクロスプラットフォームのシリアライゼーション・ライブラリです。それは protocol buffers に似ていますが、主な違いは、オブジェクト毎のメモリ割当てとしばしば結合した、データにアクセス可能になる前に FlatBuffers は二次表現への解析/アンパックステップを必要としないことです。また、FlatBuffers のコード・フットプリント (メモリ消費量) は protocol buffers よりも一桁小さいです。

TensorFlow Lite はモバイルに最適化された新しいインタプリタを持ち、これはアプリケーションをスリムで高速に保持するというキーとなる目標を持ちます。インタプリタは最小限のロード、初期化、そして実行遅延を確かなものにするために、静的グラフ順序付け (= graph ordering) とカスタム・メモリアロケーターを使用します。

TensorFlow Lite は、デバイス上で利用可能であれば、ハードウェア・アクセラレーションを利用するためのインターフェイスを提供します。Android O-MR1 の一部としてリリースされた、Android Neural Networks ライブラリを通してそれを行います。

 

新しいモバイル固有ライブラリが何故必要なのでしょう?

機械学習は計算パラダイムを変えています、そしてモバイルと組み込みデバイス上で新しいユースケースの新興のトレンドを見ています。消費者の期待もまた、カメラと音声相互作用モデルにより駆動される、彼らのデバイスとの自然で人間のような相互作用へと傾いています。

この領域の興味を煽っている幾つかの要因があります :

  • シリコン層の革新はハードウェア・アクセラレーションの新しい可能性を可能にし、Android Neural Networks API のようなフレームワークがそれらを活用することを容易にしています。
  • リアルタイム・コンピュータビジョンと音声言語理解における最近の進歩はモバイルに最適化されたベンチマーク・モデル (e.g. MobileNet, SqueezeNet) のオープンソース化につながっています。
  • 広く利用可能なスマート家電がオンデバイス・インテリジェンスのための新しい可能性を作ります。
  • より強固なユーザデータのプライバシーのためのパラダイムへの興味、そこではユーザデータはモバイルデバイスを離れる必要がありません。
  • 「オフライン」ユースケースにサーブする能力、そこではデバイスはネットワークに接続される必要がありません。

私たちは機械学習アプリケーションの次の波はモバイルと組み込みデバイス上で意義のある処理を持つことであると信じます。

 

TensorFlow Lite developer preview ハイライト

TensorFlow Lite は developer preview として利用可能で以下を含みます :

  • 量子化されかつ浮動小数点のコア演算子のセット、それらの多くはモバイル・プラットフォームのために調整されています。これらはカスタム・モデルを作成して実行するために利用可能です。開発者は自身のカスタム演算子を書き、そしてそれらをモデルで使用することもできます。
  • FlatBuffers ベースの新しいモデル・ファイルフォーマット。
  • モバイル上でより高速な実行のために最適化されたカーネルを持つオンデバイス・インタプリタ。
  • TensorFlow で訓練されたモデルを TensorFlow Lite フォーマットに変換するための TensorFlow コンバータ。
  • より小さいサイズ: 総てのサポートされる演算子がリンクされるとき TensorFlow Lite は 300 KB より小さく、InceptionV3 と Mobilenet をサポートするために必要な演算子のみを使用するときには 200 KB よりも少ないです。
  • テスト済みモデル :
    次のモデルの総ては動作することが保証されてすぐに使用できます :

    • Inception V3、画像に存在する有力なオブジェクトを検知するためのポピュラーなモデルです。
    • MobileNet、オンデバイスや組み込みアプリケーションのための制限されたリソースに配慮しながら、効率的に精度を最大化するために設計されたモバイルファーストなコンピュータ・ビジョン・モデルのファミリーです。それらは、様々なユースケースのリソース制約に適合するためにパラメータ化された、小さく、低レイテンシーな、低消費電力モデルです。MobileNet モデルは Inception V3 よりも小さくしかし 精度がより低い です。
    • On Device Smart Reply、文脈的に関連するメッセージを提案することにより受信したテキスト・メッセージのためのワンタッチな返信を提供するオンデバイス・モデルです。モデルは時計やスマホのようなメモリ制約のあるデバイスのために特に構築されていて、Android Wear 上の Smart Replies を総ての first-party と third-party アプリケーションへと舗装するために成功的に使用されています。
  • MobileNet モデルの量子化されたバージョン、これは非量子化 (浮動小数点) バージョンよりもより高速に動作します。
  • 物体分類のための量子化された MobileNet モデルによる TensorFlow Lite の利用を示すための新しい Android デモアプリケーション。
  • Java と C++ API サポート。

[注意] これは開発者リリースで、来たるバージョンでは API の変更があるかもしれません。
このリリースとの後方あるいは前方互換性は保証しません。

 

Getting Started

上で示された事前テストされたモデルで TensorFlow Lite を試すことをお勧めします。
既存のモデルを持つのであれば、モデルがコンバータとサポートされる演算子セットの両者と互換であるかをテストする必要があります。モデルをテストするためには、GitHub 上のドキュメント を見てください。

カスタム・データセットのために Inception-V3 あるいは MobileNet を再訓練する

上で言及した事前訓練されたモデルは、事前定義された 1000 クラスから成る ImageNet データセット上で訓練されています。これらのクラスが貴方のユースケースにとって関連がないか有用でないのであれば、それらのモデルを再訓練する必要があるでしょう。このテクニックは転移学習と呼ばれ、これはある問題について既に訓練されたモデルから始めて、そしてそれは類似の問題について再訓練されます。スクラッチからの深層学習は数日かかりますが、転移学習はかなり迅速に完了できます。これを行なうためには、関連するクラスでラベル付けされたカスタム・データセットを生成する必要があります。

TensorFlow for Poets codelab はこのプロセスを一歩ずつ歩き通します。再訓練コードは浮動小数点と量子化された推論の両者のための再訓練をサポートします。

 

TensorFlow Lite アーキテクチャ

次のダイアグラムは TensorFlow Lite のアーキテクチャ的なデザインを示します :

 
ディスク上の訓練済みの TensorFlow モデルから始めて、TensorFlow Lite コンバータを使用してそのモデルを TensorFlow Lite ファイルフォーマット (.tflite) に変換します。 それから貴方のモバイル・アプリケーションでその変換されたファイルが使用できます。

TensorFlow Lite モデルファイルの配備には以下を使用します :

  • Java API: Android 上 C++ API 回りの便利なラッパーです。
  • C++ API: TensorFlow Lite モデルファイルをロードしてインタプリタを起動します。Android と iOS の両者で同じライブラリが利用可能です。
  • インタプリタ: カーネルのセットを使用してモデルを実行します。インタプリタは選択的カーネル・ローディング (= selective kernel loading) をサポートします; カーネルなしではそれは 100 KB だけで、そして総てのカーネルをロードすると 300 KB です。TensorFlow Mobile により必要とされる 1.5 M から意義深い削減です。
  • Android デバイスの選択においては、ハードウェア・アクセラレーションのためにインタプリタは Android Neural Networks API を使用し、利用できるものがない場合にはデフォルトで CPU 実行を選択します。

インタプリタにより使用可能な C++ API を利用してカスタムカーネルを実装することもできます。

 

Future Work

将来のリリースでは、TensorFlow Lite は更なるモデルと組み込み演算子をサポートし、固定小数点と浮動小数点モデルの両者のための性能改善、開発者ワークフローを容易にするツールの改善そして他のより小さなデバイスのためのサポート等々を含むでしょう。(私たちが) 開発を続けるにつれて、TensorFlow Lite が小さなデバイスのためのモデルを対象とした開発者の経験を大きく単純化することを望んでいます。

将来の計画は、特定のデバイス上の特定のモデルのために最善の可能な性能を得るために特殊な機械学習ハードウェアを使用することを含みます。

 

Next Steps

developer プレビューについては、ドキュメントの殆どは GitHub 上にあります。
更なる情報とコードサンプル、デモ・アプリケーション等については GitHub 上の TensorFlow Lite レポジトリ を見てください。

 

以上

Keras / TensorFlow : MobileNet と Inception-ResNet の概要と性能評価

Keras / TensorFlow : MobileNet と Inception-ResNet の概要と性能評価
作成 : (株)クラスキャット セールスインフォメーション
作成日時 : 12/09/2017

 

MobileNet は 6 月に Google Research Blog でアナウンスされたモデルで、TF-Slim 用のモデルのチェックポイントも併せて公開されました。その名前から分かるように、モバイルや組み込み用アプリケーションのようなリソースに制約のある環境でも上手く動作するように設計されたモデルです。

Keras 実装の MobileNet も Keras 2.0.6 から利用可能になりましたので、今回は University of Oxford の VGG が提供している 102 Category Flower Dataset を題材にして、MobileNet の性能を評価してみます。

また、Keras 2.0.9 から Inception-ResNet の実装も提供されていますので、併せて評価します。
比較対象は定番の AlexNet, Inception-v3, ResNet-50, Xception を利用します。

 

MobileNet 概要

MobileNet は6月に Google Research Blog で発表されました :

併せて TF-Slim のチェックポイントファイルと技術ペーパーも公開されています (後述)。

上のブログ記事を簡単に要約しておきますと :

  • 近年、ニューラルネットワークが視覚認識技術の最先端を推し進めることで、深層学習はコンピュータ・ビジョンの大きな進歩に貢献してきました。
  • 物体、ランドマーク、ロゴやテキスト認識のような視覚認識技術の多くが Cloud Vision API を通してインターネット接続デバイスに提供されていますが、他方、モバイル・デバイスの増え続ける計算パワーは (いつでもどこでも、インターネット接続に関わらず、) これらの技術をユーザの手に配布可能です。
  • けれども、モバイルや組み込みアプリケーション上の視覚認識には多くの課題があります — モデルはリソース制約のある環境で、i.e. 制限された計算力、消費電力やストレージのみを使用して高い精度で迅速に動作しなければなりません。
  • 今日、モバイルや組み込みアプリケーションのための制限されたリソースに留意する一方で、精度を効率的に最大化するためにデザインされた、TensorFlow のためのモバイル・ファーストなコンピュータ・ビジョン・モデルのファミリである、MobileNet のリリースを発表します
  • MobileNet は様々なユースケースのリソース制約に適合するためにパラメータ化された、小さく、低遅延で低消費電力なモデルです。Inception のような他のポピュラーなラージスケール・モデルが使用される方法と同様にして、このモデルは分類・検出・埋め込みやセグメンテーションのために構築可能です。
  • このリリースは TF-Slim を使用した TensorFlow 実装の MobileNet のためのモデル定義を含みます。そしてあらゆるサイズのモバイル・プロジェクトでの利用のために、16 個の事前訓練された ImageNet 分類チェックポイントも含んでいます。モデルは TensorFlow Mobile によってモバイル・デバイス上で効率的に実行可能です。

そして参照先として :

 

Inception-ResNet 概要

本記事の主題ではありませんが Inception-ResNet の基本的な発想は、
(誰しも考えることですが) Inception アーキテクチャに残差接続を導入するメリットがあるか否かです。
詳細については以下のペーパーを参照してください :

abstract だけ翻訳しておきます :

近年、非常に深い畳み込みネットワークは画像認識性能における最大限の進歩の中心で在り続けています。一つの例は Inception アーキテクチャであり、これは比較的低い計算コストで非常に良い性能を獲得できることを示してきました。最近、より伝統的なアーキテクチャと結合した残差接続の導入は 2015 ILSVRC チャレンジにおいて最先端の性能を生成しました ; その性能は最新世代 Inception-v3 ネットワークと同様のものです。このことは、Inception アーキテクチャを残差接続と結合するメリットがあるかどうかという疑問を生じます。ここで、残差接続を有するトレーニングは Inception ネットワークのトレーニングを本質的に加速するという明確な実証的なエビデンスを与えます。残差 Inception ネットワークが、thin margin による残差接続がない高コストな Inception ネットワークよりも同様に優れていることの何某かのエビデンスもまたあります。残差と非残差 (= non-residual) Inception ネットワークの両者に対して幾つかの新しい合理化されたアーキテクチャも提示します。これらのバリエーションは ILSVRC 2012 分類タスクにおいて単一フレームの認識性能を本質的に改善します。更に、正当な活性化スケーリングが非常にワイドな残差 Inception ネットワークのトレーニングをどのように安定させるかも示します。3つの残差と1つの Inception-v4 のアンサンブルで、ImageNet 分類 (CLS) チャレンジのテストセット上で 3.08 パーセント top-5 エラーを獲得しました。

 

データセット : 102 Category Flower Dataset

今回の題材は、University of Oxford の VGG が提供している、102 Category Flower Dataset です。
以下は最初の 100 画像ほどを示しています :

 

トレーニングと評価

MobileNet, Inception-ResNet の他にも、比較のために AlexNet, Inception-v3, ResNet-50, Xception も同じ条件でトレーニングして評価してみました。

※ MobileNet のハイパー・パラメータは (Keras 実装の) デフォルト値を使用しています。
※ トレーニングは 100 エポックを上限に実行しています。

損失

エポック数に対する収束の速さは、AlexNet を別にすれば、
Xception, Inception-ResNet, MobileNet > ResNet-50, Inception といったところでしょうか。
いずれも 0 にきれいに漸近しています :

検証精度

検証精度は Inception-ResNet > Xception > Inception-v3 = MobileNet > ResNet-50 です。
これは予想通りの結果と言えましょう :

テスト精度

テスト精度も検証精度と同様ですが、Inception-v3 の方が MobileNet よりも多少良い感じです :
Inception-ResNet > Xception > Inception-v3 >= MobileNet > ResNet-50。

AlexNet 64.12 %
Inception-ResNet 88.24 %
Inception-v3 80.78 %
MobileNet 77.84 %
ResNet-50 73.63 %
Xception 84.12 %

パラメータ数

MobileNet の強みの一つはその (トレーニング可能な) パラメータ数にあります。
比較的新しいモデルのパラメータ数は 20 million が一つの目安ですが、MobileNet は僅か 3.3 million です。
逆に Inception-ResNet は 54 million あります :

AlexNet 22,000,294 
Inception-ResNet 54,432,966 
Inception-v3 21,977,350 
MobileNet 3,311,526 
ResNet-50 23,743,590 
Xception 21,015,950 

トレーニングの速さ

パラメータ数の少なさはトレーニングの速さに直結します。
以下は 1 ステップあたりにかかる時間と、1 時間に遂行可能なステップ数を算出したものです :

alexnet 1.30 min/step 46.41 steps / hour
inception_resnet 19.84 min/step 3.02 steps / hour
inception_v3 9.60 min/step 6.25 steps / hour
mobilenet 3.52 min/step 17.07 steps / hour
resnet50 11.34 min/step 5.29 steps / hour
xception 10.35 min/step 5.80 steps / hour

以下は後者 (1 時間に遂行可能なステップ数) を視覚化したものです。
(AlexNet を別にすれば、) MobileNet のトレーニング効率が高いことが分かります :

 

以上

TensorFlow : Deploy : TensorFlow Serving と Kubernetes で Inception モデルをサービス提供する

TensorFlow : Deploy : TensorFlow Serving と Kubernetes で Inception モデルをサービス提供する (翻訳)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 09/09/2017

* 本ページは、TensorFlow 本家サイトの Deploy : TensorFlow Serving – Serving Inception Model with TensorFlow Serving and Kubernetes を翻訳した上で適宜、補足説明したものです:

* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

このチュートリアルでは、Docker コンテナで動作する TensorFlow Serving コンポーネントを TensorFlow Inception モデルをサービス提供するためにどのように使用するかそして serving クラスタを Kubernetes でどのように配備するかを示します。

TensorFlow Serving についてより学習するためには、TensorFlow Serving 基本チュートリアルTensorFlow Serving 上級チュートリアル を推奨します。

TensorFlow Inception モデルについてより学習するためには、Inception in TensorFlow を推奨します。

  • パート 0 は配備のための TensorFlow Serving Docker イメージをどのように作成するかを示します。
  • パート 1 はローカル・コンテナでイメージをどのように実行するかを示します。
  • パート 2 は Kubernetes でどのように配備するかを示します。

 

パート 0: Docker イメージを作成する

TensorFlow Serving Docker イメージを構築することについての詳細は Using TensorFlow Serving via Docker を参照してください。

コンテナを実行する

Dockerfile.devel を使用してベースイメージ $USER/tensorflow-serving-devel を構築します。そしてビルド・イメージを使用してコンテナをローカルでスタートさせます。

$ docker build --pull -t $USER/tensorflow-serving-devel -f tensorflow_serving/tools/docker/Dockerfile.devel .
$ docker run --name=inception_container -it $USER/tensorflow-serving-devel

コンテナで TensorFlow Serving を clone、configure そしてビルドする

Note: 後述のすべての bazel ビルド・コマンドは標準的な -c opt フラグを使用します。ビルドをさらに最適化するためには、ここの手順 を参照してください。

実行中のコンテナ内で、clone して configure して、そして TensorFlow Serving サンプル・コードをビルドします。

root@c97d8e820ced:/# git clone --recurse-submodules https://github.com/tensorflow/serving
root@c97d8e820ced:/# cd serving/tensorflow
root@c97d8e820ced:/serving/tensorflow# ./configure
root@c97d8e820ced:/serving# cd ..
root@c97d8e820ced:/serving# bazel build -c opt tensorflow_serving/example/...

次に TensorFlow ModelServer を ここの手順 を使用して apt-get でインストールするか、以下を使用して ModelServer バイナリをビルドします :

root@c97d8e820ced:/serving# bazel build -c opt tensorflow_serving/model_servers:tensorflow_model_server

このチュートリアルの残りでは貴方が ModelServer をローカルでコンパイルしたことを仮定します、その場合はそれを実行するためにコマンドは bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server です。けれどももし apt-get を使用して ModelServer をインストールした場合には、単にそのコマンドを tensorflow_model_server で置き換えてください。

コンテナで Inception モデルをエクスポートする

実行中のコンテナで、リリースされた Inception モデル訓練チェックポイント を使用して inception モデルをエクスポートするために inception_saved_model.py を実行します。ゼロから訓練する代わりに、推論グラフをリストアしてそれを直接エクスポートするために良く訓練された variable の容易に利用可能なチェックポイントを使用します。

root@c97d8e820ced:/serving# curl -O http://download.tensorflow.org/models/image/imagenet/inception-v3-2016-03-01.tar.gz
root@c97d8e820ced:/serving# tar xzf inception-v3-2016-03-01.tar.gz
root@c97d8e820ced:/serving# ls inception-v3
README.txt  checkpoint  model.ckpt-157585
root@c97d8e820ced:/serving# bazel-bin/tensorflow_serving/example/inception_saved_model --checkpoint_dir=inception-v3 --output_dir=inception-export
Successfully loaded model from inception-v3/model.ckpt-157585 at step=157585.
Successfully exported model to inception-export
root@c97d8e820ced:/serving# ls inception-export
1
root@c97d8e820ced:/serving# [Ctrl-p] + [Ctrl-q]

配備のためにイメージを Commit

上の手順の最後で (コンテナを) 停止する代わりにコンテナからデタッチしていることに注意してください、何故ならば Kubernetes 配備のために総ての変更を新しいイメージ $USER/inception_serving に commit したいからです。

$ docker commit inception_container $USER/inception_serving
$ docker stop inception_container

 

パート 1: ローカル Docker コンテナ内で実行する

ビルドしたイメージを使用して serving ワークフローをローカルでテストしましょう。

$ docker run -it $USER/inception_serving

サーバをスタートする

コンテナで gRPC tensorflow_model_server を実行する。

root@f07eec53fd95:/# cd serving
root@f07eec53fd95:/serving# bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server --port=9000 --model_name=inception --model_base_path=inception-export &> inception_log &
[1] 45

サーバに問い合わせる

inception_client.py でサーバに問い合わせます。クライアントはコマンドライン・パラメータで指定された画像を ImageNet カテゴリの人間に読める説明への分類のために gRPC を通してサーバに送ります。

root@f07eec53fd95:/serving# bazel-bin/tensorflow_serving/example/inception_client --server=localhost:9000 --image=/path/to/my_cat_image.jpg
outputs {
  key: "classes"
  value {
    dtype: DT_STRING
    tensor_shape {
      dim {
        size: 1
      }
      dim {
        size: 5
      }
    }
    string_val: "tiger cat"
    string_val: "Egyptian cat"
    string_val: "tabby, tabby cat"
    string_val: "lynx, catamount"
    string_val: "Cardigan, Cardigan Welsh corgi"
  }
}
outputs {
  key: "scores"
  value {
    dtype: DT_FLOAT
    tensor_shape {
      dim {
        size: 1
      }
      dim {
        size: 5
      }
    }
    float_val: 9.5486907959
    float_val: 8.52025032043
    float_val: 8.05995368958
    float_val: 4.30645561218
    float_val: 3.93207240105
  }
}

root@f07eec53fd95:/serving# exit

 
動きました!サーバは貴方の猫の画像を成功的に分類しました。

 

パート 2: Kubernetes 内で配備する

このセクションでは Google Cloud Platform において Kubernetes で serving クラスタを配備するためにパート 0 でビルドしたコンテナ・イメージを使用します。

GCloud プロジェクト・ログイン

ここでは貴方が tensorflow-serving という名前の gcloud project を作成してログインしていることを仮定しています。

$ gcloud auth login --project tensorflow-serving

コンテナ・クラスタを作成する

最初にサービス配備のために Google Container Engine クラスタを作成します。

$ gcloud container clusters create inception-serving-cluster --num-nodes 5
Creating cluster inception-serving-cluster...done.
Created [https://container.googleapis.com/v1/projects/tensorflow-serving/zones/us-central1-f/clusters/inception-serving-cluster].
kubeconfig entry generated for inception-serving-cluster.
NAME                       ZONE           MASTER_VERSION  MASTER_IP        MACHINE_TYPE   NODE_VERSION  NUM_NODES  STATUS
inception-serving-cluster  us-central1-f  1.1.8           104.197.163.119  n1-standard-1  1.1.8         5          RUNNING

 
gcloud container コマンドのためのデフォルト・クラスタを設定して kubectl にクラスタ credentials を渡します。

$ gcloud config set container/cluster inception-serving-cluster
$ gcloud container clusters get-credentials inception-serving-cluster
Fetching cluster endpoint and auth data.
kubeconfig entry generated for inception-serving-cluster.

Docker イメージをアップロードする

さて私たちのイメージを Google Cloud Platform 上でそれを実行できるように Google Container Registry に push しましょう。

最初に Container Registry フォーマットとプロジェクト名を使用して $USER/inception_serving イメージにタグ付けします、

$ docker tag $USER/inception_serving gcr.io/tensorflow-serving/inception

次にイメージをレジストリに push します。

$ gcloud docker -- push gcr.io/tensorflow-serving/inception

Kubernetes Deployment とサービスを作成する

配備は、Kubernetes Deployment で制御される inception_inference サーバの3つのレプリカから成ります。レプリカは Kubernetes サービス により External ロードバランサと共に外部的に晒されます。

サンプル Kubernetes config inception_k8s.yaml を使用してそれらを作成します。

$ kubectl create -f tensorflow_serving/example/inception_k8s.yaml
deployment "inception-deployment" created
service "inception-service" created

deployment と pods のステータスを見るためには :

$ kubectl get deployments
NAME                    DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
inception-deployment    3         3         3            3           5s
$ kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
inception-deployment-bbcbc   1/1       Running   0          10s
inception-deployment-cj6l2   1/1       Running   0          10s
inception-deployment-t1uep   1/1       Running   0          10s

サービスのステータスを見るためには :

$ kubectl get services
NAME                    CLUSTER-IP       EXTERNAL-IP       PORT(S)     AGE
inception-service       10.239.240.227   104.155.184.157   9000/TCP    1m

総てがアップして実行中になるにはしばらくかかります。

$ kubectl describe service inception-service
Name:           inception-service
Namespace:      default
Labels:         run=inception-service
Selector:       run=inception-service
Type:           LoadBalancer
IP:         10.239.240.227
LoadBalancer Ingress:   104.155.184.157
Port:           <unset> 9000/TCP
NodePort:       <unset> 30334/TCP
Endpoints:      <none>
Session Affinity:   None
Events:
  FirstSeen LastSeen    Count   From            SubobjectPath   Type        Reason      Message
  --------- --------    -----   ----            -------------   --------    ------      -------
  1m        1m      1   {service-controller }           Normal      CreatingLoadBalancer    Creating load balancer
  1m        1m      1   {service-controller }           Normal      CreatedLoadBalancer Created load balancer

サービス外部 IP アドレスは LoadBalancer Ingress のすぐ次にリストされています。

モデルを問い合わせる

今、ローカルホストから (サービスの) 外部アドレスのサービスを問い合わせることができます。

$ bazel-bin/tensorflow_serving/example/inception_client --server=104.155.184.157:9000 --image=/path/to/my_cat_image.jpg
outputs {
  key: "classes"
  value {
    dtype: DT_STRING
    tensor_shape {
      dim {
        size: 1
      }
      dim {
        size: 5
      }
    }
    string_val: "tiger cat"
    string_val: "Egyptian cat"
    string_val: "tabby, tabby cat"
    string_val: "lynx, catamount"
    string_val: "Cardigan, Cardigan Welsh corgi"
  }
}
outputs {
  key: "scores"
  value {
    dtype: DT_FLOAT
    tensor_shape {
      dim {
        size: 1
      }
      dim {
        size: 5
      }
    }
    float_val: 9.5486907959
    float_val: 8.52025032043
    float_val: 8.05995368958
    float_val: 4.30645561218
    float_val: 3.93207240105
  }
}

 
Kubernetes のサービスとしてサーブする Inception モデルを成功的に配備しました!

 
以上


TensorFlow : 画像分類 : ResNet, Inception-v3, Xception 比較

TenosorFlow : 画像分類 : ResNet, Inception-v3, Xception 比較

作成 : (株)クラスキャット セールスインフォメーション
日時 : 05/17/2017

 

ImageNet のような現実的なサイズのデータセットに対して既存の CNN モデルを利用する場合、Inception を利用するか ResNet を利用するか選択に迷うことも多いでしょう。更には Xception も選択肢に入れることが可能になりました。

そこで比較的モデルの規模感が類似している Inception-v3, ResNet-50 そして Xception を定番の2つのデータセットで訓練して損失と精度グラフを比較してみました。(参考のために AlexNet も試しています。)

* Inception-v4 (Inception-ResNet) についてはまたいずれ試す予定です。

Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning
Christian Szegedy, Sergey Ioffe, Vincent Vanhoucke, Alex Alemi
(Submitted on 23 Feb 2016 (v1), last revised 23 Aug 2016 (this version, v2))

 

Xcetpion 概要

Inception や ResNet は良く知られていますのでここでは Xception についてのみ簡単に補足説明しておきます。Xception は François Chollet 氏が考案したモデルですが “Xception” は “Extreme Inception” を意味するそうです :

Xception: Deep Learning with Depthwise Separable Convolutions
François Chollet
(Submitted on 7 Oct 2016 (v1), last revised 4 Apr 2017 (this version, v3))

ここでは Abstract の翻訳のみを掲載しておきます :

畳込みニューラルネットワークの Inception モジュールの標準的な畳込みと depthwise separable convolution 演算 (pointwise convolution が追随する depthwise convolution) の間の中間的なステップとしての解釈を提案します。この観点からは、depthwise separable convolution は最大限の数のタワーを持つ Inception モジュールとして理解されます。この観察は Inception によりインスパイアされた新しい深層畳込みニューラルネットワーク・アーキテクチャの提案へと導かれ、そこでは Inception モジュールは depthwise separable convolutions に置き換えられます。Xception と呼称する、このアーキテクチャは (Inception V3 がそのために設計された) ImageNet データセット上で Inception V3 より僅かに優れた性能で、そして 350 million 画像と 17,000 クラスから成るより大きな画像分類データセット上では本質的に優れた性能であることを示します。Xception アーキテクチャは Inception V3 と同じ数のパラメータを持つので、パフォーマンス・ゲインは増加したキャパシティによるものではなくモデル・パラメータのより効率的な使用によるものです。

Xception はパラメータ削減によるモデル軽量化を目指す方向性を取っていますが、簡単に言えば Inception の改良版です。Inception モジュールも包括するアーキテクチャとして提案されています。

具体的には、Inception モジュールを全体的に depthwise separable convolution 層をベースに置き換えた線形スタックですが、前提条件として、畳込みニューラルネットワークの特徴マップにおける cross-channels correlations と spatial correlations のマッピングは完全に切り離すことができるという仮説を採用しています。

 

ImageNet : 5 flowers synsets

最初に(TensorFlow と一緒に提供されている、)ImageNet の5つの flowers synsets – daisy, dandelion, roses, sunflowers, tulips – を題材として、ResNet-50, Inception-v3, Xception モデルを訓練してみました。比較参考のために AlexNet も併せて訓練しています。

細かいハイパーパラメータは省きますが、AlexNet は(短時間で訓練可能なので)500 epochs 訓練し、他は 200 epochs 訓練しました。

損失比較

どれもきれいに損失は減少しますが、強いて言えば、AlexNet は振動が大きく、また ResNet-50 は減少が比較的緩やかです。

AlexNet

ResNet-50

Inception-v3

Xception

テスト精度比較

テスト精度は(損失から推測できるように)AlexNet は振動が激しく、ResNet-50 は緩やかに上昇します。
最後の 10 epochs のテスト精度としてはおおよそ : AlexNet : 81 %; ResNet-50 : 82 %; Inception-v3 : 87 %; Xception : 90 % が得られました。

AlexNet

ResNet-50

Inception-v3

Xception

 

University of Oxford: 17 Category Flower Dataset

続いて、University of Oxford が提供している古典的な題材を使用しました。データセットの詳細は 17 Category Flower Dataset を参照してください。

損失比較

損失はいずれもきれいに減少しますが、Xception は訓練中に損失 0 を叩き出しました。

AlexNet

ResNet-50

Inception-v3

Xception

テスト精度比較

AlexNet と Inception-v3 については明らかに over-fitting が見られました。 
(over-fitting 前の) 最後の 10 epochs のテスト精度としてはおおよそ : AlexNet : 79 %; ResNet-50 : 80 %; Inception-v3 : 79 – 80 %; Xception : 89 – 90 % が得られました。

AlexNet

ResNet-50

Inception-v3

Xception

 

以上



TensorFlow : Tutorials : Inception の最終層を新しいカテゴリーのためにどのように再訓練するか

TensorFlow : Tutorials : Inception の最終層を新しいカテゴリーのためにどのように再訓練するか (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 04/10/2017

* 本ページは、TensorFlow の本家サイトの Tutorials – How to Retrain Inception’s Final Layer for New Categories を
翻訳した上で適宜、補足説明したものです:
    https://www.tensorflow.org/tutorials/image_retraining
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

現代的な物体認識モデルは数百万のパラメータを持ち完全に訓練するためには数週間かかります。転移学習は完全に訓練済みのモデルを ImageNet のようなカテゴリのセットに利用してこれらの作業の多くをショートカットするテクニックで、既存の重みから新しいクラスのために再訓練します。本稿の例では、最終層をスクラッチから再訓練しますが、全ての他のものはさわらずにそのままにしておきます。このアプローチの更なる情報については Decaf のこのペーパー を参照できます。

完全な訓練を実行するほどには良くありませんが、多くのアプリケーションに対して驚くほど効果的で、そして GPU を必要とすることなく、ラップトップ上で早ければ 30 分のうちに実行可能です。このチュートリアルは貴方自身の画像でサンプルスクリプトをどのように実行するかを示し、そして訓練プロセスを制御するためのオプションの幾つかを説明します。

 

花の(画像の)上で訓練する

どのような訓練を開始する前でも、ネットワークに認識させたい新しいクラスについて教えるための画像のセットが必要です。どのように貴方自身の画像を準備するかを説明する後のセクションがありますが、最初の利用を簡単にするために creative-commons license の花の画像のアーカイブを作成しました。花の画像のセットを得るためには、これらのコマンドを実行してください :

cd ~
curl -O http://download.tensorflow.org/example_images/flower_photos.tgz
tar xzf flower_photos.tgz

画像をひとたび得たのであれば、retrainer を次のようにビルドできます、TensorFlow ソース・ディレクトリのルートからです :

bazel build tensorflow/examples/image_retraining:retrain

AVX 命令セット (common in x86 CPUs produced in the last few years) をサポートするマシンを持つならば、次のように (configure で適切なオプション選択後)、そのアーキテクチャのためにビルドすることによって再訓練の実行速度を改善できます :

bazel build --config opt tensorflow/examples/image_retraining:retrain

そして retrainer は次のように実行できます :

bazel-bin/tensorflow/examples/image_retraining/retrain --image_dir ~/flower_photos

このスクリプトは事前訓練された Inception v3 モデルをロードし、古いトップ層を取り除き、そしてダウンロードした花の写真で新しいものを訓練します。

どの花の種 (species) も、完全なネットワークが訓練された元の ImageNet クラスにはありません。転移学習のマジックは幾つかの物体間を識別するために訓練されたより低い層(群) が変更なしで多くの認識タスクに再利用できることです。

 

ボトルネック

貴方のマシンの速度に依存して、スクリプトは完了するのに 30 分かそれ以上かかるでしょう。最初の段階はディスクの全ての画像を解析してそれらの各々についてボトルネック値を計算します。「ボトルネック」 は、実際に分類を行なう最終出力層のすぐ前の層のためにしばしば使う非公式な用語です。この最後から2番目 (= penultimate) の層は、認識するために問われる全てのクラス間を識別するために使用される分類器のために十分に良い値のセットを出力するために訓練されています。それは画像の意味あるコンパクトな要約でなければならないことを意味しています、何故ならばそれは分類器が値の非常に小さなセットにおいて良い選択を行なうために十分な情報を含まなければならないからです。最終層の訓練が新しいクラスで動作できる理由は ImageNet の全ての 1,000 クラス間を識別するために必要な情報の種類が新しい種類の物体間の識別のためにもしばしば有用であることが判明していることです。

訓練の間全ての画像は複数回再利用されて各ボトルネックの計算はかなりの時間がかかるので、繰り返し再計算する必要がないようにディスク上にこれらのボトルネック値をキャッシュすることで高速化します。デフォルトではこれらは /tmp/bottleneck ディレクトリにストアされ、そしてスクリプトを再実行するならばそれらが再利用されるのでこのパートについては再び待つ必要がありません。

 

訓練する

ボトルネック (の計算) が完了したら、ネットワークのトップ層の実際の訓練が始まります。貴方はステップの系列の出力を見るでしょう、各々の一つは訓練精度、検証精度、そして交差エントロピーを示します。訓練精度は現在の訓練バッチで使用されている画像の何パーセントが正しいクラスでラベル付けされたかを示します。検証精度は異なるセットからのランダムに選択された画像のグループ上の精度です。主な違いは訓練精度はネットワークがそれから学習可能な画像を基にしていることでそのためネットワークは訓練データのノイズに過剰適合 (過学習) する可能性があることです。ネットワークのパフォーマンスの真の尺度は訓練データに含まれないデータセット上のパフォーマンスを計測することです — これは検証精度によって測られます。 訓練精度が高いがしかし検証精度が低いままである場合には、これはネットワークが過剰適合してより一般的には役に立たない、訓練画像の特定の特徴を記憶していることを意味します。交差エントロピーは損失関数で学習プロセスが上手く進んでいるかの一見を与えてくれます。訓練の目的は損失をできるだけ小さくすることですから、短期のノイズは無視して、損失が下落傾向を保持しているかどうかを注視することにより学習が動作しているかを識別することができます。

デフォルトではこのスクリプトは 4,000 訓練ステップを実行します。各ステップは訓練セットから無作為に 10 画像を選択し、キャッシュからボトルネックを見つけて、そしてそれらを予測を得るための最終層へと供給します。それからそれらの予測が実際のラベルと比較されて back-propagation プロセスを通して最終層の重みを更新します。プロセスが続くにつれてレポートされる精度が改善されることを見るはずです、そして全てのステップが終わった後で訓練と検証写真から分離されていた画像のセット上で最終的なテスト精度評価が実行されます。このテスト評価は訓練モデルが分類タスクでどのように遂行されるかの最良推定値です。訓練プロセスにランダムネスがあるので正確な値は実行毎に変わりますが 90% と 95 % の間の精度値を見るべきです。この数字は、モデルが完全に訓練された後で正しいラベルが与えられたテストセットの画像のペーセントを基にしています。

 

再訓練を TensorBoard で可視化する

スクリプトは TensorBoard summaries を含みます、これは再訓練を理解し、デバッグし、そして最適化することをより容易にします。例えば、重みあるいは精度が訓練の間にどのように変わるか、グラフと統計を可視化できます。

TensorBoard を launch するためには、再訓練の間またはその後でこのコマンドを実行します :

tensorboard --logdir /tmp/retrain_logs

TensorBoard が実行されたら、TensorBoard を見るために web ブラウザを localhost:6006 に navigate してください。

スクリプトは TensorBoard summaries とデフォルトでは /tmp/retrain_logs にログ出力します。ディレクトリは –summaries_dir フラグで変更可能です。

TensorBoard README は TensorBoard 使用法について、チップ (tip) & トリック、そしてデバッギング情報を含むより多くの情報を持ちます。

 

再訓練されたモデルを使用する

スクリプトは貴方のカテゴリーに再訓練された最終層とともに Inception v3 ネットワークのバージョンを /tmp/output_graph.pb に、そしてラベルを含むテキストファイルを /tmp/output_labels.txt に書き出します。これらは両者とも C++ と Python 画像分類サンプル が読み込めるフォーマットなので、新しいモデルを直ちに使用開始できます。トップ層を置き換えたので、label_image を使用しているのであれば例えばフラグ –output_layer=final_result で スクリプトでは新しい名前を指定する必要があります、

これは再訓練したグラフでどのように label_image サンプルをビルドして実行するかのサンプルです :

bazel build tensorflow/examples/label_image:label_image && \
bazel-bin/tensorflow/examples/label_image/label_image \
--graph=/tmp/output_graph.pb --labels=/tmp/output_labels.txt \
--output_layer=final_result \
--image=$HOME/flower_photos/daisy/21652746_cc379e0eea_m.jpg

花のラベルのリストを見るでしょう、多くの場合トップはひなげし (daisy) です (各再訓練されたモデルは少し異なるかもしれませんが)。–image パラメータを貴方自身の画像でそれらを試すために置き変えることができ、C++ コードを貴方自身のアプリケーションと統合するためにテンプレートとして使用できます。

もし Python プログラムで再訓練したモデルを使用したのであれば @eldor4do からのこのサンプルが行なう必要があることを示します

 

貴方自身のカテゴリ上で訓練する

花のサンプル画像上でスクリプトを何とか動作させたならば、代わりに貴方がケアするカテゴリをそれに認識することを教えることに目を向け始めることができます。理論的には必要なことの全てはそれにサブフォルダのセットをポイントさせることで、各々はカテゴリの一つから名前付けられてそのカテゴリからの画像のみを含みます。それを行なってサブディレクトリ(群)のルート・フォルダを –image_dir への引数として渡せば、スクリプトは花のために行なったように訓練するでしょう。

以下が花のアーカイブのフォルダ構造がどのように見えるか、スクリプトが求めるレイアウトの種類の例を与えるものです :
 

実際には望むような精度を得るためにはある程度の作業がかかるでしょう。下に出会うかもしれない一般的な問題の幾つかを通してガイドしてみます。

 

訓練画像のセットを作成する

始める最初の場所は集める画像に目を向けることです、何故なら訓練と一緒に見る最も一般的な問題は供給されるデータに由来するからです。

訓練が上手くいくためには、認識したい物体の各種の 100 の写真は少なくとも集めるべきです。集めるほど、訓練モデルの精度は良くなりがちです。写真はアプリケーションが実際に遭遇するものの良い表現であることも確実にすることが必要です。例えば、全ての写真をブランク・ウォールに対してインドアで撮りそしてユーザが物体を外で認識しようとするならば、デプロイした時に良い結果を見ることはおそらくないでしょう。

回避すべき他の落とし穴は、学習プロセスはラベル付けされた画像が互いに共通に持つ任意のものを拾ってしまうことで、それに注意を払わないならば有用ではないものになるでしょう。例えば物体の一つの種類を青い部屋で、他のものを緑色の部屋で撮れば、モデルはその予測を実際に大事にしたい物体の特徴ではなく、背景に基礎を置く結果になります。これを回避するためには、できる限り状況の多様性を広くして、違う時間、そして異なるデバイスで写真を撮ってみてください。この問題について更に知りたいのであれば、古典的な (そして出典の怪しい) タンク認識問題 について読むことができます。

使用するカテゴリについて考えることもまた望むかもしれません。多くの異なる物理的な形をカバーする大きなカテゴリをより視覚的に明確な小さなものに分ける価値はあるかもしれません。例えば、「乗り物 (vehicle)」の代わりに「自動車 (car)」、「motorbike (バイク)」、そして「トラック (truck)」を使用するかもしれません。あなたは「閉じた世界 (closed world)」を持つのか「開いた世界 (open world)」を持つのかという問題についても考える価値があります。

閉じた世界では、カテゴリ分けを要求されるもの全ては既知の物体のクラスです。これは植物認識アプリケーションにも適用されるでしょう、そこではユーザは花の写真を撮りがちであることを知っており、行なわなければならないことの全てはどの種かを決定することです。対照的に歩き回るロボットは世界をさまよう時にそのカメラを通してあらゆる種類の異なるものを見るでしょう。その場合には見たものが不確かであるかを分類器がレポートすることを望むでしょう。これは上手くやるのは難しいですが、しかししばしばもし関連する物体のない数多くの典型的な「背景」写真を集めれば、画像フォルダの特別な「未知の (unknown)」クラスにそれらを追加できるでしょう。

画像全てが正しくラベル付けされていることを確かにするために確認することも価値があります。しばしばユーザ生成タグは目的のためには不確実で、例えば Daisy という人の写真のために #daisy を使用したりします。画像を通してミスを取り除けば全体的な精度に驚くかもしれません。

 

訓練ステップ

画像に満足するならば、学習プロセスの詳細を変更することで結果を改善することに目を向けられるでしょう。挑戦すべきもっとも単純なものは –how_many_training_steps です。このデフォルトは 4,000 ですが、それを 8,000 に増やせば2倍の長さの間訓練します。精度の改善のレートは長い間訓練すればゆっくりになりますが、あるポイントで完全に止まるでしょう、しかしモデルの限界に当たる時を見ることを経験できるでしょう。

 

歪める (Distortions)

画像訓練の結果を改善する一般的な方法は訓練入力をランダムな方法で変形し、クロップし、あるいは明るくすることによります。これは同じ画像の全ての可能なバリエーションのおかげで訓練データの効果的なサイズ (= 画像数) を拡張する優位点を持ち、分類器の現実的な利用で起きる歪み (distortions) を処理することをネットワークが学習することを助ける傾向にあります。スクリプトでこれらの歪みを有効にする最大の不利益はボトルネック・キャッシングがもはや利用できないことです、入力画像はもはや正確には再利用できないからです。これは訓練プロセスが非常に長くなることを意味しますので、合理的に満足できるモデルを一度得てからモデルの再調整の方法として歪みを試すことを推奨します。

これらの歪みはスクリプトに –random_crop, –random_scale そして –random_brightness を渡すことで有効になります。これらは全てパーセント値で各画像に歪みの各々をどのくらい適用するかを制御します。それらの各々について 5 あるいは 10 の値から始めるのが合理的でそれからどれがアプリケーションに有用であるかを見る実験をします。–flip_left_right はランダムに画像の半分を水平に反転します、これはアプリケーションでそれらの反転が起こりがちであるならば意味があります。例えば文字を認識しようとしているならばそれは良い考えではありません、それらを反転することは意味を破壊しますので。

 

ハイパー・パラメータ

結果に有用であるかを見るために調整を試すことができる幾つかの他のパラメータがあります。-learning_rate は訓練の間に最終層への更新の重要さを制御します。直感的にはこれが小さければ学習は長くかかりますが、全体的な精度を助ける結果になります。けれどもいつも事実であるとは限りませんので、貴方のケースで何が動作するかを見るには注意深く実験する必要があります。
–train_batch_size は一つの訓練ステップの間にどれだけの画像の画像が検査されるかを制御します、そして学習率はバッチ単位で適用されるのでより大きなバッチで同じ全体的な効果を得るためにはそれを減じる必要があります。

 

訓練、検証、そしてテストセット

スクリプトが内部で行なうことの一つは画像のフォルダをポイントさせる時に3つの異なるセットに分割します。最大のものは通常は訓練セットで、これは訓練の間にネットワークに供給される全ての画像で、その結果はモデルの重みを更新するために使用されます。訓練のために全ての画像を何故使わないのか不思議に思うかもしれませんね?機械学習を行なう時の大きな潜在的な問題はモデルは正しい答えを出すために訓練画像の不適切な詳細を記憶してしまうかもしれないことです。例えば、見せられた各写真の背景のパターンを覚えてしまい物体とラベルをマッチさせるためにそれを使用してしまうネットワークを想像できるでしょう。それは訓練の間に前に見た全ての画像上では良い結果を生成できるでしょう、しかし新しい画像では失敗します、何故ならばそれは物体の一般的な特徴を学習しておらず、単に訓練画像の重要でない詳細を記憶しているからです。

この問題は過剰適合 (過学習) として知られ、これを回避するにはモデルがそれらを記憶できないように、データの一部を訓練プロセスから外へ保持しておきます。そして過剰適合が起きていないことを確認するためにそれらの画像をチェック用に使用します、何故ならばそれらの上で良い精度を見るならばネットワークが過剰適合してないことの良い兆候ですから。

通常の分割は画像の 80% を主要な訓練セットに置いて、10 % を訓練の間に頻繁に検証として実行するために取り分け、そしてそれから最後の 10% を保持しておきます。これは分類器の現実的なパフォーマンスを予測するために頻度は低いですがテストセットとして使用されます。これらの比率は –testing_percentage と –validation_percentage フラグを使用して制御可能です。一般的にはこれらの値はそのデフォルトのままにしておくことが可能です、何故ならばそれらを調整することは訓練へのどのような優位点も通常は見出せないからです。

スクリプトは訓練、検証、そしてテストセットの中で画像を分割するために (完全にランダムな関数よりも) 画像ファイル名を使用することに注意してください。異なる実行において画像が訓練とテストセット間で移動しないことを保証するために行なわれます、何故ならばもしモデルを訓練するために使用される画像が続いて検証セットでも使用されるならば問題となるからです。

検証精度は反復の間に変動することに気がつくかもしれません。この変動の多くは検証セットのランダムなサブセットは各々の検証精度計測のために選択されるという事実から発生します。変動は–validation_batch_size=-1 を選択することで訓練時間のある程度の増加を犠牲にして大きく減じることが可能です、これは各精度計算のために検証セット全体を使用します。

訓練が完了したら、テストセットの誤分類された画像を検証することは洞察に満ちたこととして見出すかもしれません。これはフラグ –print_misclassified_test_images を追加することで成されます。これは、画像のどのようなタイプがモデルにとって最も紛らわしいのか、どのカテゴリが最も識別するのが難しいのかに対する感覚を得る手助けとなるでしょう。例えば、特定のカテゴリのあるサブタイプ、またはある通常でない写真角度が特に識別が難しいことをを発見するかもしれません、これはそのサブタイプの更なる訓練画像の追加をすることを奨励するかもしれません。しばしば、誤分類された画像の検証は誤ったラベル付け、低い質、あるいはあいまいな画像のような入力データセットのエラーを指し示すこともあります。けれども、一般的にはテストセットの個々のエラーのピンポイントな修正は回避すべきです、何故ならばそれらは (更に大きな) 訓練セットのより一般的な問題を単に反映しがちであるからです。

 

以上


TensorFlow 画像キャプション・モデル – コンピュータ・ビジョンと自然言語処理の融合

TensorFlow 画像キャプション・モデル – コンピュータ・ビジョンと自然言語処理の融合

今年 (2016) の 9 月に Google 社により、Microsoft COCO 2015 画像キャプショニング・チャレンジで優秀な成績をおさめた、画像キャプション・モデルが TensorFlow 実装のオープンソースとして公開されました。(キャプションは画像の簡単な説明文です。)

動作検証してみましたので、簡単にご報告します。自前の画像でも試してみましたが、確率つきで3つのキャプション候補が表示され、(人間が見ても)十分に理解可能な結果が得られました。

該当する Google Research Blog 記事は以下です :

Show and Tell: image captioning open sourced in TensorFlow | Google Research Blog

このブログによれば、2014 年に Google Brain チームの研究員が画像を正確に記述するキャプションの自動生成のための機械学習システムのトレーニングを実行し、システムの更なる開発によって Microsoft COCO 2015 画像キャプショニング・チャレンジ(= 正確な画像キャプション計算のベストなアルゴリズムを競うコンペティション)においてトップタイの成績をおさめるという成功に導かれたとのことです。

そして更に、その画像キャプション・モデル最新版を TensorFlow 実装のオープンソースモデルとして利用可能にするとのことで、このリリースはキャプショニング・システムのコンピュータ・ビジョン・コンポーネントへの本質的な改善を含み、オリジナル・システムに比較してより詳細で正確な記述を生成できるようです。

該当ペーパーは以下 :

Show and Tell: Lessons learned from the 2015 MSCOCO Image Captioning Challenge

abstact を簡単にまとめておくと以下のような内容で、最後にコンペと TensorFlow への言及もあります :

自動的に画像の内容を説明することは、コンピュータ・ビジョンと自然言語処理を結びつける、人口知能における基本的な問題です。このペーパーでは、深層 recurrent アーキテクチャをベースとする生成モデルを提示しますが、これはコンピュータ・ビジョンと機械翻訳における最近の進歩を結合し、画像を説明する自然言語の文群を生成するために利用可能なものです。モデルは与えられた訓練画像のターゲット説明文の尤度を最大化するようにトレーニングされます。幾つかのデータセット上での実験はモデルの正確さと画像説明から単独で学習した言語の流暢さを示します。モデルは質的にも量的にも非常に正確なことが多々あります。

それから少し違う角度からの関連記事と Google / University of Edinburgh 共著のペーパーです :

Google researchers teach AIs to see the important parts of images — and tell you about them

Discovering the physical parts of an articulated object class from multiple videos

TensorFlow “Show and Tell ” モデル

今回はオープンソース・モデルの単なる動作検証ですので特に難しい話しはありません。
例によって TensorBoard でグラフを確認しておきますと、Inception モデルと LSTM を組み合わせていますね :

im2txt_graph_all2_with_logo

トレーニング

以下は損失と Perplexity(= 言語モデルの評価尺度、複雑さを表します) のグラフです。
もう少しトレーニングした方が良さそうです :
im3txt_total_loss2-50k

im2txt_perplexity2-50k

検証結果

Microsoft COCO 2015 画像で試すのが一番精度が高いだろうと考えて、ランダムに試してみました。
最初はお皿に盛られた肉、ブロッコリそしてポテトです :

coco_val2014_000000224012

キャプション候補は以下の3つ。合っていますが、1つ目と3つ目の違いはピリオドの有無でしょうか :

Captions for image COCO_val2014_000000224012.jpg:
  0) a plate of food with meat and vegetables . (p=0.000409)
  1) a plate of food with meat and broccoli . (p=0.000255)
  2) a plate of food with meat and vegetables (p=0.000025)

次に海とサーファー。このキャプション・モデルの紹介記事では、(異なる画像ですが)良く利用される題材です :
Oregon Surfers

Captions for image COCO_val2014_000000224477.jpg:
  0) a man riding a wave on top of a surfboard . (p=0.034516)
  1) a person riding a wave on a surfboard . (p=0.007086)
  2) a man riding a wave on a surfboard in the ocean . (p=0.004863)

coco_val2014_000000224000

Captions for image COCO_val2014_000000224000.jpg:
  0) a herd of sheep grazing in a field . (p=0.000379)
  1) a herd of sheep walking down a road . (p=0.000219)
  2) a herd of sheep walking down a street . (p=0.000148)

coco_val2014_000000224051

  0) a man riding a bike down a street . (p=0.000337)
  1) a bicycle is parked on the side of the road . (p=0.000283)
  2) a bicycle is parked on the side of a road . (p=0.000143)

coco_val2014_000000224037

Captions for image COCO_val2014_000000224037.jpg:
  0) a group of boats docked in the water . (p=0.000443)
  1) a group of boats floating in the water . (p=0.000402)
  2) a group of boats docked in a harbor . (p=0.000140)

Imagenet の画像も幾つか試してみましたが、結果はあまり芳しくありませんでした。
おそらく、Imagenet の画像は粗すぎるのだと思います。
honda_jazz_7

  0) a white car parked in front of a car . (p=0.000060)
  1) a white car parked in front of a parking meter . (p=0.000031)
  2) a white car parked in front of a car (p=0.000019)

自前の画像でも幾つか試してみました :

classcat_cat

  0) a cat is sitting on the floor next to a laptop . (p=0.000014)
  1) a cat is sitting on the floor next to a computer . (p=0.000008)
  2) a cat is sitting on the floor next to a cat . (p=0.000007)

apple_persimmon

  0) a bunch of apples are sitting on a table (p=0.000065)
  1) a bunch of apples are sitting on a plate (p=0.000026)
  2) a bunch of apples are sitting on a table . (p=0.000024)
 

以上

TensorFlow で GoogLeNet (Inception モデル) を実装

TensorFlow で GoogLeNet (Inception モデル) を実装

深層 CNN については既に AlexNetVGG を TensorFlow で実装して試してみましたが、締めくくりに GoogLeNet の実装に挑戦してみます。GoogLeNet は言うまでもなく、ILSVRC-2014 (ImageNet Large Scale Visual Recognition Challenge) の分類問題で優勝したネットワークです。

もちろん最新版の Inception-v3 については ImageNet によるトレーニング済みのモデルがダウンロード可能で、既に Android に組み込む ことができることも確認済みです。

参考 : トレーニング済みモデルの再利用方法については TensorFlow : Tutorials : 画像認識 を参照してください。

また自前のデータでトレーニングする場合でも fine-tuning すれば十分かもしれません。

GoogLeNet

冒頭にも書いたように、GoogLeNet は ILSVRC-2014 の分類問題で優勝したネットワークで、最新版 Inception-v3 は CNN の最高峰といっても良いでしょう。ちなみに「GoogLeNet」 は正式にはこの ILSVRC 2014 型モデルを指すコードネームのようで、ついでに言えば CNN の元祖 LeNet へのオマージュでしょう(多分):
imagenet_challenge2014b

 
テクニカルレポートは以下を参照してください :

Going Deeper with Convolutions

但し、TensorFlow のチュートリアル内では Inception-v3 モデルへの言及が多いです :

Rethinking the Inception Architecture for Computer Vision

アーキテクチャの説明は Going deeper with convolutions に詳しいので譲りますが、以下は TensorBoard のグラフ出力です。Inception が積層されています :
googlenet_graph_all_with_logo

TensorFlow GoogLeNet & University of Oxford: 17 Category Flower Dataset

ImageNet を題材にすれば高い精度が出るのでしょうけど、VGG との比較もあって、題材は今回も University of Oxford が提供しているデータセットを取り敢えず使用しました。Dataset の詳細は 17 Category Flower Dataset を参照してください。

以下は損失グラフです。オレンジ色は AdaGrad、ターコイズ色は Adam です。それっぽいです :
googlenet_loss2

※ RMSProp は同じ条件だと収束しそうになかったので断念しました。

トレーニング精度は以下 :
googlenet_accu2

そして validation 精度 :
googlenet_accu_valid2

さすがに最高峰モデルと言えましょう。VGG バリエーション・モデルに圧勝です。

 

以上

AI導入支援 #2 ウェビナー

スモールスタートを可能としたAI導入支援   Vol.2
[無料 WEB セミナー] [詳細]
「画像認識 AI PoC スターターパック」の紹介
既に AI 技術を実ビジネスで活用し、成果を上げている日本企業も多く存在しており、競争優位なビジネスを展開しております。
しかしながら AI を導入したくとも PoC (概念実証) だけでも高額な費用がかかり取組めていない企業も少なくないようです。A I導入時には欠かせない PoC を手軽にしかも短期間で認知度を確認可能とするサービの紹介と共に、AI 技術の特性と具体的な導入プロセスに加え運用時のポイントについても解説いたします。
日時:2021年10月13日(水)
会場:WEBセミナー
共催:クラスキャット、日本FLOW(株)
後援:働き方改革推進コンソーシアム
参加費: 無料 (事前登録制)
人工知能開発支援
◆ クラスキャットは 人工知能研究開発支援 サービスを提供しています :
  • テクニカルコンサルティングサービス
  • 実証実験 (プロトタイプ構築)
  • アプリケーションへの実装
  • 人工知能研修サービス
◆ お問合せ先 ◆
(株)クラスキャット
セールス・インフォメーション
E-Mail:sales-info@classcat.com