機械学習の基礎知識がゼロでも、TensorFlow で画像認識システムを構築する方法をお教えします (パート 2)

機械学習の基礎知識がゼロでも、TensorFlow で画像認識システムを構築する方法をお教えします (パート 2)

[[182024]]

これは Wolfgang Beyer によるブログ投稿です。この論文では、TensorFlow を使用して簡単な画像認識システムを構築する方法について詳しく説明します。この記事では、画像認識システムを構築するプロセス全体を段階的に説明します。

この連載では、主に機械学習の基礎知識を持たないユーザーが、TensorFlow 上で画像認識システムをゼロから構築する方法を紹介します。記事の最初の部分では、著者の Woflgang Beyer が読者にいくつかの簡単な概念を紹介しています。この記事はシリーズの第2部であり、主に簡単な画像認識機能の実装方法を紹介します。 Leifeng.com による翻訳。許可なく複製することはできません。

これで、モデルの構築を開始できます。実際の数値計算はすべて、高速で効率的な C++ バックエンドを使用する TensorFlow によって実行されます。 TensorFlow は、計算速度を低下させる Python と C++ の頻繁な切り替えを回避します。一般的なワークフローでは、まず TensorFlow グラフを作成してすべての操作を定義します。このプロセスでは計算は行われず、セットアップ操作のみを実行します。その後、入力データに対して計算操作を実行し、結果を記録します。

まずグラフを定義することから始めましょう。まず、TensorFlow 入力データの形式を記述するプレースホルダーを作成します。プレースホルダーには実際のデータは含まれず、データのタイプと形状を定義するだけです。

私たちのモデルでは、まず浮動小数点データ (tf.float32) で構成される画像データのプレースホルダーを定義しました。形状パラメータは入力データのサイズを定義します。複数の画像を同時に入力しますが (これについては後で説明します)、実際の入力画像の数はいつでも変更できるようにしたいと考えています。したがって、最初の形状パラメータは none であり、サイズは任意の長さにできることを意味します。 2 番目のパラメータは 3072 で、これは各画像の浮動小数点値です。

分類ラベルのプレースホルダーは整数データ (tf.int64) で構成され、各画像の値は 0 ~ 9 です。入力画像の数を指定していないため、shapeパラメータは[none]になります。

重みとバイアスは最適化したい変数です。しかし今は、私たちのモデルについて話しましょう。

入力は 3072 個の浮動小数点データで構成され、目的の出力は 10 個の整数データの 1 つです。 3072 個の値を 1 つにまとめるにはどうすればよいでしょうか。少し考えて、0 から 9 までの数字を出力する代わりに、結果にスコアを付けて 10 個の数字 (各カテゴリに 1 つずつ) を取得し、最も高いスコアを持つカテゴリを選択するとします。したがって、当初の質問は次のようになります。3072 個の値から 10 個の値にするにはどうすればよいでしょうか。

私たちが採用する単純なアプローチは、各ピクセルを個別にクエリすることです。各ピクセル (より正確には、ピクセルの各カラー チャネル) と各可能なクラスについて、そのピクセルの色によって、そのクラスに属する可能性が高まるか低くなるかを自問します。たとえば、ピクセルの色は赤です。車の画像のピクセルが通常赤色である場合、「車」カテゴリのスコアを上げたいと考えます。

ピクセルの赤チャンネル値に正の数を掛けて、「車」クラスのスコアに加算します。同様に、位置 1 の馬の画像に赤いピクセルがまったくないかほとんどない場合は、「馬」として分類するためのスコアを低いスコアに維持するか、さらに下げたいと考えます。つまり、より小さい数または負の数を掛けて、「馬」に分類されるスコアに加算します。この操作を 10 個のカテゴリすべてに対して繰り返し、各ピクセルに対して計算を繰り返し、3072 個の値を合計して合計を算出します。 3072 ピクセルの値に 3072 の重み付けパラメータ値を掛けて、この分類のスコアを取得します。 *** 10 のカテゴリに対して 10 のスコアが得られます。次に、スコアが最も高いものを選択し、その画像にこのタイプとしてラベルを付けます。

画像は 3072 個の値の 1 次元配列で表されます。各値に重み付けパラメータを掛け、すべての値を合計して 1 つの数値 (特定のカテゴリのスコア) を取得します。

