フロントエンドエンジニアは、これらの18のトリッ​​クをマスターすることで、ブラウザでディープラーニングを習得できます

フロントエンドエンジニアは、これらの18のトリッ​​クをマスターすることで、ブラウザでディープラーニングを習得できます

TensorFlow.js がリリースされた後、以前にトレーニングしたターゲット/顔検出モデルと顔認識モデルを TensorFlow.js にインポートしました。モデルの一部はブラウザで非常にうまく動作することがわかりました。 TensorFlow.js のおかげで、フロントエンド開発者が流行りだした気がします。

ブラウザはディープラーニング モデルを実行できますが、これらのモデルはブラウザで実行するように設計されていないため、多くの制限と課題が生じます。ターゲット検出を例に挙げると、リアルタイム検出は言うまでもなく、一定のフレームレートを維持することさえ難しい場合があります。数百メガバイトにもなるモデルがユーザーのブラウザや帯域幅(携帯電話)に与える負担についても言うまでもありません。

ただし、特定の原則に従う限り、畳み込みニューラル ネットワーク CNN と TensorFlow.js を使用してブラウザーで適切なディープラーニング モデルをトレーニングすることは夢ではありません。下の図からわかるように、私がトレーニングしたモデルのサイズはすべて 2 MB 未満に抑えられており、最小のモデルでも 3 KB しかありませんでした。

頭の中で疑問に思うことがあるかもしれません。あなたはバカですか? ブラウザを使ってモデルをトレーニングしたいのですか? はい、自分のコンピューター、サーバー、クラスター、またはクラウドを使用してディープラーニング モデルをトレーニングするのは間違いなく正しい方法ですが、誰もが NVIDIA GTX 1080 Ti または Titan X を使用するお金を持っているわけではありません (特にグラフィック カードの価格が全体的に上昇した後では)。このとき、ブラウザでディープラーニング モデルをトレーニングする利点が反映されます。WebGL と TensorFLow.js を使用すると、コンピューター上の AMD GPU を使用してディープラーニング モデルを簡単にトレーニングできます。

ターゲット認識問題では、安全のために、YOLO、SSD、残差ネットワークResNet、MobileNetなどの既製のアーキテクチャを使用することが推奨されることが多いですが、個人的には、それらを完全にコピーすると、ブラウザでのトレーニング効果が確実に悪くなると思います。ブラウザ上でトレーニングするには、モデルが小さく、高速で、できるだけ簡単にトレーニングできることが求められます。次に、モデルアーキテクチャ、トレーニング、デバッグの観点から、これら 3 つのポイントを実現する方法を見ていきます。

モデルアーキテクチャ

1. モデルのサイズを制御する

モデルのスケールを制御することが重要です。モデル アーキテクチャが大きすぎて複雑すぎると、トレーニングと実行が遅くなり、ブラウザーからのモデルの読み込みも遅くなります。モデルのサイズを制御することは言うのは簡単ですが、難しいのは精度とモデルのサイズのバランスを取ることです。精度が要件を満たさない場合、モデルがどれだけ小さくても役に立たなくなります。

2. 深さ方向に分離可能な畳み込み演算を使用する

標準的な畳み込み演算とは異なり、深さ方向に分離可能な畳み込みでは、最初に各チャネルで畳み込み演算を実行し、次に 1X1 クロスチャネル畳み込みを実行します。これを行う利点は、パラメータの数を大幅に削減できるため、モデルの実行速度が大幅に向上し、リソースの消費とトレーニング速度も向上することです。深さ方向に分離可能な畳み込み演算のプロセスを次の図に示します。

MobileNet と Xception はどちらも深さ方向に分離可能な畳み込みを使用しており、MobileNet と PoseNet の TensorFlow.js バージョンでも深さ方向に分離可能な畳み込みを確認できます。深さ方向に分離可能な畳み込みがモデルの精度に与える影響についてはまだ議論の余地がありますが、私の個人的な経験からすると、ブラウザでモデルをトレーニングする場合、これを使用するのは間違いなく正しい選択です。

最初のレイヤーでは、特徴抽出後のチャネル間の関係を維持するために、標準の conv2d 操作を使用することをお勧めします。 *** レイヤーには一般にパラメータが少ないため、パフォーマンスへの影響はほとんどありません。

他の畳み込み層はすべて、深さ方向に分離可能な畳み込みを使用できます。たとえば、ここでは 2 つのフィルターを使用します。

ここで、tf.separableConv2dで使用される畳み込みカーネル構造はそれぞれ[3,3,32,1]と[1,1,32,64]です。

3. スキップ接続と密なブロックを使用する

ネットワーク層の数が増えると、勾配消失問題が発生する可能性も高まります。勾配消失により損失関数の減少が遅くなりすぎて、トレーニング時間が非常に長くなったり、失敗したりする可能性があります。 ResNet および DenseNet で使用されるスキップ接続により、この問題を回避できます。簡単に言うと、スキップ接続とは、次の図に示すように、活性化関数をスキップし、いくつかの層の出力をネットワークの深部にある隠し層に直接入力として渡すことです。

