アルゴリズム要件実装の難航の記録: 軽量な人間姿勢推定モデル開発への道

アルゴリズム要件実装の難航の記録: 軽量な人間姿勢推定モデル開発への道

[[425432]]

この記事は、ソリューションの選択から再現の試みなど、軽量な人間の姿勢推定モデルを実装する著者の全プロセスを記録したものです。プロジェクト要件を完了するための全体的なアイデアを詳細に説明し、Google のオープンソース MoveNet の再現体験を添えています。この記事は履歴書のあらゆる段階にいる友人の役に立つでしょう!

1. 需要背景

本日、私たちは、自然なシーンにおける対象の人体の重要なポイントをリアルタイムで検出するという新たな要件を受け取りました。

アルゴリズム エンジニアの観点から、要件を分解してみましょう。

1. 人体の重要なポイントの位置を検出することが、人間の姿勢推定のタスクです。

2. リアルタイム性が求められる場合は端末の展開が必要となり、サーバー側での伝送遅延は考慮されません。ちなみに、私たちのハードウェアはあまり良くないので、軽量モデルを使用する必要があります。解像度は大きすぎず、プルーニング、量子化、蒸留の 3 点セットにも備える必要があります。

3. 「自然なシーンで人体をターゲットにする」とは、シーン内に複数の人物がいる可能性があるが、必要なのは 1 つのターゲットのキー ポイントだけであり、それらをどのように区別するかを考慮する必要があることを意味します (この点については後で説明します)。

2. ソリューションの探索

2.1 最初の会議

これまでのプロジェクト経験は、主に顔関連の分類、検出、セグメンテーション、OCR でした。人間の姿勢推定はやったことがなかったのですが、要件分析をした後、最初に感じたのは「とても簡単なはずだ」ということでした。この自信は、以前やった顔のキーポイント検出プロジェクトから来ています。その時の経験では、データをうまく処理し、適切な Loss を使用し、任意のプルーニングされた軽量モデルを使用することで、非常に高い精度を実現でき、組み込みボード上で 10 ミリ秒未満で実行できました (PFLD などは不要)。顔には 68 個の重要なポイントがありますが、人体には 17 個のポイントしかなく、はるかに単純です。

そこで、顔のキーポイントの以前のコードを取り出し、いくつかの詳細を変更し(モデル出力の調整、トレーニングデータの準備、DataLoader の変更など)、まずは少量のデータで実行しました。データはCOCOとMPIIで十分です。あとでインターネットからデータをクロールして拡張することもできます。もちろん、対象シーンのデータがあればもっと良いでしょう。

仕事をうまくやり遂げたいなら、まずモルモットを捕まえなければなりません。つまり、評価指標が必要です。分類ではAccuracyとF1が一般的で、検出ではmAPが一般的で、人の姿勢推定は異なります。Googleに聞いたところ、通常はPCK(PCKh)とOKS+mAPを使用するようです。簡単に言うと、前者は予測点とラベル点の距離を計算し、それを頭の大きさで正規化し、後者はターゲット検出でIOUと同様のOKSを使用して類似度を計算し、APを計算します。 前者は学術界ではあまり使用されていませんが(主にランキングが高すぎるため)、私たちのシーンでは1人だけで済み、エンジニアリングも簡単なので、間違いなくPCKが選択されます。データにヘッドアノテーションがすべて付いているとは限らないこと、シーン内のターゲットのサイズが比較的一貫していることを考慮して、最終的にカスタムPCKを使用することにしました。解像度160では、距離が5未満であれば正しいとみなされます。実際、PCKもaccの一種と見なされているため、後でaccを参照するために使用されます。

最初の実行後、検証セットの acc は 0.81 に達し、問題ないと判断したため、炉にさらに材料を追加し始めました (データの追加、データ バランスの増加、損失の微調整、さまざまなキー ポイント損失に対する異なる重みの設定、特徴抽出が不十分であるとの疑い、FastSCNN のバックボーンの使用、さまざまなパラメーター調整など)。一連の操作の後、ようやくわずかな改善が見られ、val-acc は 0.9869 に達しました。

非常に高いので、成功しているようです。テストのためにボードに展開する前に、まずは自分のコンピューターで実行し、ビジュアルデモを準備して見てみるのが習慣です。私は唖然としました。頭やその他の比較的正確なものを除けば、手のわずかな動きも検出しにくいです。