マトリックス方式を使用すると、ピクセル値に加重値を掛けて加算するプロセスが大幅に簡素化されます。私たちの画像は 3072 次元のベクトルで表されます。このベクトルに 3072×10 の重み付け行列を掛けると、結果は 10 次元のベクトルになります。必要な加重合計が含まれています。

行列乗算によって、10 個のカテゴリすべてにわたって画像のスコアを計算します。

3072×10 行列内の特定の値がモデルのパラメータです。それが不規則であったり役に立たなかったりすると、私たちの出力も不規則または役に立たないものになります。これを機能させるにはトレーニング データが必要です。トレーニング データをクエリすることで、モデルが最適なパラメータを自動的に計算できるようになることを期待します。

上記の2行のコードでは、重み行列のサイズが3072×10であり、初期値が0に設定されていることをTensorFlowに伝えています。さらに、バイアス値を含む 10 次元ベクトルである 2 番目のパラメータを定義します。このバイアス値は画像データに直接作用するのではなく、単に加重合計に加算されます。この偏差値は、*** スコアの開始点として考えることができます。すべてのピクセルがゼロである完全に黒い画像を想像してください。そうすると、重みマトリックスがどれだけ大きくても、すべてのカテゴリのスコアは 0 になります。バイアス値を使用することで、各カテゴリの開始値が 0 にならないようにすることができます。

さて、予測です。このステップでは、複数の画像ベクトルと行列の次元を決定しました。この操作の結果は、入力画像ごとに 10 次元のベクトルになります。


行列乗算を使用して、複数の画像の 10 個のカテゴリすべてのスコアを計算します。

重みとバイアス パラメータを徐々に最適化するプロセスはトレーニングと呼ばれ、次の手順で構成されます。まず、トレーニング データを入力し、現在のパラメータに基づいてモデルに予測を行わせます。予測値を正しい分類ラベルと比較します。比較の数値結果は損失と呼ばれます。損失値が小さいほど、予測値は正しいラベルに近くなり、逆もまた同様です。モデルの損失値を最小限に抑え、予測値を実際のラベルに近づけることを期待します。しかし、損失を最小限に抑える前に、まず損失がどのように計算されるかを見てみましょう。

前の手順で計算されたスコアは、任意の実数を含めることができる logits 変数に保存されます。ソフトマックス関数を呼び出してこれらの値を確率値(0 から 1 までの合計が 1 になる実数)に変換し、入力をその特性を表す出力に変換することができます。対応する入力の配置は変更されず、スコアが最も高いカテゴリの確率が最も高くなります。

ソフトマックス関数によって出力された確率分布を、真の確率分布と比較します。真の確率分布では、正しいカテゴリの確率は 1 で、他のカテゴリの確率は 0 です。クロスエントロピーを使用して 2 つの確率分布を比較します (より技術的な説明はここで参照できます)。クロスエントロピーが小さいほど、予測値の確率分布と正解値の確率分布の差が小さくなります。この値はモデルの損失を表します。

幸いなことに、TensorFlow には、この一連の操作を完了するのに役立つ関数が用意されています。モデル予測のロジットと正しい分類値labels_placeholderを比較します。 sparse_softmax_cross_entropy_with_logits() 関数の出力は、各入力画像の損失値です。次に、入力画像全体の平均損失値を計算する必要があります。

しかし、損失を最小限に抑えるためにパラメータをどのように調整すればよいのでしょうか? ここで TensorFlow が役に立ちます。自己微分と呼ばれる手法により、パラメータ値に対する損失値の勾配を計算できます。つまり、各パラメータが総損失に与える影響と、パラメータを少し増加または減少させることで損失を削減できるかどうかを知ることができます。その後、すべてのパラメータ値がそれに応じて調整され、モデルの精度が向上します。パラメータ調整が完了すると、プロセス全体が再び開始され、新しい画像セットがモデルに入力されます。