これにより、活性化関数とチェーン導出によって引き起こされる勾配消失の問題を回避でき、必要に応じてネットワーク層の数を増やすこともできます。

明らかに、スキップ接続の暗黙の要件は、接続された 2 つのレイヤーの出力と入力の形式が一致する必要があることです。残差ネットワークを使用する場合は、両方のレイヤーのフィルター数とパディングが同じであり、ストライドが 1 であることを確認する必要があります (ただし、形式が対応していることを確認する方法は他にもあります)。

最初は、残差ネットワークの考え方を真似して、1層おきにスキップ接続を追加しました(下図参照)。しかし、スキップ接続を追加するよりも密なブロックの方がうまく機能し、モデルの収束がはるかに速くなることがわかりました。

具体的なコードを見てみましょう。ここでの密なブロックには、深さ方向に分離可能な 4 つの畳み込み層があります。最初の層では、入力サイズを変更するためにストライドを 2 に設定しました。

4. 活性化関数としてReLUを選択する

ブラウザでディープ ネットワークをトレーニングする場合、活性化関数を確認せずに ReLU を選択するだけで済みます。主な理由は、勾配が消えるためです。しかし、ReLUのさまざまなバリエーションを試すこともできます。

MobileNetで使用されるReLU-6 (y = min(max(x, 0), 6)):

トレーニングプロセス

5. 最適化ツールとしてAdamを選択する

これは単なる私の個人的な経験です。以前は、SGD は局所最小値で行き詰まったり、勾配爆発が発生したりすることがよくありました。まず学習率を 0.001 に設定し、他のすべてのパラメータをデフォルトのままにしておくことをお勧めします。

6. 学習率を動的に調整する

一般的に言えば、損失関数が減少しなくなったらトレーニングを停止する必要があります。それ以上のトレーニングは過剰適合につながるためです。ただし、損失関数が上下に振動していることがわかった場合は、学習率を下げることで損失関数を小さくできる可能性があります。

以下の例では、学習率が最初は 0.01 に設定され、エポック 32 (黄色の線) から振動していることがわかります。ここで、学習率を 0.001 (青線) に変更すると、損失関数は約 0.3 減少します。

7. 重み初期化の原理

個人的には、バイアスを 0 に設定し、重みには従来の正規分布を使用するのが好きです。私は通常、Glorot 正規分布初期化メソッドを使用します。

8.データセットの順序をシャッフルする

それは決まり文句です。 TensorFlow.js では、tf.utils.shuffle を使用してこれを実現できます。

9. モデルを保存する

js は FileSaver.js を使用してモデルを保存 (またはダウンロード) できます。たとえば、次のコードはモデルのすべての重みを保存できます。

保存する形式を決めることはできますが、FileSaver.js は保存するだけなので、ここでは JSON.strinfify を使用して Blob を文字列に変換する必要があります。

デバッグ

[[246862]]

10. 前処理と後処理の正確性を確認する

ナンセンスではありますが、「ゴミデータ、ゴミ結果」というのは確かに真実です。ラベルは正しく、各レイヤーの入力と出力は一貫している必要があります。特に、画像に対して何らかの前処理や後処理を行った場合は、こうした小さな問題を見つけるのが難しい場合もあるため、より注意する必要があります。したがって、多少の労力はかかりますが、ナイフを研ぐことで木を切る作業が遅れることはありません。

11. カスタム損失関数

TensorFlow.js には、誰でも使用できる既製の損失関数が多数用意されており、一般的にはそれで十分なので、独自の損失関数を作成することはお勧めしません。実際に自分で書いてみたい場合は、必ず事前にテストしてください。

12. データのサブセットにオーバーフィッティングを試みる

モデルを定義した後、まず 12 枚または 20 枚の画像を選択して、損失関数が収束するかどうかを確認することをお勧めします。 ***結果を視覚化することで、モデルが成功する可能性があるかどうかを明確に確認できます。

[[246863]]

これを行うことで、モデルと前処理における低レベルのエラーを早い段階で発見することもできます。これは実際には項目 11 で説明したテスト損失関数です。

パフォーマンス

13. メモリリーク

TensorFlow.js がガベージ コレクションを自動的に支援しないことをご存知かどうかはわかりません。テンソルによって占有されているメモリは、tensor.dispose() を呼び出して手動で解放する必要があります。リサイクルを忘れると、遅かれ早かれメモリリークが発生します。

メモリリークがあるかどうかは簡単に判断できます。テンソルの数を確認するために、各反復で tf.memory() を出力してみましょう。増加し続けなければ、漏れはありません。

14. テンソルではなくキャンバスのサイズを変更する

TF.fromPixels を呼び出す前にキャンバスをテンソルに変換するには、キャンバスのサイズを変更します。そうしないと、すぐに GPU メモリが不足します。