私の熱意はついに冷たい現実に打ち砕かれました。どうやらこの「簡単なはず」の作業はそれほど簡単ではないようです... たとえひざまずいてでも、掘った穴を埋めなければなりません。失敗から学んだ教訓をまとめ、ゼロからやり直す準備をしましょう。

顔のキーポイント検出の座標点を直接回帰する効果は、特徴分布が比較的集中していることが主な理由で良好です。まず、人間の顔の大きさは比較的一定です。次に、人間の顔は剛体であり、キーポイントの相対的な位置は比較的固定されています。最後に、横顔を除いて、基本的に遮蔽はなく、対象の特徴は比較的明確です。それに比べて、人体のサイズ分布は不均一で、各関節の可動範囲が大きく、相対的な位置が固定されておらず、さまざまな位置の遮蔽や衣服の遮蔽があり、作業がはるかに困難になります。同時に、キーポイントの分布範囲が広すぎるため、回帰に完全接続層を単純に使用すると、一部のニューロンはより適切にトレーニングされる一方で、他のニューロンは適切にトレーニングされない可能性が高く、一般化能力が低下します。

2.2 反省

要点に直接戻るという考えがうまくいかない場合は、私たちは扉を開いて世界に目を向け、現在の主流の解決策を見るべきです。この 2020 年のレビューは非常に優れています: ディープラーニングベースの人間の姿勢推定: 調査。華山派の気派と剣派の有名な戦いと同じように、人体の姿勢にもおそらく異なる派閥があり、戦いはより活発になり、2つの方向に分かれています。

  • 目標学習形式: 直接回帰ポイント座標 VS 回帰ヒートマップ

  • 全体的なテストプロセス:トップボトム VS ボトムアップ

初期の人体姿勢推定は、要点に直接戻ることだったことが判明しました。先人たちの道をただ繰り返しているだけのように思えます。 その後、パフォーマンスが良くないことがわかったので、回帰ヒートマップによるトレーニングに変更しました。 簡単に言うと、元の画像を数回縮小して特徴マップを取得します。この特徴マップ内のキーポイントの位置値は 1 で、背景は 0 です。1 のみに設定すると疎すぎるため、1 をガウスカーネルに変更します。これは実際のセマンティクスにも一致しています。

学習形式を決定したら、テストのプロセスを確認します。上記の私のソリューションは、実際にはトップボトムに属します。つまり、最初に人物を検出し、次にそれらを切り取って各人物のキーポイントを検出します。ボトムアップはその逆で、すべてのキーポイントを直接検出し、次にそれらを順番に人物に組み合わせます。これは実際には、ターゲット検出における 1 段階と 2 段階に似ています。一般的に、トップ ボトム方式は精度は高いですが速度は遅く、ボトム アップ方式は高速ですが精度は低くなります。

同時に、いくつかの優れたオープンソースソリューション(主に比較的軽量なモデルに焦点を当てているため、HRNetなどは含まれていません)についても学びました:AlphaPose、OpenPose、Lightweight OpenPose、BlazePose、Simple Baselines、Fast Human Pose Estimation、Global Context for Convolutional Pose Machines、Simple and Lightweight Human Pose Estimationなど、それでは始めましょう。

2.3 試してみる

2.3.1 ちょっとだけ

上記の実行可能な潜在的なソリューションはそれぞれ個別にテストされます。

  1. 上記の顔のキーポイント回帰モデル (上から下) を変更し、出力をヒートマップに変更し、それに応じてデータ処理と損失を調整します。トレーニング効果は平均、val-acc85 です。

  2. AlphaPoseとOpenPoseはどちらも比較的大きなモデルで、GPUの速度はリアルタイムではほとんど出ません。クライアント側+CPU+低性能ボードで、1秒以上かかると予想されるため、当面は検討しません。同時に、軽量OpenPose(ボトムアップ)プロジェクトを見つけ、ボード上で直接実行したところ、360msかかり、少し希望が持てました。

  3. BlazePose では、TNN モデルを直接使用します。また、Tencent Optical Flow Lab の姿勢推定モデル (Top-Bottom) もオープンソース化されており、BlazePose よりも優れていることがわかりました。そこで、後者を直接テストしました。ボードの読み込みには 200 ミリ秒かかり、変換されたモデル以外の情報はありませんでした。

  4. 事前トレーニング済みモデルでトレーニングされたシンプルなベースライン (上 - 下) では、val-acc は約 0.95 で問題ありません。ただし、軽量ネットワーク (mobilenet-v3) に切り替えると、精度は約 0.9 に低下し、視覚化が非常に悪くなります。

  5. 高速人間姿勢推定(トップ-ボトム)は、砂時計ネットワークと比較して、ステージが半分にカットされ、チャネルが半分にカットされ、他の変更は行われません。蒸留が使用され、損失が2つの部分に分割され、1つは教師の予測結果であり、もう1つはGTです。効果はOKで、720msはわずかに遅くなります。

  6. 畳み込みポーズマシンのグローバルコンテキスト(上 - 下)、事前トレーニング済みモデルが提供され、良好な視覚化効果があり、約 400 ミリ秒です。

  7. シンプルで軽量な人間の姿勢推定 (上から下)、優れた視覚化、250 ミリ秒。