TensorFlow は、勾配情報を使用してパラメータ値を更新できるさまざまな最適化手法を認識しています。ここでは勾配降下アルゴリズムを使用します。パラメータを決定する際には、モデルの現在の状態のみが考慮され、以前のパラメータ値は考慮されません。パラメータ降下アルゴリズムには、パラメータ更新のスケーリング係数である学習率という単一のパラメータのみが必要です。学習率が大きいほど、各ステップでのパラメータ値の調整が大きくなります。学習率が大きすぎると、パラメータ値が正しい値を超え、モデルが収束しない可能性があります。学習率が小さすぎると、モデルの学習が非常に遅くなり、適切なパラメータ値を見つけるのに長い時間がかかります。

画像分類を入力し、予測結果を実際の値と比較し、損失を計算し、パラメータを調整するというプロセスを何度も繰り返す必要があります。より大規模で複雑なモデルの場合、この計算量は急速に増加します。しかし、私たちのシンプルなモデルでは、結果を得るために忍耐も特殊なハードウェアも必要ありません。

これら 2 行のコードは、モデルの精度をテストするために使用されます。 logits の argmax は、最高スコアの分類を返します。これは予測されたクラス ラベルです。 tf.equal() はこのラベルを正しい分類ラベルと比較し、ブールベクトルを返します。ブール数値は浮動小数点数(各値は 0 または 1)に変換され、これらの数値の平均によって得られるスコアが正しく予測された画像の割合になります。

最後に、TensorFlow グラフを定義し、実行する準備が整いました。 sess 変数を通じてアクセスできるセッション コントローラーでチャートを実行します。このセッション コントローラーを実行する最初のステップは、先ほど作成した変数を初期化することです。変数定義では初期値を指定しましたが、次にこれらの初期値を変数に割り当てる必要があります。

次に、反復的なトレーニング プロセスを開始します。これは max_steps 回繰り返されます。

これらの数行のコードは、トレーニング データからいくつかの画像をランダムにサンプリングします。トレーニング データから抽出された複数の画像とラベルはバッチと呼ばれます。バッチ サイズ (1 つのバッチ内の画像の数) は、パラメータを更新する頻度を示します。まず、バッチ内のすべての画像の損失値を平均します。次に、パラメータは勾配降下アルゴリズムに従って更新されます。

バッチ処理後に行うのではなく、最初にトレーニング セット内のすべての画像を分類すると、初期平均損失と初期勾配を計算し、バッチ実行時に使用される推定値の代わりにそれらを使用できます。しかし、この場合、各反復のパラメータを更新するために、より多くの計算が必要になります。反対に、バッチ サイズを 1 に設定し、単一の画像のパラメータを更新することもできます。これにより、パラメータの更新頻度が高くなりますが、不正確になる可能性が高くなります。そのため、間違った方向への修正が頻繁に行われます。

通常、これら 2 つの極端な例の中間あたりで最も速い改善が実現します。大規模なモデルの場合、メモリの考慮も重要になります。バッチ サイズは、すべての変数と中間結果がメモリに収まる範囲で、できるだけ大きくする必要があります。

ここで、コードの最初の行は、0 からトレーニング セット全体のサイズまでの値 batch_size をランダムに割り当てます。次に、この値に基づいて、バッチ処理によって対応する数の画像とラベルが選択されます。

100 回の反復ごとに、データのトレーニング バッチに対するモデルの現在の精度を確認します。これを完了するには、先ほど定義した精度演算を呼び出すだけです。

これは、トレーニング ループ全体の中で最も重要なコード行です。モデルに単一のトレーニング ステップを実行するように指示します。パラメータを更新するためにモデルが実行する必要があることを再度宣言する必要はありません。すべての情報は、TensorFlow グラフの定義によって提供されます。 TensorFlow は、損失に基づいて勾配降下アルゴリズムを使用してパラメータを更新することを認識しています。損失は​​ロジットによって異なります。ロジットは、重み、バイアス、および特定の入力バッチに依存します。

したがって、モデルにトレーニング データのバッチを入力するだけで済みます。これは、ルックアップ テーブルを提供することによって実現されます。トレーニング データ バッチは、先ほど定義したプレースホルダーにすでに割り当てられています。

トレーニング後、テスト セットを使用してモデルを評価します。モデルがテスト セットを認識するのはこれが初めてです。したがって、テスト セット内の画像はモデルにとって完全に新しいものになります。トレーニングされたモデルが、これまでに見たことのないデータに対してどの程度のパフォーマンスを発揮するかを評価します。

*** 1 行のコードで、モデルのトレーニングと実行にかかった時間を出力します。