トレーニング画像がすべて同じサイズであれば問題はありませんが、明示的にサイズを変更する必要がある場合は、以下のコードを参照してください。 (以下の記述は tfjs-core の現在の状態でのみ有効であることに注意してください。現在、tfjs-core バージョン 0.12.14 を使用しています)

15. バッチサイズを慎重に選択する

各バッチ内のサンプル数、つまりバッチ サイズは、使用する GPU とネットワーク構造によって異なることは明らかです。そのため、さまざまなバッチ サイズを試して、どれが最も高速かを確認するのが最適です。私は通常 1 から始めますが、バッチ サイズを大きくしてもトレーニングの効率が向上しないことがあります。

16. IndexedDBを有効活用する

私たちがトレーニングに使用するデータセットはすべて画像なので、かなり大きくなることがあります。毎回ダウンロードするのは間違いなく非効率です。IndexedDB を使用して保存するのが最善の方法です。 IndexedDB は実際にはブラウザに埋め込まれたローカル データベースであり、任意のデータをキーと値のペアの形式で保存できます。データの読み取りと保存は、わずか数行のコードで実行できます。

17. 損失関数の値を非同期的に返す

損失関数の値をリアルタイムで監視するには、次のコードを使用して自分で計算し、非同期で返すことができます。

各トレーニング期間後に損失関数の値をファイルに保存する場合、そのようなコードにはいくつかの問題が発生することに注意してください。損失関数の値は非同期的に返されるようになったため、保存する前に最後の Promise が返されるまで待つ必要があります。しかし、私は通常、問題が終了してから保存するまで 10 秒待ちます。

18. 重量の定量化

小型で高速という目標を達成するには、モデルのトレーニングが完了した後に重みを量子化してモデルを圧縮する必要があります。重み量子化はモデルのサイズを縮小するだけでなく、モデルの速度を向上させるのにも役立ち、欠点がなくほとんどすべての利点があります。このステップにより、モデルが小さく高速になり、ブラウザでディープラーニング モデルをトレーニングするのに非常に適しています。

これで、ブラウザでディープラーニング モデルをトレーニングするための 18 のヒント (実際には 17 のヒント) は終了です。この記事を読んで何かを得ていただければ幸いです。

<<:  Megvii Technology: 人工知能が携帯電話の「視覚」革命をリード

>>:  AIは人間の感情を理解できるのか?

ブログ    
ブログ    
ブログ    
ブログ    

推薦する

AI、機械学習、ディープラーニングはOEMにとって重要な市場です

人工知能 (AI) は、世界中の業界関係者のビジネスのやり方を急速に変えています。 AI がビジネス...

機械学習の7つの大罪

機械学習実験の信頼性を損なう7つのよくある間違い[[328516]]機械学習は私たちの世界を変える素...

自動運転分野における機械学習アルゴリズムの応用に関する包括的なレビュー

機械学習は、車内外のセンサーからのデータを融合して、運転者の状態を評価し、運転シナリオを分類するため...

最もわかりやすいAIチップレポート!才能とテクノロジーのトレンドがすべてここにあります

2010年以降、ビッグデータ産業の発展により、データ量は爆発的な増加傾向を示し、従来のコンピューティ...

アマゾンがホームロボット「Vesta」を開発、2019年に販売開始

海外メディアの報道によると、アマゾンのハードウェア研究開発部門Lab126は、「Vesta」(ヴェス...

2024年までにAIがすべての仕事をどう変えるのか

仕事の環境は、主に GenAI の進歩によって、前例のない変化を遂げています。ほんの数年前には初期段...

IDC: アジア太平洋地域のAI支出は大幅に増加、銀行業界がAIに最も投資

IDC の最新の世界人工知能支出ガイドによると、アジア太平洋地域 (日本を除く) の AI システム...

IT サービス管理における 3 つの主要な NLP 使用例

[[421132]] [51CTO.com クイック翻訳]自然言語処理 (NLP) は、機械学習の専...

K平均法アルゴリズム Java実装 クラスタ分析 681 三国志の将軍

1. k-meansアルゴリズムの紹介: k-means アルゴリズムは入力量 k を受け取り、n ...

プログラマーが使用する基本アルゴリズムトップ10

[[188736]]アルゴリズム1: クイックソートアルゴリズムクイックソートは、Tony Hal...

2019年インターネット人材採用レポート:Javaは人気だが、アルゴリズムエンジニアは不足している

技術の変化、才能主導。インターネットにおける現在の仕事の機会とトレンドはどこにありますか?本稿では、...

2018年に人工知能はどのように発展するでしょうか? 13人の専門家の予測を聞いてみよう

ウォール・ストリート・ジャーナル、フォーブス、フォーチュンなどの出版物は、2017 年を「AI の年...

AI聴覚技術は国際紛争に関与したことがあるか?

AI視覚技術がさまざまな業界で応用されるのはもはや目新しいことではなく、現在ではAI聴覚技術も戦場...

2020年のIT開発トレンドは刺激的

[[274294]] [51CTO.com クイック翻訳] Future Today Researc...