2.3.2 集中火力

総合的に検討した結果、最終的に軽量 OpenPose が最適化の対象として選択されました。

まず、これはボトムアップ モデルであり、人間検出器の追加トレーニング (追加のデータ処理コスト、モデル トレーニング コスト、および推論時間に対応) を必要としません。次に、視覚化の観点から、その精度も最高レベルです。

Lightweight OpenPose を理解するには、まず OpenPose について説明する必要があります。OpenPose は、特徴抽出に VGG を使用し、さらに 2 つのヘッダーを使用して、キー ポイントのヒートマップと PAF のヒートマップをそれぞれ出力し、複数のステージの反復を通じて最適化し (各ステージの入力と出力はこれら 2 つのヒートマップです)、最後に MSE を通じて最適化します。要点のヒートマップはわかりやすいですが、PAFとは何でしょうか?これは論文で提案された部分アフィニティフィールドで、一般的にはアフィニティベクトルフィールドと訳されます。2つのキーポイント間の接続情報を表します。キーポイント間のスケルトン情報として直感的に理解できると思います。実装時には、2つのキーポイント間の単位ベクトル(方向を表す)を見つけて、対応するヒートマップの位置を割り当てます。最後に、複数人物検出問題は二部グラフのマッチング問題に変換され、ハンガリーアルゴリズムを使用して接続されたキーポイントの最適なマッチングを取得します。

Lightweight OpenPose の作者がテストしたところ、元の OpenPose 改良段階の精度は最初の改良段階 1 以降はあまり向上せず、計算量が増加したことがわかりました。また、改良段階ネットワークの 2 つのブランチ、キー ポイントの特定 (ヒートマップ) とキー ポイントの組み合わせ (pafs) には、多くの同一の操作があり、その結果、計算が冗長になることもわかりました。そのため、主に以下の最適化が行われました。

  1. 新しいネットワーク設計。初期段階 + 改良段階の 2 段階ネットワークのみが使用されます。 (ここでは、改良段階 2 のコスト効率が高いと考えています。改良段階 1 の精度はまだ少し低いですが、計算量は多くありません。ただし、改良段階 2 では約 19GFLOP が追加され、精度が約 3% 向上し、コスト効率が向上します。)

  2. 軽量バックボーンを交換します。これを MobileNet に置き換え、拡張畳み込みを使用してネットワークを最適化します。また、一連の比較実験を実施した結果、MoblieNet v1 は実際には MobileNet v2 よりも優れていることがわかりました。

  3. 改良段階におけるキーポイント位置特定(ヒートマップ)部分とキーポイント組み合わせ(pafs)部分のネットワーク重みを共有することで、演算計算量を削減します。最後の 2 つの畳み込み層は 2 つのブランチに分かれており、キー ポイント (ヒートマップ) の位置とキー ポイントの組み合わせ (pafs) を予測します。

  1. オリジナルの OpenPose 改良ステージでは、7x7 畳み込みカーネルが使用されます。著者は、7x7 の代わりに 1x1、3x3、3x3 の 3 つの連続した畳み込みカーネルを使用し、最後の 3x3 では、dilation=2 の膨張畳み込みを使用しました。また、元の 1 つの畳み込みカーネルの代わりに 3 つの畳み込みカーネルが使用されるため、ネットワーク層の数が非常に深くなるため、著者は残差接続を追加します。

軽量 OpenPose ソースコードを研究した後、炉にマテリアルを追加し続けました (バックボーンの変更、剪定、データの追加、解像度の調整、蒸留、さまざまなパラメータの調整など)。一連の操作の後、モデルを取得しました: 速度 80ms、acc0.95 (対応する蒸留教師 acc0.98)