結果

「python softmax.py」コマンドを使用してこのモデルを実行してみましょう。出力は次のようになります:

これは何を意味するのでしょうか? このテスト セットでトレーニングされたモデルの推定精度は約 31% です。独自のコードを実行すると、結果はおそらく 25 ~ 30% の範囲になります。そのため、私たちのモデルは、これまで見たことのない画像の 25% ~ 30% を正しくラベル付けすることができます。悪くないですね! ここには 10 種類のラベルがあり、ランダムに推測しても精度は 10% しかありません。私たちの非常にシンプルな方法は、すでにランダムな推測よりも優れています。 25% はまだ少し低いと思われる場合は、このモデルがまだ比較的原始的であることを思い出してください。線や形などの特定の画像特徴の概念はありません。他のピクセルとの関連性を考慮せずに、各ピクセルの色を個別に検出するだけです。画像内の 1 つのピクセルを変更すると、モデルへの入力がまったく異なることになります。そう考えると、25% の精度はそれほど悪くないように思えます。

さらに数回繰り返して実行したらどうなるでしょうか? モデルの精度は向上しない可能性があります。結果を見ると、トレーニング精度は着実に上昇しているわけではなく、0.23 から 0.44 の間で変動していることがわかります。モデルの限界に達したようで、これ以上トレーニングしても役に立たないようです。このモデルではこれ以上の結果は得られませんでした。実際、1000 回の反復トレーニングを行う代わりに、はるかに少ない反復で同様の精度を得ることができます。

最後に気付くのは、テストの精度がトレーニングの精度よりもはるかに低いことです。このギャップが非常に大きい場合、それは過剰適合を意味します。モデルは、これまでに見たトレーニング データに合わせて細かく調整されますが、これまでに見たことのないデータに合わせて調整されるわけではありません。

この投稿の作成には長い時間がかかりました。記事を最後まで読んでいただき、ありがとうございます (または最後まで飛ばして読んでください)。機械学習分類器の仕組みや、TensorFlow で簡単なグラフを作成して実行する方法など、何か興味深いものを見つけていただければ幸いです。もちろん、追加したい資料はまだたくさんあります。これまでは、いかなる種類のニューラル ネットワークも適用しないソフトマックス分類器のみを使用してきました。次のブログ投稿では、小さなニューラル ネットワーク モデルで結果を最大限に改善する方法について説明します。

<<:  機械学習、データサイエンス、人工知能、ディープラーニング、統計などの違い。

>>:  Foreign Media Express: 2017 年の機械学習に関する 10 の予測

ブログ    
ブログ    

推薦する

...

...

業界に革命を起こすスマートパッケージング技術トップ10

ほとんどの人がサプライチェーン技術について考えるとき、パッケージングは​​おそらく最初に思い浮かぶも...

...

自動化された機械学習は AI 研究の次の主流となるでしょうか?データサイエンティストの意見

自動化された機械学習は、過去 1 年間で大きな関心を集めるトピックになりました。 KDnuggets...

人工知能技術は、インターホンを構築する主流の技術の1つになると期待されています

現在、人工知能、ビッグデータ、顔認識技術、クラウドコンピューティングなどの新技術が急速に発展し、産業...

...

顔認識はセキュリティの発展の障害になるのでしょうか?

現在、顔認識は人々の生活のあらゆる側面に組み込まれています。携帯電話のロック解除、顔をスワイプしての...

...

適切な人工知能を選択するにはどうすればよいでしょうか?

採用プロセスで人工知能テクノロジーに切り替えるのは難しいかもしれませんが、これらのヒントに従って、会...

Antの信用リスク管理の実践

1. 信用リスク管理業務の背景と事例まず、当社の事業シナリオについて簡単にご紹介させていただきます。...

...

何か効率的な「錬金術」アーティファクトをお勧めいただけますか? Fudan fastNLPチームが内部パラメータ調整ツールfitlogをリリース

このパラメータ調整ツールは、実験結果の表形式表示、カスタムメモ、フロントエンド操作の記録の削除/非表...

Pytorch の核心であるモデルの定義と構築を突破しましょう! ! !

こんにちは、Xiaozhuangです!今日はモデルの定義と構築についてお話ししましょう。初心者に最適...

...