昨日、機械学習とNVIDIA DIGITSに関する
記事を公開しまし
た 。 約束されたように、今日の記事はすべてがそれほど良くない理由+ DIGITSのフレーム内のオブジェクトを選択する例です。
NVIDIAは、DIGITSで開発および実装されたDetectNetグリッドに関するPRを開始しました。 グリッドは、画像内の同じ/類似したオブジェクトを見つけるためのソリューションとして配置されます。

これは何ですか
年の初めに、私
は何度か面白いネット
Yolo について言及しました。 一般に、私が話したすべての人々は、Faster-RCNNの方がはるかに速くて簡単であるという言葉で彼女にかなり否定的に反応しました。 しかし、NVIDIAのエンジニアはこれに
触発され、グリッドをCaffeで組み立ててDetectNetと呼びました。
グリッドの原理は、Yoloと同じです。 画像のネットワーク出力(N * a * N * a)は配列N * N * 5であり、サイズa * aの元の画像の各領域に対して、5つのパラメーターが入力されます:オブジェクトの存在とサイズ:
プラスメッシュ:
- すぐにカウントします。 フレームあたり10〜20ミリ秒を取得しました。 Faster-RCNNが100〜150を費やしていたとき。
- 学び、調整するだけです。 Faster-RCNNには多くの作業がありました。
1つマイナス:より良い検出のソリューションがあります。
話を始める前の一般的な言葉
昨日書いたカテゴリ認識とは異なり、オブジェクトの検出は不十分です。 ユーザーフレンドリーではありません。 記事のほとんどは、この奇跡を起こす方法に関するものです。 残念ながら、このアプローチは、システムとその数学のロジックを理解せずに何かを行うことができるというDIGITSの当初のアイデアを殺します。
ただし、まだ開始している場合は、使用すると便利です。
何を認識しますか
数年前、私たちは車の番号について完全にクレイジーな
アイデアを持っていました。 その結果、一連の
記事が作成されました。 私たちが投稿した写真のまともな
データベースが含まれていました。
私は開発の一部を使用し、DIGITSを通じて数字を検出することにしました。 したがって、それらを使用します。
正しい方法でマークアップされたベースは、他の
目的には非常に小さかったです。 しかし、訓練するのに十分。
行こう
メインメニューで[新しいデータセット]-> [画像]-> [オブジェクト検出]を選択すると、データセットを作成するためのメニューが表示されます。 ここで指定する必要があります:
- トレーニング画像フォルダ-画像フォルダ
- トレーニングラベルフォルダー-テキストキャプション付きのフォルダー
- 検証画像フォルダ-チェックする画像のあるフォルダ
- 検証ラベルフォルダー-テキスト署名のあるフォルダー
- パッド画像-画像がここで示されているよりも小さい場合は、黒の背景で補足されます。 複数の場合-ベースの作成が落ちる¯\ _(ツ)_ /¯
- 画像のサイズ変更-画像のサイズ変更
- 最小ボックスサイズ-この値を設定するのが最善です。 これは、検証中のオブジェクトの最小サイズです。
困難があります。 説明付きの画像にテキスト署名を作成する方法は? 公式のDIGITSリポジトリにあるNVIDIA Github
の例では、これについては控えめに言及していますが、kittiデータセットの場合と同じであるとのみ言及しています。 すぐに使えるフレームワークのユーザーに対するこのアプローチには、多少驚きました。 しかし、約 私は行って、ベースをダウンロードし、そこにドッキングし、それを読みました。 ファイル形式:
Car 0.00 0 1.95 96.59 181.90 405.06 371.40 1.52 1.61 3.59 -3.49 1.62 7.68 1.53 Car 0.00 0 1.24 730.55 186.66 1028.77 371.36 1.51 1.65 4.28 2.61 1.69 8.27 1.53 Car 0.00 0 1.77 401.35 177.13 508.22 249.68 1.48 1.64 3.95 -3.52 1.59 16.82 1.57
ファイルの説明:
当然、ここではほとんどのパラメーターは不要です。 実際には、「bbox」パラメータのみを残すことができ、残りはまだ使用されません。
後で判明したように、ファイル形式がまだ署名さ
れているDIGITSの別の
チュートリアルがありました。 しかし、彼はリポジトリにありませんでしたDIGITS¯\ _(ツ)_ /¯
使用するものについての私の推測が正しいことを確認しました:

教え始める
クラス。 ベースが完成し、トレーニングを開始します。 トレーニングのために、
例で指定されているのと同じ設定を設定する必要があります。
- なしで平均を減算
- 0.0001の基本学習率
- ADAMソルバー
- ベースを選択してください
- [カスタムネットワーク]タブを選択します。 ファイル「/caffe-caffe-0.15/examples/kitti/detectnet_network.prototxt」からテキストをコピーします(これはもちろん、nvidiaのカフェフォークにあります)。
- 事前にトレーニングされたGoogleNetモデルをここからダウンロードすることもお勧めします。 「事前学習済みモデル(s)」で示します
また、私は次のことをしました。 コピーしたグリッド「detectnet_network.prototxt」について、すべての画像サイズの値「1248、352」をデータベースの画像のサイズに置き換えました。 これがなければ、学習は落ちました。 まあ、もちろん、チュートリアルのどれもこれを持っていません...¯\ _(ツ)_ /¯
損失チャートはダウンし、学習は終了しました。 しかし...精度チャートはゼロです。 なに?
私が見つけた2つのチュートリアルのいずれも、この質問に答えていません。 グリッドの説明を詳しく調べに行きました。 掘る場所は、すぐに明らかになりました。 損失が減ると、トレーニングが続きます。 検証パイプラインのエラー。 そして本当に。 ネットワーク構成にブロックがあります:
layer { name: "cluster" type: "Python" bottom: "coverage" bottom: "bboxes" top: "bbox-list" python_param { module: "caffe.layers.detectnet.clustering" layer: "ClusterDetections" param_str: "1024, 640, 16, 0.05, 1, 0.02, 5, 1" } }
疑わしいようです。
クラスタリング層の説明を開くと、コメントを見つけることができます。
これらが急流であることが明らかになります。 そこでエッセンスを掘り下げずに3つの数字をランダム化しました。 学習が進み、検証が成長し始めました。 約5時間でいくつかの妥当なしきい値に達しました。

しかし、これは残念です。 トレーニングが成功すると、100%の画像が露出しませんでした。 この層の意味を掘り下げて理解する必要がありました。
レイヤーは、取得した仮説のコレクションを単一のソリューションに実装します。 メインツールとして、OpenCVモジュール「cv.groupRectangles」がここで使用されます。 これは、長方形のグループを1つの長方形に関連付ける関数です。 ご存知のように、ネットワークはオブジェクトの近くに多くのポジティブがあるべき構造を持っています。 それらを単一のソリューションにまとめる必要があります。 収集アルゴリズムには多数のパラメーターがあります。
- gridbox_cvg_threshold(0.05)-オブジェクト検出しきい値。 実際、数字を見つけたという事実の信頼性。 小さい-より多くの検出。
- gridbox_rect_threshold(1)-数値を決定するために動作する必要がある検出器の数
- gridbox_rect_eps(0.02)-1つの仮説にまとめるために、長方形のサイズを何回変えることができるか
- min_height-オブジェクトの最小の高さ
今では、それらを拾い上げて機能させるだけで十分です。 そして今、ユーモア。 Takiは
3番目のチュートリアルでもあり、全体の一部が説明されています。
しかし、すべてではありません¯\ _(ツ)_ /¯
結果は何ですか
その結果、グリッドが強調表示したものを確認できます。
かなりうまくいきます。 一見、使用したHaarよりも優れています。 しかし、小さなトレーニングベース(〜1,500フレーム)が感じられることがすぐに明らかになりました。 汚れた数字はデータベースで考慮されませんでした=>検出されません。 データベースは、数の強力な見通しを考慮しませんでした=>検出されません。 大きすぎても小さすぎても考慮されません。 さて、あなたはポイントを得る。 要するに、あなたはあまりに怠zyである必要はなく、通常5000個の数字をマークアップします。
認識機能を使用すると、アクティベーションカード(
1、2、3 )でクールな写真を見ることができます。 次の各レベルで、数字がよりはっきりと見えることがわかります。
実行方法
楽しい瞬間-結果は20行までのコードで開始できます。 そして、それは既製の番号検出器になります:
import numpy as np import sys caffe_root = '../'
ここに、グリッド用のデプロイファイルと、トレーニングされたネットワークの重みを配置します(必要な場合)。