速度はかろうじて許容範囲内で、精度も問題ありませんが、視覚テストは少し不正確で、これはデータに関連している可能性があります。

3. 転機

3.1 譲渡

軽量 OpenPose の最適化を続けるかどうか迷っていたところ、偶然この記事を見つけました。「人体の 17 個の重要なポイントをリアルタイムで検出、Google SOTA 姿勢検出モデル、携帯電話でも実行可能」。この記事では、今年 5 月に Google がオープンソース化した軽量の人間姿勢推定モデルである MoveNet を紹介しています。このモデルには tfjs に対応する API があります。

私は何百回も人混みの中で彼を探したが、振り返ると彼は薄暗い光の中に立っていた。これは神が私のために用意してくれたものではないでしょうか?早速Webページでテストしてみましたが、問題ない感じでした。以前bodypixのtfjsモデルをtfモデルに変換した経験があったので、モデルをダウンロードしてローカルで実行するつもりでした。幸い、今回はMoveNetにtfjsモデルだけでなくtfliteモデルもあり、とても便利になりました。

公式ブログの短い言葉と Netron 可視化ネットワークを通じて、私はモデルについて予備的な理解を得ました。公式は、このモデルは CenterNet に基づいて修正されたと主張していましたが、多くの変更が加えられました (予測スキームは CenterNet に大まかに従っていますが、速度と精度の両方を向上させる注目すべき変更が加えられています)。具体的には、Mobilenetv2+FPNをバックボーンとして4つのヘッダーを出力し、最終的に後処理を経て画像の中心に最も近い人物のキーポイントを出力します。これもボトムアップ派に属していることがわかります。同時に、キーポイント回帰の範囲によって重み付けされ、中心に最も近い人物のキーポイントのみが出力されます。これは、軽量 OpenPose に関する限り、残りの人物の PAF 情報は実際には冗長であるため、私たちのシーンに完全に一致しています。

まずは速度をテストしてみましょう。まず、Android ボードに tflite モデルを直接ロードしようとしたところ、組み込みオペコード 'RESIZE_BILINEAR' バージョン '3' の op が見つかりませんでしたというエラーが報告されました。以前は org.tensorflow:tensorflow-lite:2.0.0 を使用していましたが、2.3.0 を試したら動作しました。速度は1フレームあたり約150ms、連続実行速度は約120msです。次に、いくつかの推論フレームワーク (Tengine、NCNN、MNN など) を試します。ここでは、TNN の使用に慣れています。その結果、tflite から tnn と pb から tnn の両方が失敗しました。デバッグの結果、後処理にある ARG_MAX 演算子がサポートされていないことがわかりました。そのため、後処理なしで mobilenetv2+fpn+4 ヘッダーのモデルを作成し、それを tnn に変換しました。ボード上のテストには約 80 ミリ秒かかりました。

Lightweight OpenPose は大幅に最適化されているため、これ以上の最適化の余地は限られており、前述のように冗長な出力があるのに対し、MoveNet は 80 ミリ秒以上で直接実行でき、人物の要点のみを出力し、Google の承認も得ているため、Lightweight OpenPose を断念し、MoveNet のソリューションを採用して再現を試みることにしました。同時に、プラン B も準備しました。再現できない場合は、tflite のバックボーンの重みを直接エクスポートし、新しい pytorch モデルを作成して重みをロードし、モデル推論出力を取得した後、C++ コードを通じて後処理を実装します。これの欠点は、トレーニングに独自のデータを使用できず、反復して最適化できず、公式の事前トレーニング済みモデルを使用した視覚化の精度が特に高くないことです。

3.2 複製

さあ、袖をまくってMoveNetを再現してみましょう。

モデル構造に基づいてモデルトレーニングを複製することは難しくも簡単でもありません。モデル構造は、他のモデルをコピーすることで構築できます。重要なのは、データの構築方法や損失の選択方法に関する情報がないことです。ガウスカーネルの構築、損失の重みの設定、オプティマイザー、その他のハイパーパラメータ設定など、多くの詳細が隠されています。道は長く困難ですが、歩き続ければ目的地にたどり着きます。一度に一歩ずつしか進むことはできません。

以下の分析はすべて主観的な推測であることを事前に留意してください。実験によって検証され、結果が良好であるだけです。Google の本来の実装が必ずこうなっているというわけではありません。あくまでも参考用です。

