Amazon Web Services ブログ
Apache MXNet で事前にトレーニングを受けたモデルを使用する
このブログ記事では、Apache MXNet で事前トレーニングを受けたモデルの使用方法について解説します。複数モデルを試してみようと思われた理由は? 最高の精度をもったモデルを選ばないのはなぜでしょう? この記事の後半で説明するように、同じデータセット上でこれらのモデルがトレーニングを受け最高の精度を得るために最適化されたとしても、個々のイメージではその動作にわずかながら違いが生じます。また、予測速度も変動する可能性があります。これは多くのアプリケーションにとって重大な要素です。事前にトレーニングされたモデルをいくつか試すことで、自分のビジネス課題を解決するのに最適なモデルを見つけることができます。
まず、Apache の MXNet モデルから、3 つのイメージ分類モデルをダウンロードしてみましょう。
- VGG-16 (研究報告)、ImageNet Large Scale Visual Recognition Challenge (ImageNet 大規模ビジュアルリコグニッションチャレンジ) における 2014 年度の分類最優秀モデル。
- Inception v3 (研究報告)、GoogleNet の発展、オブジェクト検査での 2014 年度最優秀モデル。
- ResNet-152 (研究報告)、複数カテゴリにおける 2015 度最優秀モデル。
各モデルについて次に示す 2 種類のファイルをダウンロードする必要があります。
- ニューラルネットワークの JSON 定義を含むシンボルファイル: レイヤー、接続、アクティベーション機能など。
- 全接続加重、バイアスの値を保存する加重ファイルで別名パラメーター。トレーニングフェーズ中にネットワークにより習得。
VGG-16 シンボルファイルの 1 行目を見てみましょう。入力レイヤー (「data」) の定義、最初のコンボリューションレイヤーの加重とバイアスが記述されています。コンボリューションオペレーション (「conv1_1」) と、そのほかに、ReLU の活性化関数 (‘relu1_1’) が定義されています。
3 モデルのいずれも ImageNet データセットで事前トレーニングされており、これには 1,000 種類に分類されるオブジェクトと動物の写真が 120 万種以上含まれています。synset.txt ファイルでこれらのカテゴリを閲覧できます。
続いてモデルをロードしてみましょう。
まず、ファイルから加重とモデルについての記述をロードします。MXNet ではこれをチェックポイントと呼びます。各トレーニングのエポック後、加重を保存するのは良い習慣です。トレーニングが完了したら、トレーニングログを見て、最高の検証精度を示した最適なエポックの加重を選ぶことができます。これが最後の最後に現れることはあまりないようです。
ロードが完了したら、Symbol オブジェクトと加重、別名モデルパラメーターを取得できます。その後、新しい Module を作成し、入力 Symbol に割り当てます。 モデルを実行するコンテキストを指定することも可能です。デフォルトの動作は CPU 環境を使用するようになっています。その理由には、次の 2 つがあります。
- まず、ご使用のコンピューターに GPU が搭載されていなくても、これによりノートブックをテストできます。
- 次に、1 つのイメージを予測するだけなので、特にパフォーマンスに関する要件はありません。大量のイメージを最高のスループットで予測するような本番環境のアプリケーションでは、GPU が最善の選択肢となります。
その後、入力 Symbol を入力データに結び付けます。そのネットワークの入力レイヤーの名前から、「data」と呼ぶ必要があります (JSON ファイルの最初の数行を思い出してください)。
最後に、「data」の形式として 1 x 3 x 224 x 224 を定義します。 224 x 224 は画像の解像度で、モデルをトレーニングする方法となります。3 は赤、緑、青 (この順) でチャネルの数です。1 はバッチのサイズです。ここでは一度に 1 つのイメージを予測します。
また、synset.txt ファイルに分類された 1,000 種のカテゴリもロードする必要があります。予測時には実際の説明が必要です。
それでは、ファイルからイメージをロードする関数を書いていきましょう。このモデルでは 1 つ 224 x 224 の赤、緑、青を持つ、4 次元の NDArray を想定していることを思い出しましょう。入力イメージからこの NDArray を構築するのに、OpenCV ライブラリーを使用します。
ステップは次のとおりです。
- イメージを読み込みます。これはイメージの高さ、イメージの幅、3 の形状をした、numpy 配列を戻します。これには BGR (青、緑、赤) の順で 3 つのチャネルがあります。
- イメージを RGB (赤、緑、青) に変換します。
- イメージのサイズを 224 x 224 に変換します。
- イメージの高さ、イメージの幅、3 を 3、イメージの高さ、イメージの幅の形状に変換します。
- 4 番目の次元を追加し、NDArray を構築します。
予測を処理しましょう。パラメーターはイメージ、モデル、カテゴリのリスト、そして戻したい上位カテゴリの数です。
Module オブジェクトではバッチに分けてモデルにデータを挿入しなくてはならないことを思い出してください。これにはデータイテレーターを使うのが一般的な方法です。ここで予測するのは 1 つのイメージだけなので、データイテレーターを使用することはできますが、その必要はないでしょう。代わりに、ここでは名前付きのタプルを作りましょう。Batch と名前を付け、「data」属性が参照されたときに入力 NDArray を戻すことで、偽イテレーターとして動作します。
イメージが転送されると、モデルは 1,000 個の確率をもつ NDArray を出力します。この出力された配列はトレーニングを受けた 1,000 個のカテゴリに相当します。バッチサイズが 1 であることから、NDArray には 1 行しかありません。
これを squeeze() を持つ配列に変換しましょう。 続いて、argsort() を使用することで、降順に並べ替えられた確率のインデックスをもつ 2 つの目の配列を作成します。最後に、上から n 位までのカテゴリとその記述を戻します。
これまでの内容をひとまとめにします。3 つのモデルをすべてロードします。
イメージを分類する前に、「.params」ファイルからロードしたばかりの VGG-16 パラメーターをいくつか見てみましょう。まず、全レイヤーの名前を出力します。
レイヤーごとに、加重とバイアスの 2 つのコンポーネントを見ることができます。加重を数えると 16 レイヤー (13 個のコンボリューションレイヤーと 3 個の完全接続済みレイヤー) あるのがわかります。これでこのモデルが VGG-16 と呼ばれる理由がお分かりいただけたことでしょう。
次に最後の接続済みレイヤー用に加重を出力します。
このマトリックスの形状に気付きましたか? 1000×4096 です。このレイヤーには 1,000 個のニューロンが含まれます。それぞれのニューロンには、個別のカテゴリに属すイメージの確率が保存されます。また、各ニューロンは前のレイヤー (「fc7」) の全 4,096 個のニューロンに完全に接続されています。
これでおしまいです。これらのモデルをイメージの分類に使用しましょう。
今度は GPU を使った環境でもう一度ご覧ください。
注意 : GPU サポートについてのエラーが表示されたら、ご使用のマシンに GPU が搭載されていないか、GPU サポート (USE_CUDA=1) 付きで構築されなかったバージョンの MXNet を使用していることを意味します。
GPU サポート付きでソースから MXNet を構築する手順についてはこちらをご覧ください。 代わりに、プレビルト版をインストールすることもできます。
パフォーマンスの差は 15 倍から 20 倍と歴然です。 同時に複数のイメージを予測する場合、GPU アーキテクチャの膨大な並列処理が原因で差は広がります。
次は皆さんのイメージで試してみてください。このノートブックと同じフォルダーにそれらをコピーし、上のセルのファイル名を更新して、predict() コールを再実行します。
事前トレーニング型のモデルを使用した処理に挑戦してみましょう!
今回のブログの投稿者について
Julien は EMEA の人工知能およびMachine Learning のエバンジェリストです。彼は、開発者や企業のアイデアを実現させるための支援を中心として活動しています。彼は余暇時間に、JRR Tolkien の作品を何度も読んでいます。