特定のドメインに特化した物体検出モデルの最適化方法

特定ドメインに特化した物体検出モデルの最適化手法―効果的なアプローチを探る

特定の問題を解決するために、より優れたかつ高速なモデルを設計する

Photo by paolo candelo on Unsplash

物体検出は、その低い計算コストで優れた結果を提供する能力により、学術から産業分野に至るまで、さまざまなドメインで広く使用されています。ただし、公開されているオープンソースのアーキテクチャが非常に多いにもかかわらず、これらのほとんどは一般的な問題を解決するために設計されており、特定の状況には適していない場合があります。

例として、この分野の研究のベースラインとして一般的に使用される「Common Objects in Context(COCO)」データセットを挙げることができます。このデータセットには、さまざまな照明条件、背景、サイズで90の異なるクラスが含まれています。しかし、時には直面する検出の問題は比較的単純です。シーンやサイズの変動が少ない、ごくわずかな異なる物体を検出したい場合もあります。この場合、一般的なハイパーパラメータのセットを使用してモデルをトレーニングすると、不必要な計算コストを引き起こすモデルになる可能性があります。

この視点を念頭に置いて、この記事の主な目的は、より複雑でないタスクに対してさまざまな物体検出モデルを最適化するためのガイダンスを提供することです。計算コストを削減し、平均精度を損なうことなく、より効率的な構成を選択するお手伝いをしたいと思います。

背景の提供

私の修士課程の目標の1つは、計算要件が最小限の手話認識システムを開発することでした。このシステムの重要なコンポーネントは、以下の図に示す通り、リアルタイムで手話通訳者の手や顔を検出することでした:

この研究で作成されたHFSLデータセットのサンプル。画像:著者によるもの。

上記のように、この問題は比較的単純で、画像には2つの異なるクラスと同時に表示される3つの物体しか含まれていません。そのため、私の目標は、高い平均精度(mAP)を維持しながら計算コストを削減し、スマートフォンなどのエッジデバイスで効率的な実行を可能にするため、モデルのハイパーパラメータを最適化することでした。

物体検出のアーキテクチャとセットアップ

このプロジェクトでは、以下の物体検出アーキテクチャがテストされました:EfficientDetD0、Faster-RCNN、SDD320、SDD640、およびYoloV7。ただし、ここで紹介する概念は、他のさまざまなアーキテクチャにも適用できます。

モデル開発には、主にPython 3.8とTensorFlowフレームワークを使用しましたが、YoloV7ではPyTorchを使用しました。ここで提供されるほとんどの例はTensorFlowに関連していますが、これらの原則を好みのフレームワークに適応させることができます。

ハードウェアに関しては、テストはRTX 3060 GPUとIntel Core i5-10400 CPUを使用して行われました。すべてのソースコードとモデルはGitHubで利用可能です。

物体検出器の微調整

TensorFlowを使用して物体検出を行う場合、すべてのハイパーパラメータは「pipeline.config」という名前のファイルに格納されていることを理解することが重要です。このプロトバファイルは、モデルのトレーニングと評価に使用される設定を保持しており、たとえばTF Model Zooからダウンロードした事前トレーニング済みモデルにも同様のファイルが含まれています。この文脈では、物体検出器の最適化のために私が実装したパイプラインファイルの修正について説明します。

ここで提供されているハイパーパラメータは、手と顔の検出(2つのクラス、3つのオブジェクト)に特化して設計されていることに注意してください。自分の問題領域に合わせて調整してください。

一般的な簡略化

すべてのモデルに適用できる最初の変更は、クラスごとの最大予測数と生成されるバウンディングボックスの数を100からそれぞれ2と4に減らすことです。これは、train_configオブジェクト内のmax_number_of_boxesプロパティを調整することで実現できます:

...train_config {  batch_size: 128  sync_replicas: true  optimizer { ... }  fine_tune_checkpoint: "PATH_TO_BE_CONFIGURED"  num_steps: 50000  startup_delay_steps: 0.0  replicas_to_aggregate: 8  max_number_of_boxes: 4 # <------------------ この行を変更する  unpad_groundtruth_tensors: false  fine_tune_checkpoint_type: "classification"  fine_tune_checkpoint_version: V2}...

その後、オブジェクト検出器のpost_processing内にあるmax_total_detectionsmax_detections_per_classを変更します:

post_processing {  batch_non_max_suppression {    score_threshold: 9.99999993922529e-09    iou_threshold: 0.6000000238418579    max_detections_per_class: 2 # <------------------ この行を変更する    max_total_detections: 4     # <------------------ この行を変更する    use_static_shapes: false  }  score_converter: SIGMOID}

これらの変更は重要です、特に私の場合は画像に同時に表示されるオブジェクトが3つのオブジェクトと2つのクラスしかないためです。予測数を減らすことで、非最大値抑制(NMS)を通じて重なり合うバウンディングボックスを除去するための反復回数が減少します。したがって、検出するクラスの数が限られており、シーンに表示されるオブジェクト数も限られている場合は、このハイパーパラメータを変更すると良いでしょう。

具体的なアーキテクチャの詳細を考慮して、個別に追加の調整を行いました。

シングルショットマルチボックスディテクター(SSD)

オブジェクト検出を行う際には、異なる解像度を試すことが常に良いアイデアです。このプロジェクトでは、320×320ピクセルと640×640ピクセルの入力画像解像度で、モデルのSSD320とSSD640の2つのバージョンを使用しました。

両モデルとも、最初の変更点の一つは、Feature Pyramid Network(FPN)の深さを5から4に減らし、最も表層のレイヤーを削除することです。FPNは複数の特徴マップサイズで動作する強力な特徴抽出メカニズムです。ただし、より大きなオブジェクトに対しては、高解像度の画像向けに設計された最も表層のレイヤーは必要ないかもしれません。つまり、検出しようとしているオブジェクトがあまり小さくない場合は、このレイヤーを削除すると良いでしょう。この変更を実装するには、「fpn」オブジェクト内の「min_level」属性を3から4に調整します:

...feature_extractor {  type: "ssd_mobilenet_v2_fpn_keras"  depth_multiplier: 1.0  min_depth: 16  conv_hyperparams {    regularizer { ... }    initializer { ... }    activation: RELU_6    batch_norm {...}  }  use_depthwise: true  override_base_feature_extractor_hyperparams: true  fpn {    min_level: 4 # <------------------ この行を変更する    max_level: 7    additional_layer_depth: 108 # <------------------ この行を変更する  }}...

また、より高解像度のモデル(SSD640)では、「additional_layer_depth」を128から108に簡略化しました。同様に、両モデルの「multiscale_anchor_generator」の深さも5から4レイヤーに調整しました。以下に示します:

...anchor_generator {  multiscale_anchor_generator {    min_level: 4 # <------------------ この行を変更する    max_level: 7    anchor_scale: 4.0    aspect_ratios: 1.0    aspect_ratios: 2.0    aspect_ratios: 0.5    scales_per_octave: 2  }}...

最後に、バウンディングボックスの予測を生成するネットワーク(「box_predictor」)のレイヤー数は4から3に減少しました。SSD640の場合、ボックスプレディクターの深さも128から96に減少しています、以下に示されています:

...box_predictor {  weight_shared_convolutional_box_predictor {    conv_hyperparams {      regularizer { ... }      initializer { ... }      activation: RELU_6      batch_norm { ... }    }    depth: 96 # <------------------ この行を変更    num_layers_before_predictor: 3 # <------------------ この行を変更    kernel_size: 3    class_prediction_bias_init: -4.599999904632568    share_prediction_tower: true    use_depthwise: true  }}...

これらの簡略化は、検出する比較的単純なパターンを持つ限られた数の異なるクラスがあるために行われました。そのため、モデルのレイヤー数と深さを減らすことが可能です。少ない特徴マップでも、画像から必要な特徴を効果的に抽出することができます。

EfficinetDet-D0

EfficientDet-D0に関しては、バイディレクショナルフィーチャーピラミッドネットワーク (Bi-FPN)の深さを5から4へと減少させました。さらに、Bi-FPNの反復回数を3から2へ、特徴マップのカーネルを64から48へと減らしました。Bi-FPNはマルチスケールの特徴融合のための高度な技術であり、素晴らしい結果を生み出すことができます。しかし、より高い計算要求がかかるため、より単純な問題にはリソースの無駄です。前述の調整を実装するには、以下のように「bifpn」オブジェクトの属性を更新してください:

...bifpn {      min_level: 4 # <------------------ この行を変更      max_level: 7      num_iterations: 2 # <------------------ この行を変更      numyaml_filters: 48 # <------------------ この行を変更    }...

その他にも、「multiscale_anchor_generator」の深さをSSDと同様に減らすことが重要です。最後に、バウンディングボックスのネットワークのレイヤーを3から2へと減らしました:

...box_predictor {  weight_shared_convolutional_box_predictor {    conv_hyperparams {      regularizer { ... }      initializer { ... }      activation: SWISH      batch_norm { ... }      force_use_bias: true    }    depth: 64    num_layers_before_predictor: 2 # <------------------ この行を変更    kernel_size: 3    class_prediction_bias_init: -4.599999904632568    use_depthwise: true  }}...

Faster R-CNN

Faster R-CNNモデルは、領域提案ネットワーク(RPN)とアンカーボックスを主要な技術として使用しています。アンカーは、バックボーンCNNの最後の特徴マップ上でスライドウィンドウを反復する際の中心点です。各反復において、分類器は提案がオブジェクトを含む確率を判断し、リグレッサはバウンディングボックスの座標を調整します。検出器が位置に関して不変であることを確保するために、アンカーボックスに対して3つの異なるスケールと3つのアスペクト比を使用し、反復ごとの提案の数を増やしています。

これは浅い説明ですが、このモデルは2段階の検出プロセスを持つため、他のモデルよりも複雑であることが明らかです。しかし、高い精度を保ちながら、速度を向上させるためにシンプルにすることが可能です。

そのために、最初の重要な変更は生成される提案の数を300から50に減らすことです。この削減は、画像に同時に存在するオブジェクトが少数であるため実現可能です。以下のように「first_stage_max_proposals」プロパティを調整することで、この変更を実装できます:

...first_stage_box_predictor_conv_hyperparams {  op: CONV  regularizer { ... }  initializer { ... }}first_stage_nms_score_threshold: 0.0first_stage_nms_iou_threshold: 0.7first_stage_max_proposals: 50 # <------------------ この行を変更first_stage_localization_loss_weight: 2.0first_stage_objectness_loss_weight: 1.0initial_crop_size: 14maxpool_kernel_size: 2maxpool_stride: 2...

その後、モデルから最大のアンカーボックスのスケール (2.0) を除外しました。これは、通訳者がカメラからの固定距離を保つため、手と顔のサイズが一定であるためです。大きなアンカーボックスを持つことは、提案の生成には役立たないかもしれません。さらに、データセット内のオブジェクトは似たような形状であり、アンカーボックスのアスペクト比の1つを削除しました。以下に、これらの調整を視覚的に示します:

first_stage_anchor_generator {  grid_anchor_generator {    scales: [0.25, 0.5, 1.0] # <------------------ この行を変更する    aspect_ratios: [0.5, 1.0] # <------------------ この行を変更する    height_stride: 16    width_stride: 16  }}

ただし、ターゲットオブジェクトのサイズとアスペクト比を考慮することが重要です。この考慮により、あまり役に立たないアンカーボックスを除外し、モデルの計算コストを大幅に減らすことができます。

YoloV7

これに対して、YoloV7にはアーキテクチャの機能性を保つため、最小限の変更が加えられました。主な変更点は、特徴抽出を担当するCNNを簡素化することであり、バックボーンとモデルのヘッドの両方で行われました。このため、ほとんどの畳み込み層のカーネル数/特徴マップ数を減らし、次のモデルを作成しました:

backbone:  # [from, number, module, args]  [[-1, 1, Conv, [22, 3, 1]],  # 0   [-1, 1, Conv, [44, 3, 2]],  # 1-P1/2         [-1, 1, Conv, [44, 3, 1]],   [-1, 1, Conv, [89, 3, 2]],  # 3-P2/4     [-1, 1, Conv, [44, 1, 1]],   [-2, 1, Conv, [44, 1, 1]],   [-1, 1, Conv, [44, 3, 1]],   [-1, 1, Conv, [44, 3, 1]],   [-1, 1, Conv, [44, 3, 1]],   [-1, 1, Conv, [44, 3, 1]],   [[-1, -3, -5, -6], 1, Concat, [1]],   [-1, 1, Conv, [179, 1, 1]],  # 11   [-1, 1, MP, []],   [-1, 1, Conv, [89, 1, 1]],   [-3, 1, Conv, [89, 1, 1]],   [-1, 1, Conv, [89, 3, 2]],   [[-1, -3], 1, Concat, [1]],  # 16-P3/8     [-1, 1, Conv, [89, 1, 1]],   [-2, 1, Conv, [89, 1, 1]],   [-1, 1, Conv, [89, 3, 1]],   [-1, 1, Conv, [89, 3, 1]],   [-1, 1, Conv, [89, 3, 1]],   [-1, 1, Conv, [89, 3, 1]],   [[-1, -3, -5, -6], 1, Concat, [1]],   [-1, 1, Conv, [512, 1, 1]],  # 24   [-1, 1, MP, []],   [-1, 1, Conv, [89, 1, 1]],   [-3, 1, Conv, [89, 1, 1]],   [-1, 1, Conv, [89, 3, 2]],   [[-1, -3], 1, Concat, [1]],  # 29-P4/16     [-1, 1, Conv, [89, 1, 1]],   [-2, 1, Conv, [89, 1, 1]],   [-1, 1, Conv, [89, 3, 1]],   [-1, 1, Conv, [89, 3, 1]],   [-1, 1, Conv, [89, 3, 1]],   [-1, 1, Conv, [89, 3, 1]],   [[-1, -3, -5, -6], 1, Concat, [1]],   [-1, 1, Conv, [716, 1, 1]],  # 37   [-1, 1, MP, []],   [-1, 1, Conv, [256, 1, 1]],   [-3, 1, Conv, [256, 1, 1]],   [-1, 1, Conv, [256, 3, 2]],   [[-1, -3], 1, Concat, [1]],  # 42-P5/32     [-1, 1, Conv, [128, 1, 1]],   [-2, 1, Conv, [128, 1, 1]],   [-1, 1, Conv, [128, 3, 1]],   [-1, 1, Conv, [128, 3, 1]],   [-1, 1, Conv, [128, 3, 1]],   [-1, 1, Conv, [128, 3, 1]],   [[-1, -3, -5, -6], 1, Concat, [1]],   [-1, 1, Conv, [716, 1, 1]],  # 50  ]# yolov7 headhead:  [[-1, 1, SPPCSPC, [358]], # 51   [-1, 1, Conv, [179, 1, 1]],   [-1, 1, nn.Upsample, [None, 2, 'nearest']],   [37, 1, Conv, [179, 1, 1]], # route backbone P4   [[-1, -2], 1, Concat, [1]],   [-1, 1, Conv, [179, 1, 1]],  

先述の通り、ディテクターから一部のレイヤーとフィーチャーマップを削除することは、簡単な問題に対しては通常良いアプローチです。なぜなら、フィーチャーエクストラクターは元々、さまざまなシナリオで数十、または数百のクラスを検出するように設計されており、これらの複雑さに対応し、高い精度を確保するためにより堅牢なモデルが必要だからです。

これらの調整により、パラメータの数を3640万からわずか1410万に減らすことができ、約61%の削減になります。さらに、元の論文で提案されている640x640ピクセルではなく、入力解像度を512x512ピクセルに使用しました。

追加のヒント

オブジェクトディテクターのトレーニングにおいてもう一つの有益なヒントは、アンカーボックスの比率を調整するための「Kmeansモデルの利用」です。これにより、フィギュアの幅と高さを調整し、トレーニングセット内の「Intersection over Union (IoU)の比率を最大化する」ことができます。これにより、アンカーを与えられた問題領域により適応させることができ、適切なアスペクト比で開始することでモデルの収束を向上させることができます。以下の図は、3つのアンカーボックスをSSDアルゴリズムのデフォルトで使用した場合(赤)と、手と顔の検出タスクに最適化されたアスペクト比を持つボックス(緑)とを比較したものです。

異なるバウンディングボックスのアスペクト比の比較。著者提供の画像。

結果の表示

私は独自のデータセットである「Hand and Face Sign Language(HFSL)データセット」を使用して、それぞれのディテクターをトレーニングおよび評価し、mAPとフレームレート(FPS)を主な指標として考慮しました。以下の表は、要約した結果を示しており、かっこ内の値は、説明された最適化のいずれも実装していないディテクターのFPSを表しています。

オブジェクト検出の結果。

ほとんどのモデルは、さまざまなレベルのIntersection over Union(IoU)において高いmAPを保ちつつ推論時間が大幅に短縮されたことがわかります。Faster R-CNNやEfficientDetなどのより複雑なアーキテクチャは、GPU上でのFPSをそれぞれ200.80%および231.78%増加させました。さらに、SSDベースのアーキテクチャもパフォーマンスが大幅に向上し、640および320のバージョンでは、それぞれ280.23%および159.59%の改善が見られました。 YoloV7に関しては、FPSの差はCPU上で最も顕著ですが、最適化されたモデルではパラメータが61%少なくなり、メモリ要件が低減され、エッジデバイスに適しています。

結論

計算リソースが限られている場合や、タスクを素早く実行する必要がある場合があります。このようなシナリオでは、オープンソースのオブジェクト検出モデルをさらに最適化し、計算要件を低減させつつ結果に影響を与えないハイパーパラメータの組み合わせを見つけることができ、様々な問題領域に適した解決策を提供することができます。

この記事があなたがより効率的なオブジェクト検出器をトレーニングするためのより良い選択をするのに役立てば幸いです。説明された概念が理解できなかった場合は、オブジェクト検出アーキテクチャの仕組みについて深く理解することをおすすめします。さらに、特定の問題に基づいてモデルをさらに最適化するために、異なるハイパーパラメータの値を試してみることも検討してください!

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more