3.2.1 モデル構造

モデルの再現は難しくありません。多くのモデルには論文や公式コード、あるいは他者が再現したコードがあり、さらには各種コラムブログでの分解・解析も大いに役立ちます。残念ながら、MoveNetにはこれらがありません。参考にできるのは、Googleの公式ブログでの紹介と、TFHubが提供するトレーニング済みモデルの2つだけです。これは、この記事を共有する本来の目的でもあります。

モデル構造を観察すると、主にバックボーン、ヘッダー、後処理の 3 つの部分に分かれています。

1. バックボーンは前述のとおり非常にシンプルです。つまり、mobilenetv2+fpn です。制御性と柔軟性を確保するために、既存の mobilenetv2 実装の一部は使用せず、自分でレイヤーごとに構築しました (実際、そうする必要はありませんでした。後でバックボーンを変更したときに、既存のモデル コードも直接変更しました)。

2. ヘッダーの構造はさらにシンプルです。バックボーンの特徴マップを入力し、いくつかの畳み込み層を通過して、最終的に各次元の特徴マップを出力します。難しいのは、各ヘッダーの意味を理解することです。全体の構造は次のとおりです。

継続的な分析、推測、テストを経て、私が到達した結論をここで共有したいと思います。説明を簡単にするために、4 つのヘッダーに head_heatmap、head_center、head_reg、head_offset という名前を付けます。

  • head_heatmap の次元は [N, K, H, W] です。ここで、n はバッチサイズで、トレーニング中に自分で指定し、予測中には通常 1 です。K はキーポイントの数 (17 など) を表します。H と W は対応する特徴マップで、入力は 192x192 で、4 倍にダウンサンプリングすると 48x48 になります。これは、現在の画像内のすべての人物のキーポイントのヒートマップを表します。すべての人が対象であることに注意してください。

  • head_centerの次元は[N, 1, H, W]です。ここで、1は現在の画像にいるすべての人物の中心点のヒートマップを表しています。単純にキーポイントと理解していただければ結構です。1つしかないのでチャネルは1です。公式ブログでは算術平均、つまり各人のすべてのキーポイントの算術平均を表していると書かれていますが、効果はよくないことがテストでわかりました。最終的にすべてのキーポイントの最大外接矩形の中心点を取得しました。離れたキーポイントがいくつかある場合、算術平均は近いポイントのほとんどをトレーニングできるかもしれませんが、遠いポイントに対しては効果はあまりよくありません。手首などの遠いポイントにはより注意を払っています。私の方法によると、各ポイントの学習はほぼ同じです。これは意見の問題です。自分のシーンの実験結果を参照してください。

  • head_reg の次元は [N、2K、H、W] で、K 個のキー ポイントがあり、座標は x、y で表され、2K のデータがあり、これはここでの 2K チャネルに対応します。では、データはどのように構築されるのでしょうか。モデル構造の分解によると、各人物の中心座標位置には、2Kチャネルの順序に従ってx1、y1、x2、y2、...が順番に割り当てられます。ここで、xとyは、中心点に対する同一人物のキーポイントのオフセット値を表します。オリジナルのMovenetは、特徴マップサイズ48以下の絶対オフセット値を使用しています。これを相対値に変更する(つまり、size48で割って0〜1の間隔に変換する)ことも可能で、収束がわずかに速くなりますが、ほとんど違いはありません。

  • head_offsetの次元は[N, 2K, H, W]です。チャンネルは同じ意味を持ち、Kキーポイントの座標です。唯一の違いは、上が回帰オフセット値で、ここがオフセットであることです。これは、モデルのダウンサンプリングされた特徴マップに量子化エラーが発生する可能性があることを意味します。たとえば、192解像度のx = 0とx = 3を48解像度の特徴マップにマッピングすると、座標は0になります。同時に、回帰エラーもあり、ここで一緒にトレーニングされます。

3. 後処理は、さまざまな奇妙な操作があるため、比較的面倒です。このステップは、Netron の視覚化と組み合わせて段階的に推測し、公式ブログと組み合わせて慎重に分析するしかありません。構造は次のようになり、従来の CNN 構造ではないことがわかります。

公式の紹介は以下の通りで、これも多くの謎を解き明かします。

皆さんをハラハラさせないように、後処理のプロセスをそのまま説明します。

まず、head_heatmap と head_center にはシグモイドが必要です。これは、位置の重みが後で乗算されるため、主に値の範囲を確保するために、ここでネットワーク構造に書き込むこともできます。

次に、head_center については、サイズが 48x48 の位置重み行列を掛けます。値は、Netron を介して Google の設定からエクスポートできます。Numpy+OpenCV で読み込んで視覚化すると、明るい中心点を持つガウス カーネルであることがわかります。検出したすべての中心点について、このような中心位置重み付けマトリックスを乗算することで、中心に近い人物の重みを増やすことができます。これは、最終的には画像の中心に最も近い人物だけが取得されるためです。

重みを乗算した後、共通の argmax 演算を使用して、最終検出ターゲットの中心点である最大値点の座標を見つけます。この座標を取得したら、head_reg の 2K チャネルの対応する座標位置から 2K の値を取り出し、中心点の座標を追加して大まかなキー ポイントの位置を取得します。最初はこれがテストの主な出力だと思っていましたが、後で、ここでの重要なポイントは、単なる大まかな回帰座標オフセットであるため、実際には非常に不正確であることがわかりました。

その実際の機能は、大まかなキー ポイント座標ごとに、この座標点を中心とした重みマトリックスを生成することです。ここではガウス カーネルは存在せず、0 から 47 までの等差数列を使用して直接構築できます。 大まかなキーポイントの最小座標とその周囲を増加させる重み行列を構築した後、0 による除算を防ぐために定数 (1.8 など) を追加し、この重み行列で初期 head_heatmap を除算し、K チャネルを通じて argmax を計算して、洗練されたキーポイント座標を取得します。なぜこれをするのですか? 実際、アイデアは非常に単純で、キーポイントの範囲を大まかに特定し、現在の人物に属する可能性が最も高いキーポイントを重み付けして見つけるというものです。先ほど、ソリューションがボトムアップであると述べたため、head_heatmap はすべての人のすべてのキーポイントを検出します。このワンステップ操作により、中心点に最も近い人物のキーポイントを抽出できます。

最後に、座標点に応じて、head_offset の対応する座標位置に移動し、オフセット値を取得して追加します。信頼度は、head_heatmap のシグモイド後の値です。

3.2.2 データ処理

最後に、モデル構造と後処理プロセスを分析しましたが、まだデータを入力してターゲット関数を定義する必要があるため、トレーニングを開始できません。

後処理プロセスを理解してしまえば、データ構築は難しくありません。注目すべき点の 1 つは、ヒートマップのガウス カーネルをどのように構築するかです。最初は cv2.GaussianBlur を使用して生成しました。視覚化は良好に見えましたが、後でデバッグ中に問題が見つかりました。単一のポイントでは影響はありませんが、複数の近いキーポイントがある場合、ガウスカーネルの最大値が影響を受け、1 より小さい値になる可能性があります。そこで、CenterNet と Lightweight OpenPose でのガウスカーネル生成を試してみました。前者は古典的なガウスカーネルで、後者は指数曲線に従って生成されます。最終的に後者を選択しました。 MoveNetの後処理では、重みを掛け合わせて最大値を取るというステップがあるため、異なる点の区別を強めるには(例えば、遠い点の信頼度は1で、近い点の信頼度は0.9なので、この時は近い点0.9を取る)、異なる距離にある点の重み差を大きくする必要があります。しかし、同じ点のヒートマップ範囲内での中心点の変化を小さくするには(例えば、同じガウスカーネルの最大値は1で、2番目に大きいのは0.9ですが、0.9の方が中心に近いので、この時はやはり1を取る)、隣接する点の間隔を狭くする必要があります。これら 2 つの矛盾の場合、重みマトリックスは Google が提供する既知の値です。より合理的な解決策は、指数曲線によって生成されたヒートマップを選択することです。つまり、同じガウスカーネル内の異なるポイント間の差を大きくすることです。最後に、ハイパーパラメータとして調整できるガウスカーネルのサイズ半径に注意してください。元の画像に重ねて、妥当かどうかを分析することをお勧めします。ターゲットのサイズに応じて、異なる半径サイズを設定するのが最適です。

もう 1 つの細かい点は、中心点の座標に対応する head_reg 上の点にのみ値を割り当てると、回帰値を取得するたびに点が 1 つしかないため学習が困難になることです。そのため、周囲の円にも値を割り当てます。割り当てられた座標の対応する加算と減算にのみ注意してください。

3.2.3 損失関数

一般的に、このようなヒートマップデータでは、Lightweight OpenPose などの L2 損失がより一般的に使用され、CenterNet では Focal 損失が使用されます。実際、Focal 損失も L2 損失から最適化されていますが、カテゴリの重み付けに応じたカテゴリの不均衡の問題と、信頼度の重み付けに応じた難しいサンプルと簡単なサンプルの問題のみを処理します。

最終的には、正負のサンプルのバランスをとることに相当する、MSE の加重バージョンを使用しました。ヒートマップ + ガウス カーネル法では背景が大きな割合を占めますが、実験効果が良くなかったため、焦点損失のガンマは追加されませんでした。この重み付けも実装が簡単です。ラベルは 0 ~ 1 の値を持つ行列だからです。k を掛けて 1 を加えるだけで、1 ~ k+1 の値の範囲が得られます。つまり、値が 1 の位置は重み k+1 に対応し、値が 0 の位置、つまり背景は重み 1 に対応します。この k はデータの状況に応じて調整でき、基準値は 5 ~ 10 です。基準コードは次のとおりです。

  1. 損失 = torch.pow((事前ターゲット), 2 )
  2. 重みマスク = ターゲット*k+ 1  
  3. #ガンマ = torch.pow(torch.abs(ターゲット-pre), 2 )
  4. 損失 = 損失*重みマスク #*ガンマ

最後に、head_heatmap と head_center は加重 MSE を使用し、head_reg と head_offset は L1 Loss を使用しました。これも CenterNet への参照です。

最後に考慮すべきことは、さまざまな損失の重みです。初期のデバッグでは、大きさの違い (head_reg) が絶対座標の違いであるため、head_heatmap:head_center:head_reg:head_offset=1:1:0.1:1 に設定しました。最終的な最適化の後、1:1:1:1 を直接使用しました。

この時点で、MoveNet 全体がほぼ再現され、acc は 95 に到達できます。いくつかのバグを修正し、いくつかの詳細を最適化すると、基本的に 97 に到達できます。ただし、ビデオ デモの視覚化は満足できるものではないため、詳細な最適化のベースラインとして使用する必要があります。

4. 錬金術の道

ベースラインができてトレーニング コードの準備ができたので、いよいよ待望の錬金術フェーズを開始します。

実際、MoveNet を再現するプロセスには、損失の選択やガウスカーネルの生成など、いくつかの最適化が含まれています。最初は効果が良くないため、それが誤った再現によるものなのか、最適化が不十分なためなのかはわかりません。ここでは反復的なデータクリーニングと一般的なデータ強化について詳しく説明しません。私に深い印象を残したもののいくつかについてお話ししたいと思います。

私の提案は、まず視覚分析+実験検証を通じてデータ強化計画を決定し、次にモデル構造を調整し、最後に損失とさまざまなハイパーパラメータを最適化することです。これにより、繰り返しの実験をある程度回避できます。

1つ目はデータの拡張です。Googleは、クリーンアップされたCOCOデータセットを使用するだけでなく、YouTubeからいくつかのヨガとフィットネスのビデオをクロールし、画像と注釈を生成しました。元のCOCO、MPIIなどの写真には、ヨガなどの特別なポーズがまだ欠けているため、データの不均衡が発生します(顔のキーの口の開閉に似ています)。したがって、コードにデータバランスを追加することを検討するだけでなく、一部のデータを拡張するのが最善の方法です。そのため、Bilibiliからヨガ、フィットネス、体操、ダンスなどのビデオ注釈もダウンロードしました。

第二に、ターゲット検出では、ターゲットボックスの水平方向の座標も繰り返します。手首ではなく、これは小さな手首です。

ターゲットシーンから収集された数百の写真のキーポイントエリアの分布を見てみましょう。

次に、ランダム作物、作物の範囲などを調整し、最終的には元の分布よりもはるかに優れていることがわかります。

次のステップは、Googleの元のソリューションが私の個人的な経験によると、モデル構造の最適化です。 FPNを追加して、元のMovenet融合レイヤーで使用しましたが、ネットワーク構造ブロックの違いにより、MobileNETV3とShufflenETV2の3つの特徴層のみを融合しました。多くの実験テストといくつかの経験的剪定の後、shufflenetv2+fpnが最終的に0.75の幅係数で選択され、チャネルの数でいくつかの剪定が行われました。

同時に、シグモイドは、0.5 *(x/(1+torch.abs(x))+0.5に置き換えられ、速度は数ミリゼーションツールの問題を解決します。

その後、モデルが訓練されている間、「姿勢推定技術の概要」というタイトルの記事に出会い、骨の損失のいくつかを試しましたが、援助はわずかな改善もありましたが、自動加重損失はこのモデルに明らかな影響を与えませんでした。

最後の部分は、いくつかのマトリックス操作を伴うため、後でC ++バージョンを使用することを計画しています。 。

この時点で、プロジェクト全体が掘り出したほとんどの穴を埋め、最終的に検証セットとテストセットの両方で99%のACCを達成しました(蒸留する予定はありません)。視覚化効果も良好ですが、検証セットがすでに非常に高いため、まだ改善の余地があります。

V. 結論

要約すると、私は最初の人間の姿勢の推定の分野に精通しておらず、いくつかの迂回路を取りました。同時に、私はソリューションの選択に一見役に立たない試みをしましたが、それは単純なベースラインと軽量のオープンで、人間の姿勢の推定の関連プロセスを深く理解する機会を与え、したがって、Movenetモデルファイルに基づいてトレーニングプロセス全体を再現しました。最適化後、精度は飽和に近く、元のMovenet Pure Backboneの80msから80ミリ秒から、後処理プロセス全体を含む60msを超えるまで改善されました。

最後に、通常の見通しを見てみましょう。

  1. 私のシナリオでは、速度は最初に受け入れられ、その後、このソリューションの精度を改善する余地があります。

  2. DSNTおよびDark Solutionsを試してください。

  3. MPLLデータセット評価リストの敵対的なセマンティックデータ増強で提案されたデータ増強を94.1%にしてください。

  4. PytorchのQATはONNXの輸出をサポートせず、推論フレームワークに変換することができないため、量子化認識トレーニング(QAT)は行われませんでした。ただし、トレーニング後の量子化の実際の加速は明らかです。Movenetには重量操作がかかります。

  5. 今年の軽量のネットワークを試してみてください。

私はあまり知識がありませんので、私が犯したことや議論はどんな間違いでも指摘してください。

<<:  顔認識技術はスマート建設現場やスマートコミュニティにどのようなメリットをもたらすのでしょうか?

>>:  Pythonでグラフを描いてニューラルネットワークを理解する

ブログ    

推薦する

産業用拡張現実(AR)は、機器のメンテナンス、現場サービス、従業員のトレーニングを容易にします。

拡張現実技術の可能性は、小売、エンターテインメント、教育などのクリエイティブ産業を超えて広がります。...

産業用 AI が将来、精製業界にどのような力を与えるか

[[347965]]研究によると、人工知能技術は石油精製業界に大きな利益をもたらす可能性があるそうで...

Google ドキュメントでテキスト要約を自動的に生成できるようになりました。

私たちの多くは、毎日たくさんのファイルを処理する必要があります。新しい文書を受け取ったとき、通常は、...

無料の Python 機械学習コース 1: 線形回帰アルゴリズム

最も基本的な機械学習アルゴリズムは、単一の変数を持つ線形回帰アルゴリズムです。現在、非常に多くの高度...

...

0からNまで、ハンワンテクノロジーが再び人工知能のトレンドに火をつける

本日、「0からNへ・原始開拓」をテーマにした2021年漢王科技秋季新製品発表会がオンラインで開催され...

...

電子商取引検索アルゴリズム技術の進化

2018年9月28日、アリババの電子商取引検索部門は「未来を探して推奨する」をテーマにした技術サミッ...

人工知能が伝統文化に新たな命を吹き込む。パンダ型ロボット「Youyou」が国境を越えて「新年クロストーク会議」に参加

「パンダはトークができる、パンダはジョークを言うことができる、パンダは書道を書ける、そしてパンダはチ...

...

ディープラーニングパーセプトロンの原理の詳しい説明

前回の機械学習のトピックは終了しました。機械学習の分野でよく使用されるアルゴリズム、モデル、その原理...

...

...

普通のプログラマーはどうやって AI を活用するのでしょうか?

[[199775]]現在、人工知能はますます人気が高まっている分野となっています。普通のプログラマ...

強化学習アルゴリズムの分類をさまざまな観点から理解します

この記事は、公開アカウント「Reading the Core」(ID: AI_Discovery)か...