yolov5の詳細説明と改良

https://github.com/z1069614715/objectdetection_script

YOLOV5 の改善 - 最適なトランスポート割り当て

Optimal Transport Assignment (OTA) は YOLOv5 の改良であり、検出精度を確保しながら検出速度を大幅に向上できる、より優れたターゲット検出フレームワークです。

従来のターゲット検出フレームワークでは、通常、ターゲットと検出フレームを照合するためにハンガリー アルゴリズムが使用されます。このアルゴリズムは最適なマッチングを見つけることができますが、実際のアプリケーションでは、マッチングの計算が過剰になるため、検出速度が遅すぎることがよくあります。

OTA アルゴリズムは、ターゲットと検出フレーム間の新しい距離測定方法を導入し、計算量を増やすことなくターゲットと検出フレームをより迅速に照合することができます。具体的には、OTA アルゴリズムはターゲットと検出フレーム間の距離を確率分布に変換し、2 つの確率分布間のワッサーシュタイン距離を最小化することでターゲットと検出フレームを一致させます。Wasserstein 距離の計算量が少ないため、OTA アルゴリズムは検出速度を大幅に向上させることができます。

OTA アルゴリズムは検出速度の高速化に加えて、検出精度も向上します。従来のハンガリーのアルゴリズムでは、一部の不正確な一致が最適な一致としてみなされる可能性があり、その結果、検出精度が低下します。OTA アルゴリズムは、2 つの確率分布間のワッサーシュタイン距離を最小限に抑えることで、この状況をある程度回避し、検出精度を向上させることができます。

一般に、OTA アルゴリズムは YOLOv5 の重要な改良点です。ターゲットと検出フレーム間の新しい距離測定方法を導入することで、計算量を増やすことなくターゲットと検出をより迅速に実行できます。フレーム マッチングにより検出速度が向上します。そして正確さ。
以下は、OTA アルゴリズムのコード実装と式です。

式:
まず、2 つの分布ppを定義します。pqqqは、それぞれターゲット ボックスと予測ボックス間の距離分布を表します。この場合、最適なマッチングは次の問題として表すことができます。

min ⁡ T ∈ Ψ E ( i , j ) ∼ T [ di , j ] \min_{T\in\Psi} \mathbb{E}{(i,j)\sim T}[d{i,j}]T ΨE (j )T [ d i ,j ]

其中, d i , j d_{i,j} d jターゲット フレームと予測フレーム間の距離を示します ( TT)T はマッチング行列Ψ \PsiΨ は、すべての正当なマッチング行列のセットを表します。E ( i , j ) 〜 T [ di , j ] \mathbb{E}{(i,j)\sim T}[d{i,j}]E (j )T [ d i ,マッチング行列TT内のj ]Tの制約の下で、ターゲット ボックスと予測ボックス間の距離の期待値。

ターゲットボックスと予測ボックス間の距離を確率分布に変換するには、C ∈ R n × m C\in\mathbb{R}^{n\times m} を定義します。CRn × mは距離行列です。ここで、nnn はターゲット ボックスの数を表し、mmm は予測ボックスの数を表します。C ij C_{ij}Cイジiiを示しますiターゲット ボックスとjjthj 個の予測ボックス間の距離

距離行列CCC は確率分布P ∈ R n × m P\in\mathbb{R}^{n\times m}PRn × mQ ∈ R n × m Q\in\mathbb{R}^{n\times}QRn × m、ここでP ij P_{ij}Pイジiiを示しますiターゲット ボックスとjjthj 個の予測ボックスQ ij Q_{ij}Qイジiiを示しますiターゲット ボックスとjjthj 個の予測ボックスが一致しない確率。次に、次のとおりです。

P ij = exp ⁡ ( − C ij / τ ) ∑ k = 1 m exp ⁡ ( − C ik / τ ) P_{ij} = \frac{\exp(-C_{ij}/\tau)}{\sum_ {k=1}^m\exp(-C_{ik}/\tau)}Pイジ=k = 1メートルexp ( C/ t )exp ( Cイジ/ t)。

Q ij = exp ⁡ ( − C ij / τ ) ∑ k = 1 n exp ⁡ ( − C kj / τ ) Q_{ij} = \frac{\exp(-C_{ij}/\tau)}{\sum_ {k=1}^n\exp(-C_{kj}/\tau)}Qイジ=k = 1exp ( Ckj/ t )exp ( Cイジ/ t)。

その中で、τ \tauτ は、確率分布の滑らかさを制御する温度パラメータです。

最後にPPPQQQ をワッサーシュタイン距離の式に代入すると、ワッサーシュタイン距離を最小化する問題が得られます。

min ⁡ T ∈ Ψ ∑ i = 1 n ∑ j = 1 m T ij C ij \min_{T\in\Psi} \sum_{i=1}^n\sum_{j=1}^m T_{ij} C_{ij}T Ψi = 1j = 1メートルTイジCイジ

s 。と。T 1 n = α , TT 1 m = β , T i , j ∈ [ 0 , 1 ] st \quad T1_n = \alpha, T^T1_m = \beta, T_{i,j}\in[0,1]s T1 _=_TT1 _メートル=b T j[ 0 ,1 ]

その中でもTTさんはTはマッチング行列1 n 1_n1そして1m1_m1メートルそれぞれnnを表しますn寸法とmmm次元の完全な 1 ベクトル、α \alphaαβ \betaβ はそれぞれターゲット ボックスと予測ボックスの数を示します。T1n = α T1_n = \alphaT1 _=α は、各予測フレームが 1 つのターゲット フレームのみと一致できることを意味します。TT 1 m = β T^T1_m = \betaTT1 _メートル=β は、各ターゲット ボックスが 1 つの予測ボックスのみと一致できることを意味します。Ti , j ∈ [ 0 , 1 ] T_{i,j}\in[0,1]T j[ 0 ,1 ] は、マッチング行列の各要素の値の範囲を表します。

コード:
OTA アルゴリズムのコード実装は YOLOv5 に実装されており、https://github.com/ultralytics/yolov5 の models/yolo.py ファイルにあります。以下は、OTA アルゴリズムの主要なコード スニペットです。

まず、距離行列CCを定義します。

距離行列

iou = box_iou(xywh2xyxy(pred_boxes), xywh2xyxy(target_boxes))  # shape(n,m)
iou[iou < 0.001] = 0  # avoid CPU NaN, [0,1]
C = -iou.log()  # cost = -log(iou)  shape(n,m)

次に、マッチング行列TTを計算します。

OT

T = torch.Tensor(ot.sinkhorn(torch.exp(-Cself.ota_tau), self.ota_lambd)).to(device)  # shape(n,m), run Sinkhorn

このうち、ot.sinkhorn() 関数は、Python Optimal Transport ライブラリの Sinkhorn アルゴリズムを使用して、マッチング行列TTを計算します。T._ _ self.ota_tau と self.ota_lambd は、それぞれ OTA アルゴリズムの温度パラメーターと正則化パラメーターを表します。最後に、マッチング行列TTに従って、T は、ターゲット ボックスと予測ボックスの間の距離を計算します。

損失

loss_xy = self.mse_loss(pred[..., :2], t[..., :2])  # xy loss
loss_wh = self.mse_loss(pred[..., 2:4], t[..., 2:4])  # wh loss
loss_obj = self.bce_loss(pred[..., 4:5], t[..., 4:5]) + self.bce_loss(pred[..., 9:10], t[..., 9:10])  # obj loss
loss_cls = self.bce_loss(pred[..., 5:9], t[..., 5:9]) + self.bce_loss(pred[..., 10:], t[..., 10:])  # cls loss
loss_l2 = self.l2_loss(pred_boxes, target_boxes) / self.hyp['giou']  # giou loss
loss = loss_xy + loss_wh + loss_obj + loss_cls + loss_l2  # total loss
loss *= self.ota_lambd
loss += (T * C).sum() * self.ota_tau  # OT loss

総損失を計算する際には、OTA アルゴリズムの正則化項と OT 損失項が追加されます。

上記は、OTA アルゴリズムのコード実装と式です。

YOLOv5にアテンションメカニズムを追加

YOLOv5 にアテンション メカニズムを追加すると、次の利点が得られます。

検出精度の向上: アテンション メカニズムにより、ネットワークが重要な機能にさらに注意を払い、重要でない機能を抑制できるため、検出精度が向上します。

堅牢性の向上: アテンション メカニズムにより、ネットワークがノイズや干渉に対してより堅牢になり、検出の堅牢性が向上します。

小さなターゲットの検出能力の強化: YOLOv5 では、アテンション メカニズムを追加することで小さなターゲットの検出能力を強化できます。これは、小さなターゲットは通常弱い特徴表現を持ち、アテンション メカニズムによりネットワークが小さなターゲットの重要な特徴にさらに注意を払うことができるためです。となり、検出精度が向上します。

モデルの収束を高速化: アテンション メカニズムにより、ネットワークが重要な特徴にさらに注意を払うようになり、それによってネットワークの冗長な計算が削減され、モデルの収束が高速化されます。

YOLOv5 では、アテンション メカニズムが SPP モジュールと PANet モジュールに適用されます。SPP モジュールでは、アテンション メカニズムを使用して、さまざまなスケールの特徴マップの重みを調整し、小さなオブジェクトの検出能力を向上させます。PANet モジュールでは、アテンション メカニズムを使用してさまざまなレベルで特徴マップの重みを調整し、検出精度と堅牢性を向上させます。

import torch
import torch.nn as nn


class SimAM(torch.nn.Module):
    def __init__(self, e_lambda=1e-4):
        super(SimAM, self).__init__()

        self.activaton = nn.Sigmoid()
        self.e_lambda = e_lambda

    def __repr__(self):
        s = self.__class__.__name__ + '('
        s += ('lambda=%f)' % self.e_lambda)
        return s

    @staticmethod
    def get_module_name():
        return "simam"

    def forward(self, x):
        b, c, h, w = x.size()

        n = w * h - 1

        x_minus_mu_square = (x - x.mean(dim=[2, 3], keepdim=True)).pow(2)
        y = x_minus_mu_square / (4 * (x_minus_mu_square.sum(dim=[2, 3], keepdim=True) / n + self.e_lambda)) + 0.5

        return x * self.activaton(y)


if __name__ == '__main__':
    input = torch.randn(3, 64, 7, 7)
    model = SimAM()
    outputs = model(input)
    print(outputs.shape)

このコードは、ニューラル ネットワークの特徴表現能力を向上させるために使用できる類似性に基づく注意メカニズム (SimAM) を実装しています。

SimAM の実装では、特徴マップxxを入力します。xを規格化し、各画素と他の画素との類似度を計算する。具体的には、入力特徴マップx ∈ RB × C × H × W x\in\mathbb{R}^{B\times C\times H\times W} の場合バツRB × C × H × W、ここでBBB はバッチサイズ、CCC はチャンネル数を表し、HHH W W W はそれぞれ特徴マップの高さと幅を表し、SimAM の計算プロセスは次のとおりです。

特徴マップxxを計算しますxの平均値μ ∈ RB × C × 1 × 1 \mu\in\mathbb{R}^{B\times C\times 1\times 1}メートルRB × C × 1 × 1および分散var ∈ RB × C × 1 × 1 var\in\mathbb{R}^{B\times C\times 1\times 1}ワー_ _RB × C × 1 × 1、平均と分散はそれぞれHHH W W W寸法で計算します。

機能マップxxの場合xは標準化された特徴マップx ~ ∈ RB × C × H × W \tilde{x}\in\mathbb{R}^{B\times C\times H\times W} を取得するために標準化されます。バツRB × C × H × W、つまり:

x ~ = x − μ var + ϵ \tilde{x} = \frac{x-\mu}{\sqrt{var+\epsilon}}バツ=ワー_ _+ϵ バツメートル

ここで、ϵ \εϵは、分母のゼロを避けるための小さな定数です。

各ピクセル点xi , j ∈ x ~ x_{i,j}\in\tilde{x} を計算します。バツ jバツ~他のピクセルとの類似度yi , j y_{i,j}y j、類似性を正規化します。具体的には、各ピクセルxi 、 j x_{i,j}について、バツ j、他のピクセルとの類似度を計算します:
yi , j = xi , j 2 4 ( 1 n − 1 ∑ k ≠ i , jxk 2 + ϵ ) + 0.5 y_{i,j} = \frac{x_{i ,j} ^2}{4(\frac{1}{n-1}\sum_{k\neq i,j}x_k^2+\epsilon)}+0.5y j=4 n 11k= i , jバツk2+) _バツj2+0.5

ここで、n = HW n=HWn=H W は、特徴マップ内のピクセル数を表します。類似度yi , j y_{i,j}y j計算方法はxi , j x_{i,j}となります。バツ j他のピクセルとの二乗差を正規化し、バイアス項を追加0.5 0.50.5、類似度を[ 0 , 1 ][0,1][ 0 ,1 ]の範囲内です。

元の特徴マップxxxと類似度yyyを乗算して重み付き特徴マップを取得します。 z ∈ RB × C × H × W z\in\mathbb{R}^{B\times C\times H\times W}zRB × C × H × W、すなわち:
zi , j = xi , jyi , j z_{i,j} = x_{i,j}y_{i,j}z j=バツ jy j

最後に、重み付けされた特徴マップzzzはシグモイド活性化関数によって正規化され、最終的な出力特徴マップが取得されます。

SimAM では、類似度の計算方法は、SENet などのアテンション メカニズムのグローバル プーリング方法ではなく、特徴マップ内のピクセル間の類似性に基づいています。この類似性に基づく注意メカニズムにより、元の特徴マップの空間情報をより適切に保存できるため、ネットワークの特徴表現能力が向上します。

SimAM の利点は次のとおりです。

ネットワークの特徴表現能力を向上させることができます。SimAM を使用すると、ネットワークが重要な特徴にさらに注目し、重要でない特徴を抑制できるため、特徴表現能力が向上します。

ネットワークの堅牢性を向上できる: SimAM は、ネットワークをノイズや干渉に対してより堅牢にし、それによってネットワークの堅牢性を向上させることができます。

元の特徴マップの空間情報を保存できます。SimAM は、特徴マップ内のピクセル間の類似性に基づいて注意の重みを計算します。これにより、元の特徴マップの空間情報をより適切に保存できます。

計算量が少ない: SimAM は計算量が少なく、いくつかの基本的な数学的演算のみを必要とするため、ニューラル ネットワークに簡単に組み込むことができます。

SimAM のハイパーパラメータe λ e_\lambdaに注意してください。e特定のタスクに応じて調整する必要があり、タスクごとに異なるハイパーパラメータが必要になる場合があります。

SimAM は、画像分類、画像セグメンテーション、物体検出などの複数の視覚タスクに適用されて成功しています。

YOLOV5 の改善 - FocalEIoU を追加し、FocalEIoU を使用して他の IoU バリアントを最適化します。

https://www.bilibili.com/video/bv1pd4y1n7w3/?spm_id_from=333.788&VD_SOURCE=85F7D0D97C49494901F6886C09B832B
、ターゲット テストのターゲット テストの著者のテスト サービスの iOU 計算方法が改善され、新しい IOU バリアント -Focaleiou 、およびFocalEIoU アイデアを使用して、他の IoU バリアントを最適化します。

従来のターゲット検出タスクでは、IoU は検出ボックスとグラウンド トゥルース ボックス間の重複の程度を評価するために使用される指標です。しかし、従来の IoU はカテゴリの不均衡に対処する際にいくつかの問題を抱えており、たとえば、一部のまれなオブジェクトについては、従来の IoU では現実のフレームと背景のフレームを区別することが困難であり、検出の精度に影響を与えます。

この問題を解決するために、新しい IoU バリアントである FocalEIoU が YOLOv5 に導入されました。FocalEIoU は、従来の IoU 計算方法に基づいたカテゴリの重みとサンプルの重みを導入し、カテゴリの不均衡の状況に適切に対処できるようにします。具体的には、FocalEIoU は次のように計算されます。

焦点 EI o U = ∑ i = 1 nwi ⋅ fi ⋅ e γ ( 1 − fi ) ∑ i = 1 nwi FocalEIoU = \frac{\sum_{i=1}^{n}w_i\cdot f_i\cdot e^ {\gamma(1-f_i)}}{\sum_{i=1}^{n}w_i}Foc a lE I o U _=i = 1w私はi = 1w私はf私はec ( 1 f私は)

その中で、んんn は検出フレームと実際のフレーム間の交差の数を表します;wi w_iw私は各カテゴリの重みを示します; fi f_if私は各カテゴリの頻度を表し、サンプル数によって推定できます; γ \gammaγ は、陽性サンプルと陰性サンプルの重みのバランスをとるために使用されるハイパーパラメーターを表します。

FocalEIoU を使用する利点は、クラスの不均衡の場合をより適切に処理できるため、検出の精度が向上することです。さらに、FocalEIoU を使用して、GioU や DIoU などの他の IoU バリアントを最適化することもできます。具体的には、FocalEIoU のアイデアを使用して、カテゴリの重みとサンプルの重みを導入し、これらの IoU の計算を最適化できます。

要約すると、YOLOv5 の FocalEIoU は、カテゴリの不均衡をより適切に処理できる効果的な IoU バリアントであり、オブジェクト検出の精度を向上させます。さらに、FocalEIoU のアイデアは、他の IoU バリアントを最適化するために使用することもできます。

FocalEIoU に加えて、YOLOv5 では次のような他の改善点も導入されています。

CSPDarknet バックボーン ネットワーク: YOLOv5 は、新しいバックボーン ネットワークである CSPDarknet を使用します。これにより、ネットワークの特徴表現能力と計算効率が向上します。

アダプティブ トレーニング: YOLOv5 はアダプティブ トレーニング戦略を使用しており、データ セットのサイズと難易度に応じてトレーニング パラメーターを自動的に調整できるため、トレーニング効果が向上します。

マルチスケール トレーニング: YOLOv5 はマルチスケール トレーニング戦略を使用しており、さまざまなスケールでネットワークをトレーニングできるため、ネットワークの汎化能力と堅牢性が向上します。

事前トレーニング戦略: YOLOv5 は、大規模な画像データセットで事前トレーニングできる新しい事前トレーニング戦略を使用して、ネットワークの特徴表現と一般化機能を向上させます。

これらの改善により、YOLOv5 はターゲット検出タスクで非常に優れた結果を達成できるようになり、たとえば、COCO データセットのパフォーマンスは他のターゲット検出アルゴリズムを上回り、速度も大幅に向上しました。さらに、YOLOv5 はモデル圧縮などの技術を通じて計算効率をさらに向上させることができます。

YOLOv5 はターゲット検出タスクで良好な結果を達成していますが、タスクやデータセットが異なれば、必要なアルゴリズムや技術も異なる可能性があることに注意してください。したがって、実際のアプリケーションでは、特定のタスクやデータセットに応じて選択および調整する必要があります。

YOLOV5 の改善 - DAMO-YOLO で Efficient-RepGFPN を使用して、YOLOV5 の Neck を置き換えます。

https://www.bilibili.com/video/BV1iR4y1a7bx/?spm_id_from=333.788&vd_source=85f7d0d97c49c694901f6886c09b832b
DAMO-YOLO は YOLOv5 をベースにした改良版で、新しい機能ピラミッド ネットワークである Efficient-RepG FPN が導入されており、ネックを置き換えることができます。 YOLOv5. Efficient-RepGFPN は、ネットワークの特徴表現能力と計算効率を向上させることができるため、物体検出の精度と速度がさらに向上します。

Efficient-RepGFPN は、特徴の繰り返しとグローバルな特徴ピラミッド プーリングに基づいた特徴ピラミッド ネットワークです。具体的には、次のモジュールが含まれます。

特徴反復モジュール: 特徴マップは複数回繰り返され、元の特徴マップと結合されて、特徴マップの解像度と豊富さが向上します。

通常の特徴ピラミッド モジュール: 複数の畳み込み層とプーリング層を使用して特徴ピラミッドを構築し、それによって特徴マップの規模と豊富さを向上させます。

グローバル特徴ピラミッド プーリング モジュール: さまざまなプーリング スケールを使用してグローバル特徴を抽出し、それらを従来の特徴ピラミッドと結合して、特徴マップの豊富さと一般化機能を向上させます。

特徴融合モジュール: 特徴アテンション メカニズムと特徴カスケードを使用して、さまざまなスケールの特徴マップを融合し、それにより特徴マップの表現能力と精度を向上させます。

Efficient-RepGFPN を使用して YOLOv5 の Neck を置き換えると、次の利点が得られます。

特徴表現能力の向上: Efficient-RepGFPN は、特徴マップの解像度、スケール、豊富さを向上させることができ、それによって特徴表現能力がさらに向上します。

計算効率の向上: Efficient-RepGFPN は、特徴の繰り返しとグローバル特徴ピラミッド プーリングを通じて計算量とパラメーターの数を削減し、それによって計算効率を向上させます。

検出精度の向上: Efficient-RepGFPN の特徴融合モジュールにより、特徴マップの表現能力と精度がさらに向上し、検出精度がさらに向上します。

Efficient-RepGFPN は上記の利点をもたらしますが、実際のアプリケーションでは、特定のタスクやデータセットに応じて選択および調整する必要があることに注意してください。同時に、Efficient-RepGFPN の実装では、コンピューティング リソースの制限とモデル トレーニングの安定性も考慮する必要があります。

YOLOV5 の改善 - yolov5 の損失関数に EIOU、SIOU、AlphaIOU を追加しました。

https://www.bilibili.com/video/BV1KM411b7Sz/?spm_id_from=333.788&vd_source=85f7d0d97c49c694901f6886c09b832b
YOLOv5 の損失関数に EIOU、SIOU、AlphaIOU を追加すると、ターゲット検出の精度と堅牢性をさらに最適化できます。これらの IoU バリアントは、クラスの不均衡や不規則なオブジェクトの形状などの問題をより適切に処理できるため、オブジェクト検出の精度と堅牢性が向上します。

具体的には、YOLOv5 の損失関数に EIOU、SIOU、AlphaIOU を追加して、検出フレームと実際のフレームの重なりの度合いを計算できます。これらの IoU バリアントは次のように計算されます。

EIOU:
EIOU = IOU − ( arctan ( wt / ht ) − arctan ( wp / hp ) ) 2 π 2 EIOU = IOU - \frac{(arctan(w_t/h_t) - arctan(w_p/h_p))^2}{ \pi^2}オ・=アイ・オー・ユー円周率2( rcタン( w _ _/ h)アークタン( w _ _ _p/ hp) )2

その中で、wt w_twそしてhth_th実際のボックスの幅と高さを示します、wp w_pwpそしてHP h_php検出ボックスの幅と高さを示します。

SIOU:
SIOU = IOU − ( wt − ht ) 2 wp 2 + hp 2 SIOU = IOU - \frac{(w_t-h_t)^2}{w_p^2+h_p^2}シオウ_ _ _=アイ・オー・ユーwp2+hp2( wh)2

その中で、wt w_twそしてhth_th実際のボックスの幅と高さを示します、wp w_pwpそしてHP h_php検出ボックスの幅と高さを示します。

AlphaIOU:
A lpha IOU = 1 − ( 1 − IOU α ) ( 1 − IOU α + ϵ ) AlphaIOU = 1 - \frac{(1 - IOU^\alpha)}{(1 - IOU^\alpha + \epsilon) } }A lpI O U=1( 1アイ・オー・ユーある+) _( 1アイ・オー・ユー

その中で、α \alphaαは調整可能なパラメータϵ \epsilonϵは、分母のゼロを避けるための小さな正の数です。

これらの IoU バリアントを YOLOv5 の損失関数に追加すると、物体検出の精度と堅牢性をさらに最適化できます。これらの IoU バリアントの計算方法とパラメーター設定は、特定のタスクとデータセットに従って選択および調整する必要があることに注意してください。同時に、実際のアプリケーションでは、計算効率やモデルトレーニングの安定性などの問題を考慮する必要があります。

EIOU、SIOU、および AlphaIOU はすべて IoU の改良バージョンであり、検出ボックスとグラウンド トゥルース ボックスの間の重複の程度を計算するために使用されます。それらの違いは主に計算方法と最適化目標に反映されます。

EIOU(ユニオンよりも効率的な交差点):

  • EIOUの計算方法は、従来のIoU(Intersection over
    Union)をベースに、検出フレームと実フレームの回転関係を考慮した角度項目を追加しています。EIOU の最適化の目標は、角度の違いの影響を考慮しながら、予測ボックスとグラウンドトゥルース ボックス間の重複の程度を最大化することです。

SIOU(ユニオン上の滑らかな交差点):

  • SIOU の計算方法は、従来の IoU に基づいて、検出フレームと実際のフレームの形状の違いを緩和するための平滑化アイテムを追加します。SIOU の最適化の目標は、形状の違いの影響を考慮しながら、予測ボックスとグラウンドトゥルース ボックス間の重複の程度を最大化することです。

アルファIOU:

  • AlphaIOU はパラメータ調整に基づく IoU バリアントで、調整可能なパラメータα \alphaを導入します。α。グラウンド トゥルース ボックスと予測ボックスの間の重なりの度合いのバランスを取るために使用されます。α = 1の場合\alpha=1ある=1の場合、AlphaIOU は従来の IoU と同等です。α< 1 \alpha<1ある<1の場合、AlphaIOU は予測フレームと実際のフレームの間の重なりにさらに注意を払います (α > 1 \alpha>1ある>1の場合、AlphaIOU は、予測フレームと実際のフレームの間の重複しない部分により多くの注意を払います。AlphaIOU の最適化の目標は、パラメーター調整の影響を考慮しながら、予測ボックスとグラウンド トゥルース ボックス間の重複の程度を最大化することです。

EIOU、SIOU、および AlphaIOU の計算方法とパラメーター設定は、特定のタスクとデータセットに応じて選択および調整する必要があることに注意してください。実際のアプリケーションでは、計算効率やモデルトレーニングの安定性などの問題も考慮する必要があります。

YOLO 改善シリーズ - YOLOV8 の C2F モジュールを YOLOV5 に追加します。

https://www.bilibili.com/video/BV1rx4y1g7xt/?spm_id_from=333.788&vd_source=85f7d0d97c49c694901f6886c09b832b

YOLOv8 の C2F モジュールを YOLOv5 に追加すると、オブジェクト検出の精度と堅牢性がさらに向上します。C2F モジュールは、スケールの異なる複数の特徴マップを融合して、特徴マップの表現力と検出精度を向上させることができる特徴融合モジュールです。
異なるスケールの複数の特徴マップを融合すると、主に次の理由により、特徴マップの表現能力と検出精度が向上します。

  • マルチスケール機能マップは、より多くのセマンティック情報を取得できます。異なるスケールの特徴マップは、異なるレベルで異なる意味情報を取得し、それらを融合することで、異なるレベルの情報を包括的に利用することができ、それにより、特徴マップの表現能力と検出精度が向上します。
  • マルチスケールの特徴マップにより、さまざまなスケールのオブジェクトに対する検出器の適応性が向上します。異なるスケールの物体は特徴マップ上で異なる表現を持ち、異なるスケールの複数の特徴マップを融合すると、異なるスケールの物体に対する検出器の適応性が向上し、それによって検出精度が向上します。
  • マルチスケールの特徴マップにより、検出器によるオブジェクトのコンテキスト情報の利用率が向上します。異なるスケールの複数の特徴マップを融合すると、より豊富な物体コンテキスト情報が得られるため、物体を理解する検出器の能力と検出精度が向上します。

具体的には、C2F モジュールには次の手順が含まれます。

異なるスケールの特徴マップが畳み込まれてプールされ、異なるスケールの複数の特徴マップが取得されます。

各スケールの特徴マップについては、畳み込み操作とアップサンプリング操作を使用して、均一なサイズに再スケールします。

調整された特徴マップは結合されて、融合された特徴マップが得られます。

いくつかの畳み込み演算および特徴注目メカニズムは、特徴マップの表現能力および検出精度をさらに向上させるために、融合特徴マップ上で実行される。

YOLOv5 に C2F モジュールを追加する具体的な実装手順は次のとおりです。

YOLOv5 のバックボーンでは、さまざまなスケールの複数の特徴マップを取得するために、畳み込み操作とプーリング操作が追加されています。

畳み込み演算とアップサンプリング演算は各スケールの特徴マップに対して個別に実行され、スケールは均一なサイズに調整されます。

調整された特徴マップは結合されて、融合された特徴マップが得られます。

いくつかの畳み込み演算および特徴注目メカニズムは、特徴マップの表現能力および検出精度をさらに向上させるために、融合特徴マップ上で実行される。

特定の実装では、C2F モジュールを YOLOv5 のネック部分に追加して、異なるスケールの特徴マップを融合できます。具体的には、YOLOv5 の FPN (Feature Pyramid Network) モジュールに C2F モジュールを追加して、異なるスケールの特徴マップを融合できます。C2F モジュールの実装では、表現能力と検出をさらに向上させるために、SENet (スクイーズアンド励起ネットワーク)、CBAM (畳み込みブロック アテンション モジュール) などのいくつかの共通の機能アテンション メカニズムを使用できます。特徴マップの精度。

実際のアプリケーションでは、C2F モジュールの計算効率やモデル トレーニングの安定性などの問題も考慮する必要があることに注意してください。計算効率を向上させるために、特徴マップのチャネル数を減らす、畳み込み層の深さを減らすなど、いくつかの最適化手法を採用できます。モデルトレーニングの安定性を向上させるために、ドロップアウト、バッチ正規化などのいくつかの正則化手法を使用して、過学習のリスクを軽減できます。

YOLOV5 改善に向けた IoU

https://www.bilibili.com/video/BV1tG4y1N7Gk/?spm_id_from=333.788&vd_source=85f7d0d97c49c694901f6886c09b832b
Wise IoU は、ターゲット検出タスクにおける検出器の精度を向上できる、改良された IoU 計算方法です。従来のIoU計算方法では予測フレームと実フレームの重なりのみを考慮していましたが、Wise IoUでは予測フレームと実フレームの相対的な位置関係を考慮することで、2つのフレームの重なりの度合いをより正確に評価します。

具体的には、Wise IoU の計算方法は次のステップに分けることができます。

  • 予測ボックスとグランド トゥルース ボックスの間の交差と結合を計算します。従来の IoU 計算と同じです。
  • 実際のフレームの中心点に対する予測フレームの中心点のオフセット、および予測フレームと実際のフレームのアスペクト比の差を計算します。
  • オフセットとアスペクト比の差を 2 つの重み付け係数として使用し、交差と結合の面積に重み付けを行います。
  • Wise IoU は加重領域を使用して計算されます。

YOLOv5 で Wise IoU を追加する具体的な実装は次のとおりです。

  • 検知器の評価機能では、従来のIoU計算方式をWise IoU計算方式に置き換えました。
  • トレーニング プロセス中に、Wise IoU が損失関数の一部として使用され、それによって位置および形状情報の考慮が導入され、検出器の精度が向上します。

Wise IoU 計算方法の特定の実装は、特定のタスクとデータセットに従って選択および調整する必要があることに注意してください。一方で、実用化においては、Wise IoU計算手法の計算効率やモデル学習の安定性にも留意する必要があります。

要約すると、Wise IoU 計算方法を導入することにより、YOLOv5 では検出器の精度と堅牢性をさらに向上させることができます。

YOLOV5 の改善 - Deformable Conv V2 の追加

https://www.bilibili.com/video/BV1rT411Q76q/?spm_id_from=333.788&vd_source=85f7d0d97c49c694901f6886c09b832b

Deformable Conv V2 は、物体検出タスクにおける検出器の精度を向上させる、改良された畳み込み演算です。従来の畳み込み演算は固定されたサンプリング位置のみを考慮しますが、Deformable Conv V2 は、特徴マップ上の空間変換に応じて、特徴マップ上の各位置のサンプリング位置を動的に調整できることを考慮し、形状と形状をキャプチャします。ターゲットをより正確に把握するためのテクスチャ情報。

具体的には、Deformable Conv V2 は次のステップに分割できます。

  • 入力特徴マップに対して空間変換を実行して、各位置のオフセットを取得します。
  • オフセットに応じて各位置のサンプリング位置が調整されることで、対象物の形状や質感情報をより正確に捉えることができます。
  • 畳み込み演算は、サンプリングされた特徴に対して実行されます。
  • 畳み込み結果は重み付けされ、融合されて、最終的な特徴表現が得られます。

Deformable Conv V2 を YOLOv5 に追加する具体的な実装は次のとおりです。

  • YOLOv5 のバックボーンでは、従来の畳み込み演算が Deformable Conv V2 演算に置き換えられます。
  • YOLOv5 のネック部分では、従来の畳み込み演算が Deformable Conv V2 演算に置き換えられます。
  • YOLOv5 のヘッド部分では、従来の畳み込み演算が Deformable Conv V2 演算に置き換えられます。

実際のアプリケーションでは、Deformable Conv V2 演算の計算効率やモデル トレーニングの安定性などの問題も考慮する必要があることに注意してください。計算効率を向上させるために、特徴マップのチャネル数を減らす、畳み込み層の深さを減らすなど、いくつかの最適化手法を採用できます。モデルトレーニングの安定性を向上させるために、ドロップアウト、バッチ正規化などのいくつかの正則化手法を使用して、過学習のリスクを軽減できます。
ここに画像の説明を挿入ここに画像の説明を挿入

YOLOV5 の改善 - CONTEXT_AUGMENTATION_MODULE

https://www.bilibili.com/video/BV17b411d7ef/?spm_id_from=333.788&vd_source=85f7d0d97c49c694901f6886c09b832b

CONTEXT_AUGMENTATION_MODULE は、物体検出タスクにおける検出器の精度を向上させる改良されたモジュールです。その主なアイデアは、ターゲットの周囲のコンテキスト情報を使用してターゲットの特徴表現を強化し、それによってターゲットを認識する検出器の能力を向上させることです。

具体的には、CONTEXT_AUGMENTATION_MODULE は次のステップに分割できます。

オブジェクト検出タスクでは、オブジェクトごとに、まずオブジェクトの境界ボックス情報を使用して周囲のコンテキスト領域が抽出されます。

各コンテキスト領域について、畳み込みニューラル ネットワークなどの高度な特徴抽出手法を使用して、その特徴表現が抽出されます。

ターゲットの特徴表現とコンテキスト領域の特徴表現は、強化された特徴表現を得るために融合される。

ターゲット検出タスクでは、強化された特徴表現がターゲットの認識と位置特定に使用されます。

YOLOv5 で CONTEXT_AUGMENTATION_MODULE を追加する具体的な実装は、YOLOv5 の検出ヘッドの上にコンテキスト モジュールを追加することです。これには、ターゲットの周囲のコンテキスト情報を抽出し、それをターゲットと組み合わせるために使用される、異なるスケールの複数の畳み込み層が含まれています。その機能は次のとおりです。強化された特徴表現を取得するために融合され、最終的に強化された特徴表現はターゲットの認識と位置決めに使用されます。

実験では、CONTEXT_AUGMENTATION_MODULE を追加すると、YOLOv5 の検出パフォーマンスが大幅に向上することが示されており、COCO データセットでは、検出 AP が 1.5 パーセント ポイント以上増加する可能性があり、この方法の有効性が証明されています。
ここに画像の説明を挿入

YOLOV5 の改善 - 補助トレーニングヘッドを追加

https://www.bilibili.com/video/BV1Fo4y1v7bi/?spm_id_from=333.788&vd_source=85f7d0d97c49c694901f6886c09b832b

YOLOv5 では、補助トレーニング ヘッドの追加が改良された手法であり、検出器の精度の向上に役立ちます。補助トレーニング ヘッドとは、メイン検出ヘッドに加えていくつかの追加の検出ヘッドを追加することを指します。これらは、さまざまな特徴レイヤーを同時に予測するために使用され、それによって検出器がターゲットの特徴表現をより適切に学習できるようになります。

具体的には、補助トレーニング ヘッドを追加する具体的な実装は、YOLOv5 のメイン検出ヘッドに加えて、いくつかの追加の検出ヘッドを追加することです。これらの追加の検出ヘッドは、通常、メイン検出ヘッドと同様の構造を持っていますが、機能が異なります。予測する。複数の検出ヘッドを通じてさまざまな特徴レイヤーを同時に予測すると、検出器がターゲットのマルチスケール特徴表現をより適切に学習できるようになり、検出器の精度が向上します。

トレーニング プロセス中に、メイン検出ヘッドと補助トレーニング ヘッドの予測結果が損失計算とバックプロパゲーションに使用されるため、すべての検出ヘッドを効果的にトレーニングできます。テストプロセスでは、複数の検出ヘッドの予測結果を使用して合成し、最終的な検出結果を取得します。

実験では、補助トレーニング ヘッドを追加すると、YOLOv5 の検出パフォーマンスが大幅に向上することが示されており、COCO データセットでは、検出 AP が 1.5 パーセント ポイント以上増加する可能性があり、この方法の有効性が証明されています。

補助トレーニング ヘッドの主な役割は、さまざまなスケールの物体をより適切に検出できるように、検出器の受容野を拡大することです。物体検出タスクでは、通常、異なるスケールの物体は異なる特徴表現を持っているため、異なる特徴レイヤーに補助トレーニング ヘッドを追加することで、検出器がこれらの特徴表現をよりよく学習できるようになり、それによって検出器の精度が向上します。

さらに、補助トレーニング ヘッドを追加すると、勾配消失の問題を軽減することもできます。これは、深いネットワークでは、バックプロパゲーション中の勾配の縮小により、最後の数層のトレーニングが大幅に制限される可能性があるためです。異なるフィーチャ レイヤーに補助トレーニング ヘッドを追加することにより、勾配がネットワーク内をより適切に流れることができるため、勾配消失の問題が軽減され、モデルのトレーニング効果が向上します。

補助トレーニング ヘッドを追加すると、モデルの複雑さと計算が増加し、より多くのトレーニング時間が必要になる可能性があることに注意してください。したがって、実際のアプリケーションでは、特定のタスクやハードウェア リソースに応じてこのテクノロジを使用するかどうかを選択する必要があります。

結論として、補助トレーニング ヘッドの追加は、特にマルチスケールの物体検出タスクにおいて、物体検出器の精度と堅牢性の向上に役立つ効果的な手法です。

YOLOV5 の改善 - あなたが知らないかもしれないいくつかのトリック

https://www.bilibili.com/video/BV1Cy4y1f72u/?spm_id_from=333.788&vd_source=85f7d0d97c49c694901f6886c09b832b

  1. yolov5-p6 または yolov5-p7 モデルの使用方法は?

YOLOv5-p6 と YOLOv5-p7 は YOLOv5 の 2 つの亜種で、YOLOv5 と比較して、より深いネットワーク構造とより高い解像度を備えており、検出器の精度とパフォーマンスを向上させることができます。YOLOv5-p6 または YOLOv5-p7 モデルを使用する手順は次のとおりです。

YOLOv5 のコードと事前トレーニングされた重みをダウンロードします。YOLOv5 の GitHub リポジトリからコードと重みをダウンロードするか、
pip install yolov5 コマンドを使用して YOLOv5 をインストールできます。

データセットを準備します。YOLOv5 は、COCO、VOC、YOLO などのターゲット検出データ セットをサポートしています。データ セットを YOLOv5 がサポートする形式、つまり txt 形式に変換する必要があります。各 txt ファイルは画像に対応し、ファイル内の各行には次の内容が含まれますターゲットに関する情報。ターゲット カテゴリ、ターゲットの中心座標、ターゲットの幅と高さなどが含まれます。

モデルトレーニングを行います。モデルのトレーニングには YOLOv5 の train.py スクリプトを使用します。たとえば、 –cfg パラメーターを設定することで、YOLOv5-p6 モデルまたは YOLOv5-p7 モデルの使用を選択できます。

python train.py --img 640 --batch 16 --epochs 50 --data coco.yaml
–cfg yolov5-p6.yaml このうち、-cfg パラメータは使用するモデル構成ファイルを指定し、yolov5-p6.yaml または yolov5-p7.yaml を選択できます。

モデルのテストを行います。モデルのテストには、YOLOv5 の detect.py スクリプトを使用します。–cfg パラメータを設定することで、YOLOv5-p6 または YOLOv5-p7 モデルの使用を選択することもできます。例: –weights パラメータは、使用するモデル重みファイルを指定します
python detect.py --weights yolov5-p6.pt --img 640 --conf 0.5 --source test.jpg --cfg yolov5-p6.yaml
。 yolov5-p6.pt または yolov5-p7.pt を選択でき、 --source パラメータはテスト イメージのパスを指定し、 --cfg パラメータは使用するモデル構成ファイルを指定します。

YOLOv5-p6 および YOLOv5-p7 は、YOLOv5 よりも多くのコンピューティング リソースと長いトレーニング時間を必要とするため、実際のアプリケーションでは、特定のタスクとハードウェア リソースに応じてどのモデルを使用するかを選択する必要があることに注意してください。

  1. yolov5 で浅い検出レイヤーを増やすにはどうすればよいですか?

YOLOv5 に浅い検出レイヤーを追加すると、小さなオブジェクトに対する検出器の検出パフォーマンスを向上させることができます。YOLOv5 に浅い検出レイヤーを追加する手順は次のとおりです。
YOLOv5 のコードと事前トレーニング重みをダウンロードします。YOLOv5 の GitHub リポジトリからコードと重みをダウンロードするか、pip install yolov5 コマンドを使用して YOLOv5 をインストールできます。
YOLOv5の設定ファイルを変更します。YOLOv5 の設定ファイルは models/yolov5x.yaml にあります (他のバージョンを使用する場合、対応する設定ファイル名が異なる場合があります)。このファイルに浅い検出レイヤーを追加する必要があります。具体的には、元のバックボーン ネットワークの最後の畳み込み層を 2 つの畳み込み層に置き換えることができます。次に例を示します。

最後の畳み込み層

  • 名前: features.14.conv
    from: -6 # -6 レイヤーを入力として使用します (デフォルト = 17)
    モジュール:
    • _CSPRoute
    • nn.Conv2d:
      in_channels: 320
      out_channels: 640
      kernel_size: 1
      ストライド: 1
      パディング: 0
    • nn.BatchNorm2d: # BN ではバイアスは必要ありません
      num_features: 640
      勢い: 0.03
      eps: 1E-4
    • nn.LeakyReLU:
      インプレース: true
    • nn.Conv2d:
      in_channels: 640
      out_channels: 1280
      kernel_size: 3
      ストライド: 1
      パディング: 1
    • nn.BatchNorm2d: # BN ではバイアスは必要ありません
      num_features: 1280
      勢い: 0.03
      eps: 1E-4
    • nn.LeakyReLU:
      インプレース: true

ここでは、元のバックボーン ネットワークの最後の畳み込み層 features.14.conv を 2 つの畳み込み層に置き換えます。最初の畳み込み層の出力チャネル数は 640、2 番目の畳み込み層の出力チャネル数は 1280 です。

なお、浅い検出層を追加するとモデルの計算量や複雑さが増加する可能性があるため、特定のタスクやハードウェアリソースに応じてこの技術を使用するかどうかを選択する必要があります。

モデルのトレーニングとテストを実行します。モデルのトレーニングには YOLOv5 の train.py スクリプトを使用し、モデルのテストには detect.py スクリプトを使用します。トレーニングとテストを行うときは、変更した構成ファイルを指定する必要があります。例:
python train.py --img 640 --batch 16 --epochs 50 --data coco.yaml
–cfg yolov5x-custom.yaml python detect.py --weights yolov5x-custom.pt --img 640 --conf 0.5 --source test.jpg --cfg yolov5x-custom.yaml このうち、 --cfg パラメータは使用するモデル構成ファイルを指定し、変更された yolov5x-カスタムの .yaml ファイルを選択できます。

結論として、YOLOv5 に浅い検出レイヤーを追加すると、検出器のパフォーマンスの向上に役立ちますが、タスクとハードウェア リソースに応じてこの手法を使用するかどうかを検討する必要があります。

  1. yolov5 の深層検出レイヤーを削除するにはどうすればよいですか?

YOLOv5 で深層検出レイヤーを削除すると、モデルの計算量とパラメーターが削減され、モデルの推論速度も向上します。YOLOv5 で深層検出レイヤーを削除する手順は次のとおりです。

YOLOv5 のコードと事前トレーニングされた重みをダウンロードします。YOLOv5 の GitHub リポジトリからコードと重みをダウンロードするか、
pip install yolov5 コマンドを使用して YOLOv5 をインストールできます。

YOLOv5の設定ファイルを変更します。YOLOv5 の構成ファイルは models/yolov5x.yaml にあります (他のバージョンを使用する場合、対応する構成ファイル名が異なる場合があります)。このファイル内の深層検出レイヤーを削除する必要があります。具体的には、次のように、元のヘッド ネットワークの最後の畳み込み層と最後の検出層を削除できます。

探知

  • 名前: 検出
    元: [-2, -1]
    NC: 80
    アンカー: [[10, 13, 16, 30, 33, 23], [30, 61, 62, 45, 59, 119], [116, 90] 、156、198、373、326]]
    ストライド: [8、16、32]

    回帰層と分類層

    回帰: nn.Conv2d(640, 18, kernel_size=1, stride=1, padding=0)
    分類: nn.Conv2d(640, 90, kernel_size=1, stride=1, padding=0)

最後の畳み込み層 features.14.conv の出力チャネル数を 640 に変更し、最後の検出層 detect の入力チャネル数を 640 に変更し、回帰層と分類層の入力チャネル数を 640 に変更します。

ディープ検出レイヤーを削除すると、特に小さなターゲット検出の場合、モデルの検出パフォーマンスが低下する可能性があるため、特定のタスクとハードウェア リソースに応じてこのテクノロジーを使用するかどうかを選択する必要があることに注意してください。

モデルのトレーニングとテストを実行します。モデルのトレーニングには YOLOv5 の train.py スクリプトを使用し、モデルのテストには detect.py スクリプトを使用します。トレーニングとテストを行うときは、変更した構成ファイルを指定する必要があります。例:
python train.py --img 640 --batch 16 --epochs 50 --data coco.yaml
–cfg yolov5x-custom.yaml python detect.py --weights yolov5x-custom.pt --img 640 --conf 0.5 --source test.jpg --cfg yolov5x-custom.yaml このうち、 --cfg パラメータは使用するモデル構成ファイルを指定し、変更された yolov5x-カスタムの .yaml ファイルを選択できます。

つまり、YOLOv5 でディープ検出レイヤーを削除すると、モデルの計算量とパラメーターを削減できますが、タスクとハードウェア リソースに応じてこのテクノロジーを使用するかどうかを検討する必要があります。

ここに画像の説明を挿入

  1. yolov5 のアクティベーション機能をワンクリックで置き換えるにはどうすればよいですか?

YOLOv5 コードの関連部分を変更することで、YOLOv5 のアクティベーション機能をワンクリックで置き換えることができます。YOLOv5 のアクティベーション機能をワンクリックで置き換える手順は次のとおりです。

YOLOv5 のコードと事前トレーニングされた重みをダウンロードします。YOLOv5 の GitHub リポジトリからコードと重みをダウンロードするか、pip install yolov5 コマンドを使用して YOLOv5 をインストールできます。

YOLOv5 の models/yolo.py ファイルを開きます。このファイルは YOLOv5 モデルの構造を定義しており、このファイル内のアクティベーション関数を置き換える必要があります。具体的には、元のアクティベーション関数 (デフォルトでは SiLU) を、ReLU などの他のアクティベーション関数に置き換えることができます。

yolo.py ファイル内の SiLU を ReLU に置き換えます

act = nn.ReLU(inplace=True) は、
新しい活性化関数を YOLOv5 モデルに適用します。YOLOv5 モデルのコンストラクターにパラメーターを追加して、アクティベーション関数を指定できます。例えば:

class YOLOv5(nn.Module):
    def __init__(self, cfg='yolov5s.yaml', ch=3, nc=None):
        super().__init__()

        self.model, self.save = parse_model(deepcopy(load_yaml(cfg)), ch=[ch])  # model, savelist
        self.nc = self.model[-1].nc = nc  # number of classes

        # 将激活函数作为参数传递到构造函数中,用于替换原来的SiLU激活函数
        self.act = nn.ReLU(inplace=True)
        self.model = nn.Sequential(*self.model[0])

        # Initialize
        self.initialize()

モデルのトレーニングとテストを実行します。モデルのトレーニングには YOLOv5 の train.py スクリプトを使用し、モデルのテストには detect.py スクリプトを使用します。トレーニングとテストを行うときは、次のように、変更されたモデル コードを指定する必要があります。

python train.py --img 640 --batch 16 --epochs 50 --data coco.yaml --cfg yolov5s-custom.py
python detect.py --weights yolov5s-custom.pt --img 640 --conf 0.5 --source test.jpg --cfg yolov5s-custom.py

このうち、-cfg パラメーターは使用するモデル コード ファイルを指定し、変更された yolov5s-custom.py ファイルを選択できます。

つまり、YOLOv5 のアクティベーション関数をワンクリックで置き換えるには、コードの変更とモデルの再トレーニングが必要となるため、一定のプログラミングとディープラーニングの知識が必要になります。

  1. yolov5 で fpn と bifpn を使用するにはどうすればよいですか?

YOLOv5 で FPN または BiFPN を使用するには、次の手順が必要です。

YOLOv5 のコードと事前トレーニングされた重みをダウンロードします。YOLOv5 の GitHub リポジトリからコードと重みをダウンロードするか、pip install yolov5 コマンドを使用して YOLOv5 をインストールできます。

YOLOv5 の models/yolo.py ファイルを変更します。このファイルは YOLOv5 モデルの構造を定義しており、FPN または BiFPN 構造をこのファイルに追加する必要があります。具体的には、元の畳み込み層を FPN または BiFPN の畳み込み層に置き換えることができます。たとえば、BiFPN 構造を YOLOv5s モデルに追加するには、yolo.py ファイルを次のように変更できます。

# 在 yolo.py 文件中添加以下代码,将原来的卷积层替换为BiFPN中的卷积层
from models.common import Conv, BottleneckCSP, SPP, DWConv

class BiFPN(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(BiFPN, self).__init__()

        self.conv6_up = Conv(in_channels[0], out_channels, 1, 1)
        self.conv5_up = Conv(in_channels[1], out_channels, 1, 1)
        self.conv4_up = Conv(in_channels[2], out_channels, 1, 1)
        self.conv3_up = Conv(in_channels[3], out_channels, 1, 1)

        self.conv3_down = Conv(in_channels[3], out_channels, 1, 1)
        self.conv4_down = Conv(in_channels[2], out_channels, 1, 1)
        self.conv5_down = Conv(in_channels[1], out_channels, 1, 1)
        self.conv6_down = Conv(in_channels[0], out_channels, 1, 1)

        self.conv7 = Conv(out_channels, out_channels, 3, 2)
        self.conv8 = Conv(out_channels, out_channels, 3, 2)
        self.conv9 = Conv(out_channels, out_channels, 3, 2)
        self.conv10 = Conv(out_channels, out_channels, 3, 2)

        self.act = nn.SiLU(inplace=True)

    def forward(self, inputs):
        c3, c4, c5, c6 = inputs

        # Top-down
        p6 = self.conv6_up(c6)
        p5 = self.conv5_up(c5) + F.interpolate(p6, scale_factor=2, mode='nearest')
        p4 = self.conv4_up(c4) + F.interpolate(p5, scale_factor=2, mode='nearest')
        p3 = self.conv3_up(c3) + F.interpolate(p4, scale_factor=2, mode='nearest')

        # Bottom-up
        p4 = self.conv4_down(p4) + self.conv4_up(F.interpolate(p3, scale_factor=0.5, mode='nearest'))
        p5 = self.conv5_down(p5) + self.conv5_up(F.interpolate(p4, scale_factor=0.5, mode='nearest'))
        p6 = self.conv6_down(p6) + self.conv6_up(F.interpolate(p5, scale_factor=0.5, mode='nearest'))
        p7 = self.conv7(p6)
        p8 = self.conv8(p7)
        p9 = self.conv9(p8)
        p10 = self.conv10(p9)

        # Output
        return [p3, p4, p5, p6, p7, p8, p9, p10]

class YOLOv5(nn.Module):
    def __init__(self, cfg='yolov5s.yaml', ch=3, nc=None, fpn=False, bifpn=True):
        super().__init__()

        self.model, self.save = parse_model(deepcopy(load_yaml(cfg)), ch=[ch])  # model, savelist
        self.nc = self.model[-1].nc = nc  # number of classes

        # Add FPN or BiFPN structure
        if fpn:
            self.model[-1].conv = nn.Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
            self.model[-1].m[-1].conv = nn.Conv2d(512, 1024, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
            self.model[-1].m[-1].m[-1].conv = nn.Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), padding=(0, 0), bias=False)
self.model[-1].m[-1].m[-1].act = nn.SiLU(inplace=True)
self.model[-1].m[-1].m[-1].bn = nn.BatchNorm2d(512, eps=0.001, momentum=0.03)

    if bifpn:
        # Replace the last convolution layer with BiFPN
        self.model[-1].conv = BiFPN([256, 512, 1024, 2048], 256)
        self.model[-1].m[-1].conv = nn.Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), padding=(0, 0), bias=False)
        self.model[-1].m[-1].act = nn.SiLU(inplace=True)
        self.model[-1].m[-1].bn = nn.BatchNorm2d(1024, eps=0.001, momentum=0.03)

    self.model = nn.Sequential(*self.model[0])
    
    # Initialize
    self.initialize()

上記のコードでは、BiFPN 構造の実装を含む BiFPN クラスを定義し、YOLOv5s モデルの最後の畳み込み層を BiFPN に置き換えます。FPN と BiFPN のコード実装は若干異なる場合があり、特定の状況に応じて変更する必要があることに注意してください。

  1. モデルのトレーニングとテストを実行します。モデルのトレーニングには YOLOv5 の train.py スクリプトを使用し、モデルのテストには detect.py スクリプトを使用します。トレーニングとテストを行うときは、使用するモデル コード ファイルを指定する必要があります。たとえば、次のようになります。
python train.py --img 640 --batch 16 --epochs 50 --data coco.yaml --cfg yolov5s-custom.py --bifpn
python detect.py --weights yolov5s-custom.pt --img 640 --conf 0.5 --source test.jpg --cfg yolov5s-custom.py --bifpn

このうち、-cfg パラメーターは使用するモデル コード ファイルを指定し、変更された yolov5s-custom.py ファイルを選択できます。–bifpn パラメータは、BiFPN 構造の使用を示すために使用されます。FPN 構造を使用する場合は、-fpn パラメータを使用できます。
モデルの最適化を実行します。モデルのパフォーマンスをさらに最適化するために、さまざまなハイパーパラメーターとトレーニング戦略を試すことができます。たとえば、学習率の調整、データ拡張の追加、さまざまな損失関数の使用などを行うことができます。さらに、さまざまな事前トレーニングされた重みを使用したり、事前トレーニングされたモデルを微調整したりすることもできます。

モデルの評価を行います。YOLOv5 の test.py スクリプトをモデル評価に使用すると、テスト データ セット上のモデルの精度、再現率、その他の指標を計算できます。例えば:

python test.py --weights yolov5s-custom.pt --data coco.yaml --cfg yolov5s-custom.py --bifpn

このうち、-weights パラメータは使用するモデル重み付けファイルを指定し、-data パラメータは使用するデータセット構成ファイルを指定し、-cfg パラメータは使用するモデル コード ファイルを指定し、-bifpn パラメータは BiFPN 構造の使用を示します。

上記は、YOLOv5 で FPN または BiFPN を使用する一般的な手順です。具体的な実装プロセスは、データ セットやハイパーパラメーターなどの要因により異なる場合があります。状況に応じて調整や修正が必要となります。

  1. kmean を使用して独自のデータセットに対応するアンカーボックスをクラスター化するにはどうすればよいですか?

ターゲット検出において、アンカー ボックスは画像内の関心のある領域を選択する方法です。アンカー ボックスの数とサイズは検出効果に大きな影響を与えるため、独自のデータセットに応じてアンカー ボックスを選択する必要があります。その中で、一般的な方法は、K-Means クラスタリング アルゴリズムを使用してデータ セットを分析し、データ セットに最適なアンカー ボックスを決定することです。

K-Means アルゴリズムを使用してアンカー ボックスを生成する手順は次のとおりです。

データセットを準備します。まず、画像や注釈ファイルなどを含む、ターゲット検出用のトレーニング データ セットを準備する必要があります。

ラベルボックスの幅と高さの比率を抽出します。注釈ファイルからすべての注釈ボックスのアスペクト比を抽出し、リストに保存します。Python の PIL ライブラリまたは OpenCV ライブラリを使用して画像や注釈ファイルを読み取り、データ処理に Numpy ライブラリを使用できます。

K-Means アルゴリズムを実行します。scikit-learn ライブラリの KMeans クラスを使用して K-Means アルゴリズムを実行します。具体的には、クラスタ数 k と反復回数 n_init を指定する必要があり、ラベル付きボックスの幅と高さの比率がクラスタリングの入力データとして使用されます。

from sklearn.cluster import KMeans

# 读取所有标注框的宽高比例
ratios = []
for annotation in annotations:
    bbox = annotation['bbox']
    ratio = bbox[2] / bbox[3]
    ratios.append(ratio)

# 运行K-Means算法
kmeans = KMeans(n_clusters=k, n_init=n_init).fit(np.array(ratios).reshape(-1, 1))
获取聚类中心。K-Means算法将标注框的宽高比例聚类成k个簇,每个簇的中心即为一个Anchor Box的宽高比例。可以使用KMeans类的cluster_centers_属性获取所有聚类中心。然后,将聚类中心按照宽高比例从小到大排序,得到最终的Anchor Box。
# 获取聚类中心
centers = kmeans.cluster_centers_.reshape(-1)

# 按照宽高比例从小到大排序
order = np.argsort(centers)

# 获取最终的Anchor Box
anchors = []
for i in order:
    anchors.append([0, 0, int(round(centers[i] * base_size)), base_size])

anchors = np.array(anchors)

このうち、base_size はベンチマーク サイズであり、独自のデータセットに応じて調整できます。

アンカー ボックスをファイルに保存します。最後に、生成されたアンカー ボックスをトレーニング中に使用できるようにファイルに保存します。アンカー ボックスは、Numpy 配列、JSON ファイル、またはその他の形式として保存できます。

# 保存Anchor Box到文件
np.savetxt('anchors.txt', anchors, fmt='%d')

K-Means アルゴリズムを使用してアンカー ボックスを生成する場合、適切なクラスター数 k と反復数 n_init を選択する必要があることに注意してください。一般的に、k は 5 ~ 10、n_init は 10 ~ 20 に設定できます。同時に、DBSCAN などの他のクラスタリング アルゴリズムも使用できます。

生成されたアンカー ボックスをターゲット検出トレーニングに使用する場合、アンカー ボックスをモデルのハイパーパラメーターとして入力する必要があります。以下は、生成されたアンカー ボックスを使用したターゲット検出トレーニングの一般的な手順です。

データセットを準備します。まず、画像や注釈ファイルなどを含む、ターゲット検出用のトレーニング データ セットを準備する必要があります。

アンカーボックスをロードします。以前に生成したアンカー ボックス ファイルを使用して、トレーニング中に使用できるようにアンカー ボックスをメモリにロードします。

# 加载Anchor Box
anchors = np.loadtxt('anchors.txt')

モデルを構成します。ターゲット検出フレームワーク (YOLOv5、Faster R-CNN など) を使用してモデルを構成し、生成されたアンカー ボックスをハイパーパラメーターとして入力します。具体的には、アンカー ボックスの数とサイズをモデルのハイパーパラメーターとして入力する必要があります。YOLOv5 では、モデル構成ファイル (yolov5s.yaml など) を変更し、生成されたアンカー ボックスにアンカー パラメーターを設定できます。

# 修改模型配置文件
anchors_str = ','.join([str(int(x)) for x in anchors.reshape(-1)])
with open('yolov5s.yaml', 'r') as f:
    content = f.read()
content = content.replace('anchor: [0,0,0,0,0,0,0,0,0,0]', f'anchor: [{
      
      anchors_str}]')
with open('yolov5s-custom.yaml', 'w') as f:
    f.write(content)

モデルをトレーニングします。構成されたモデルとデータセットをトレーニングに使用します。トレーニング中に、アンカー ボックスをハイパーパラメータとして入力する必要があり、学習率やバッチ サイズなどの他のハイパーパラメータを必要に応じて調整する必要があります。

# 训练模型
python train.py --weights yolov5s.pt --cfg yolov5s-custom.yaml --data coco.yaml --batch-size 16 --epochs 50 --hyp hyp.scratch.yaml

モデルを評価します。テスト データ セットを使用してトレーニング済みモデルを評価し、精度や再現率などのモデルのパフォーマンス指標を計算します。

# 评估模型
python test.py --weights yolov5s-custom.pt --data coco.yaml --cfg yolov5s-custom.yaml

生成されたアンカー ボックスをトレーニングに使用する場合、独自のデータ セットに適応させるためにいくつかの調整が必要になる場合があることに注意してください。たとえば、アンカー ボックスの数とサイズは、データセットのサイズと複雑さに応じて調整できます。さらに、他のターゲット検出フレームワークやアルゴリズムを使用して、さまざまなニーズを満たすこともできます。

YOLOV5 の改善 - SAConv を追加。

ここに画像の説明を挿入
ここに画像の説明を挿入

SAConv は、入力特徴マップの空間構造に応じてコンボリューション カーネルのサイズと形状を自動的に調整できる適応型コンボリューションであり、それによってより優れた特徴抽出を実現します。
YOLOv5 では、SAConv レイヤーを追加することでモデルのパフォーマンスを向上させることができます。

以下は、YOLOv5 に SAConv レイヤーを追加する一般的な手順です。

SAConv 層を定義します。まず、SAConv 層の構造とパラメータを定義する必要があります。YOLOv5 では、SAConv レイヤーは PyTorch を使用して実装できます。具体的には、SAConv 層は、適応畳み込み層、バッチ正規化層、活性化関数層を含む PyTorch モジュールとして定義できます。

import torch
import torch.nn as nn
import torch.nn.functional as F

class SAConv(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=1):
        super(SAConv, self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)
        self.bn = nn.BatchNorm2d(out_channels)
        self.act = nn.ReLU(inplace=True)
        self.sa = nn.Conv2d(out_channels, out_channels, kernel_size=1, stride=1, padding=0)

    def forward(self, x):
        x = self.conv(x)
        x = self.bn(x)
        x = self.act(x)
        sa = F.avg_pool2d(x, x.size()[2:])
        sa = self.sa(sa)
        x = x * sa
        return x

このうち、in_channels と out_channels は入力および出力特徴マップのチャネル数を表し、kernel_size はコンボリューション カーネルのサイズを表し、stride はストライドを表し、padding はフィル サイズを表します。

YOLOv5 の畳み込み層を置き換えます。YOLOv5 では、replace_module 関数を使用してモデル内の畳み込み層を置き換えることができます。具体的には、モデルのすべての層を走査し、畳み込み層を見つけて、それらを SAConv 層に置き換えることが可能です。

from models.yolo import Model

model = Model()
for name, module in model.named_modules():
    if isinstance(module, nn.Conv2d):
        sa_conv = SAConv(module.in_channels, module.out_channels, kernel_size=module.kernel_size, stride=module.stride, padding=module.padding)
        setattr(model, name, sa_conv)

モデルをトレーニングします。変更された YOLOv5 モデルをオブジェクト検出トレーニングに使用し、必要に応じて学習率やバッチ サイズなどの他のハイパーパラメーターを調整します。

トレーニングモデル

python train.py --weights yolov5s.pt --cfg yolov5s-custom.yaml --data coco.yaml --batch-size 16 --epochs 50 --hyp hyp.scratch.yaml

SAConv レイヤーを追加すると、モデルの計算量とパラメーターが増加し、トレーニング時間とメモリ消費量が増加する可能性があることに注意してください。したがって、SAConv レイヤーを使用してモデルのパフォーマンスと計算効率のバランスを取る場合は、特定のハイパーパラメーターの調整が必要です。

YOLOV5 の改善 - Soft-NMS (複数の IoU バリアントをサポート)

https://www.bilibili.com/video/BV1cM41147Ry/?spm_id_from=333.788&vd_source=85f7d0d97c49c694901f6886c09b832b
集中的なターゲット検出時にデータセットが追加される

Soft-NMS は、ターゲット検出タスクにおける YOLOv5 モデルのパフォーマンスを向上できる、改良された非最大抑制アルゴリズムです。従来の NMS アルゴリズムとは異なり、Soft-NMS は重なりが大きい検出フレームを直接削除しませんが、重なり合うフレームの信頼性を下げることでより多くの検出フレームを保持し、それにより検出の再現率と精度が向上します。

Soft-NMS を YOLOv5 に追加する一般的な手順は次のとおりです。

Soft-NMS 機能を定義します。まず、Soft-NMS 機能の計算方法を定義する必要があります。YOLOv5 では、Soft-NMS 機能を Python を使用して実装できます。具体的には、Soft-NMS は、入力検出ボックス、信頼度、およびしきい値を含む Python 関数として定義でき、低減された信頼度およびフィルター処理された検出ボックスを出力します。

def soft_nms(dets, confs, thresh=0.3, sigma=0.5):
    """
    Soft-NMS算法
    :param dets: 检测框列表,格式为(x1, y1, x2, y2)
    :param confs: 置信度列表
    :param thresh: 重叠阈值
    :param sigma: 置信度下降因子
    :return: 筛选后的检测框和置信度
    """
    ...
    return keep, new_confs

YOLOv5 で Soft-NMS 関数を呼び出します。YOLOv5 の検出モジュールでは、Soft-NMS 関数を呼び出すことで従来の NMS アルゴリズムを置き換えることができます。具体的には、検出モジュールにおいて、NMS を Soft-NMS に置き換えることができ、Soft-NMS の出力を最終的な検出結果として使用できます。

# 使用Soft-NMS替代传统的NMS
keep, confs = soft_nms(dets, confs, nms_thresh, nms_sigma)
# 将Soft-NMS的输出作为最终的检测结果
output.extend([Detection(xyxy, confs[i], cls) for i, xyxy in enumerate(dets[keep])])

...
Soft-NMS のパラメータを調整します。Soft-NMS を使用する場合、重複しきい値や信頼性低下係数などのパラメーターを、特定のタスクやデータセットに応じて調整する必要があります。一般に、これらのパラメーターは、検証セットのパフォーマンスに応じて調整して、検出モデルのパフォーマンスを最適化できます。
Soft-NMS は、YOLOv5 ターゲット検出タスクにおける検出の再現率と精度を向上させる効果的な非最大抑制アルゴリズムです。従来のNMSアルゴリズムをSoft-NMSに置き換え、Soft-NMSのパラメータを調整することで、検出性能をさらに向上させることができます。

YOLOV5 の改善 - CoordConv を追加しました。

CoordConv は、畳み込みニューラル ネットワークに座標情報を追加する方法であり、物体検出タスクにおける YOLOv5 モデルのパフォーマンスを向上させることができます。CoordConv は、入力特徴マップの各ピクセルの位置情報を追加のチャネル情報としてネットワークに追加します。これにより、ネットワークがオブジェクトの位置とスケールをよりよく理解できるようになります。

各ピクセルの位置情報を追加チャネル情報としてネットワークに追加する方法

各ピクセルの位置情報を追加のチャネル情報としてネットワークに追加することは、AddCoords レイヤーを使用して実装できます。具体的には、AddCoords レイヤーは、まず各ピクセルの位置情報を計算して入力特徴マップに追加し、位置情報を追加した後の特徴マップを返します。

単純な AddCoords レイヤーの実装例を次に示します。

torch.nn を nn としてインポート

class AddCoords(nn.Module):
def init (self):
super(AddCoords, self)。init ()
def forward(self, x):
バッチサイズ, _, 高さ, 幅 = x.size()
xx_channel = torch.arange(width).repeat(batch_size, 1)
yy_channel = torch.arange(height).repeat(バッチサイズ, 1).t()
xx_channel = xx_channel.float() / (幅 - 1)
yy_channel = yy_channel.float() / (高さ - 1)
xx_channel = xx_channel * 2 - 1
yy_channel = yy_channel * 2 - 1
xx_channel = xx_channel.repeat(1, height).view(バッチサイズ, 高さ, 幅)
yy_channel = yy_channel.repeat(1, width).view(バッチサイズ, 高さ, 幅)
ret = torch.cat([x, xx_channel.to(x.device), yy_channel.to(x.device)], dim=1)
return ret
AddCoords 層で、最初に入力特徴マップのサイズを取得し、次に torch .arange を使用します。対応する x および y 座標行列を生成し、それを [-1,1] の範囲に正規化し、最後に x および y 座標行列を特徴マップと同じサイズに繰り返し、それを特徴マップ を入力し、位置情報を付加した後の特徴マップを取得します。

実際の使用では、畳み込みニューラル ネットワークの入力層の後に AddCoords 層を追加できるため、各ピクセルの位置情報を追加のチャネル情報としてネットワークに追加して、ネットワークがオブジェクトの位置と場所をよりよく理解できるようになります。 . スケールやその他の情報。

CoordConv を YOLOv5 に追加する一般的な手順は次のとおりです。

CoordConv レイヤーを定義します。まず、CoordConv レイヤーの計算方法を定義する必要があります。YOLOv5 では、Python を使用して CoordConv レイヤーを実装できます。具体的には、CoordConv 層は、nn.Module を継承し、forward 関数を定義する Python クラスとして定義できます。

import torch.nn as nn
import torch.nn.functional as F

class CoordConv(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0):
        super(CoordConv, self).__init__()
        self.addcoords = AddCoords()
        in_channels += 2
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)

    def forward(self, x):
        x = self.addcoords(x)
        x = self.conv(x)
        return x

class AddCoords(nn.Module):
    def __init__(self):
        super(AddCoords, self).__init__()

    def forward(self, x):
        batch_size, _, height, width = x.size()
        xx_channel = torch.arange(width).repeat(batch_size, 1)
        yy_channel = torch.arange(height).repeat(batch_size, 1).t()
        xx_channel = xx_channel.float() / (width - 1)
        yy_channel = yy_channel.float() / (height - 1)
        xx_channel = xx_channel * 2 - 1
        yy_channel = yy_channel * 2 - 1
        xx_channel = xx_channel.repeat(1, height).view(batch_size, height, width)
        yy_channel = yy_channel.repeat(1, width).view(batch_size, height, width)
        ret = torch.cat([x, xx_channel.to(x.device), yy_channel.to(x.device)], dim=1)
        return ret

このうち、AddCoords クラスは、各ピクセルの位置情報を計算し、入力特徴マップに追加して、追加された特徴マップを返すために使用されます。CoordConv クラスは nn.Module から継承し、位置情報を追加した後に特徴マップ上で畳み込み演算を実行するために使用されます。

YOLOv5 で CoordConv レイヤーを呼び出します。YOLOv5 のネットワーク構造では、従来の畳み込み層を CoordConv 層に置き換えることができ、それにより特徴マップに座標情報が追加されます。具体的には、ネットワーク構造において、Conv2d を CoordConv に置き換えて、対応する位置に追加することができます。

# 使用CoordConv替代Conv2d
x = CoordConv(in_channels, out_channels, kernel_size, stride, padding)(x)

...
CoordConv のパラメータを調整しています。CoordConv を使用する場合、コンボリューション カーネル サイズ、ステップ サイズ、パディングなどのパラメーターを特定のタスクやデータ セットに応じて調整する必要があります。一般に、これらのパラメーターは、検証セットのパフォーマンスに応じて調整して、検出モデルのパフォーマンスを最適化できます。
CoordConv は、畳み込みニューラル ネットワークに座標情報を追加する効果的な方法であり、物体検出タスクにおける YOLOv5 モデルのパフォーマンスを向上させることができます。従来の畳み込み層を CoordConv 層に置き換え、CoordConv のパラメータを調整することで、検出性能をさらに向上させることができます。

YOLOV5 の改善 - 小さなターゲット向けの NWD。

NWD は Normalized Weighted Distance の略で、ターゲット検出における距離測定の損失関数です。ターゲット検出タスクでは、多くの場合、モデルの検出効果を測定するために、予測フレームとターゲット フレーム間の距離を計算する必要があります。NWD 損失関数は、予測フレームとターゲット フレーム間の距離を重み付けして合計し、ターゲット検出の損失関数としてスカラー値を取得します。

具体的には、NWD 損失関数が 2 つのボックス間の距離を計算する場合、通常はユークリッド距離またはその他の距離測定方法が使用されます。重み付け係数は、ターゲット フレームのサイズや位置などの要因に応じて調整され、モデルの小さなターゲットの検出能力が向上します。

YOLOv5 などのターゲット検出モデルでは、NWD 損失関数を使用すると、モデルの検出効果、特に小さなターゲットの検出能力が向上し、より良い結果が得られます。
小さなターゲット用の NWD (Normalized Weighted Distance) は、YOLOv5 モデルで使用できる改良されたターゲット検出アルゴリズムです。従来のターゲット検出アルゴリズムと比較して、小さなターゲット用の NWD アルゴリズムは小さなターゲットの検出に適切に対処し、検出の精度を向上させることができます。

以下は、YOLOv5 の小さなターゲットに対して NWD アルゴリズムを使用するための一般的な手順です。

小さなオブジェクトの NWD 損失関数を定義します。小さな物体の NWD 損失関数は、物体検出における距離メトリックに基づく損失関数です。まず、各予測ボックスとターゲット ボックスの間の距離を計算する必要があります。次に、距離の加重和が計算され、損失関数の値として使用されます。具体的には、距離計算にはユークリッド距離などの距離測定手法を用いることができ、ターゲットボックスの大きさや位置などに応じて重み付け係数を調整することができる。以下は、小さなターゲットに対する NWD 損失関数の簡単な実装例です。

def nwd_loss(pred, targets, anchors):
    # 计算距离
    distance = torch.sqrt((pred[..., 0] - targets[..., 0]) ** 2 + (pred[..., 1] - targets[..., 1]) ** 2)
    # 计算加权系数
    weight = 2 - targets[..., 2] * targets[..., 3]
    # 计算损失函数
    loss = torch.sum(weight * distance)
    return loss
其中,pred是模型的预测结果,targets是真实标签,anchors是先验框信息。

在YOLOv5中调用针对小目标的NWD损失函数。在YOLOv5的网络训练过程中,可以使用针对小目标的NWD损失函数作为模型的优化目标。具体来说,在训练过程中,可以将nwd_loss函数作为损失函数,并使用反向传播算法来更新模型的参数。
# 计算损失函数
loss = nwd_loss(pred, targets, anchors)
# 反向传播
loss.backward()
# 更新参数
optimizer.step()

モデルのハイパーパラメータを調整します。小さなオブジェクトに NWD アルゴリズムを使用する場合、さまざまなオブジェクト検出タスクに適応するようにモデルのハイパーパラメーターを調整する必要があります。具体的には、前のフレームのサイズや数、重み付け係数の重みなどのハイパーパラメータを調整して、検出の精度と再現率を向上させることができます。

要約すると、小さなターゲットの NWD アルゴリズムは効果的な改善方法であり、YOLOv5 などのターゲット検出モデルで使用して、小さなターゲットの検出効果を向上させることができます。
小さなターゲットに対する NWD アルゴリズムの使用に加えて、YOLOv5 で使用できる小さなターゲットに対するその他の改良された方法をいくつか紹介します。

  1. トレーニング中はより小さい入力サイズを使用してください。より小さい入力サイズを使用すると、モデルの小さなオブジェクトの検出能力が向上します。ただし、この方法ではモデルが大きな物体を検出する能力も低下するため、精度と速度のトレードオフが必要になります。
  2. モデルの構造を変更します。YOLOv5 のネットワーク構造を変更して畳み込み層またはプーリング層を追加し、モデルの受容野と特徴抽出機能を向上させることができます。この方法では、モデルの多くのデバッグとトレーニングが必要となり、モデルの複雑さと計算も増加します。
  3. マルチスケール検出方法を使用します。マルチスケール検出方法では、さまざまなスケールでオブジェクトを検出できるため、小さなオブジェクトを検出するモデルの能力を効果的に向上させることができます。具体的には、入力画像の異なるスケールで検出を実行し、検出結果を融合して最終的な検出結果を得ることができます。
  4. より多くのデータ拡張方法を使用します。データ拡張手法により、データの多様性が高まり、モデルの堅牢性と一般化能力が向上します。具体的には、回転、スケーリング、平行移動、トリミングなどのデータ拡張手法を使用して、より多くのトレーニング サンプルを生成し、小さなターゲットを検出するモデルの能力を向上させることができます。
  5. より洗練された以前のボックス情報を使用します。事前フレーム情報はモデルの検出効果に重要な影響を及ぼし、ターゲットのサイズや位置などの要因に応じてより洗練された事前フレームを設計して、モデルの検出精度を向上させることができます。

要約すると、小さなオブジェクトを改善するには多くの方法があり、特定のタスクの要件に応じて選択して組み合わせることができます。

YOLOV5 の改良 - 最新の変形可能なコンボリューション V3

https://www.bilibili.com/video/BV1LY411z7iE/?spm_id_from=333.788&vd_source=85f7d0d97c49c694901f6886c09b832b
Deformable Convolution (変形可能な畳み込み) は、オブジェクト形状の多様性のための畳み込み演算であり、畳み込み層の情報に変形を導入し、オブジェクトの適応性を向上させることができます。モデルを複雑なシーンや形状に合わせて変更します。最新の変形可能コンボリューション V3 は、変形可能コンボリューション V1 および V2 をベースに改良されており、計算効率と検出性能が向上しており、YOLOv5 などのターゲット検出モデルの改善に使用できます。

最新の変形可能コンボリューション V3 の主な改善点は次のとおりです。

  1. 変形サンプリング方法をさらに追加しました。Deformable Convolution V3 では、三角形と四面体に基づく変形サンプリング手法が導入されており、さまざまなオブジェクトの形状や分布に適切に適応できます。
  2. マルチブランチ構造が導入されています。Deformable Convolution V3 は、コンボリューション層にマルチブランチ構造を導入し、複数の変形サンプリングを同時に実行できるため、モデルの受容野と特徴抽出能力が向上します。
  3. 変形サンプリングアルゴリズムを最適化しました。Deformable Convolution V3 は、変形サンプリング アルゴリズムを最適化し、より効率的な計算方法とより正確なサンプリング方法を採用し、モデルの計算効率と検出精度を向上させることができます。
  4. グローバルコンテキスト情報を追加しました。Deformable Convolution V3 では、畳み込み層にグローバル コンテキスト情報が導入されており、グローバル情報をより適切に利用してモデルの検出能力を向上させることができます。

最新の変形可能コンボリューション V3 を導入することで、YOLOv5 などのターゲット検出モデルの検出効果と計算効率を効果的に向上させることができ、特に複雑なシーンや形状変化を扱う場合に、より優れたパフォーマンスを得ることができます。

YOLOV5 の改善 - DSConv.

ここに画像の説明を挿入ここに画像の説明を挿入

DSConv は、Depthwise Separable Convolution の改良版であり、YOLOv5 などのターゲット検出モデルを改良するために使用できます。深さ方向の分離可能な畳み込みは、畳み込み演算を深さ方向の畳み込みと点方向の畳み込みの 2 つのステップに分解してパラメーターと計算を削減できる軽量の畳み込み演算です。DSConv は、深さ分離可能な畳み込みに基づいて分離可能なコンテキスト畳み込みを導入します。これにより、モデルの受容野と特徴抽出能力が強化され、検出精度が向上します。

DSConv の主な機能は次のとおりです。

  1. 分離可能なコンテキスト畳み込みが使用されます。DSConv は、深さ分離可能な畳み込みに基づいて分離可能なコンテキスト畳み込みを導入します。これにより、モデルの受容野と特徴抽出能力が強化され、検出精度が向上します。
  2. チャンネルごとのスケーリングを追加しました。DSConv は、ポイント バイ ポイントの畳み込みにチャネルごとのスケーリング操作を追加します。これにより、さまざまなチャネルの特徴マップの重みをさまざまな程度に調整して、モデルの堅牢性と汎化能力を向上させることができます。
  3. 畳み込み層の計算効率を維持します。DSConv は、深さ方向の分離可能な畳み込みの軽量機能を維持しており、計算効率を確保しながらモデルの検出精度を向上させることができます。

DSConv を導入することで、YOLOv5 などのターゲット検出モデルの検出効果と計算効率を効果的に向上させることができます。

YOLOV5 の改善 - 効率的なデカップリングヘッダー (yolov6 を参照)

効率的なデカップリング ヘッド (Efficient Head) は、ターゲット検出モデルの改良された方法であり、モデルの検出精度と計算効率を向上させることができます。効率的なデカップリング ヘッドは YOLOv6 で提案されました。これは、畳み込み層のチャネルを 2 つの部分 (デカップリングされた畳み込みとポイントバイポイントの畳み込み) に分解することで、モデルの特徴表現能力と計算効率を向上させます。

具体的には、効率的なデカップリング ヘッドの計算プロセスは次のとおりです。

  1. 特徴は、分離された畳み込みを使用して抽出されます。分離畳み込みは、畳み込み層のチャネルを 2 つの部分に分解し、個別に畳み込み演算を実行してモデルの特徴表現能力を向上させることができる特別な畳み込み演算です。効率的なデカップリング ヘッドでは、まずデカップリング コンボリューションを使用して特徴を抽出し、高次元の特徴表現を取得します。
  2. 点ごとの畳み込みを使用した次元削減。ポイントワイズ畳み込みは、高次元の特徴表現を低次元に削減して計算を削減する軽量の畳み込み演算です。効率的なデカップリング ヘッドでは、ポイントごとの畳み込みを使用して高次元の特徴表現の次元を削減し、低次元の特徴表現を取得します。
  3. 低次元のフィーチャを後続のレイヤーに渡します。最後に、低次元の特徴表現は、物体検出などのタスクのために後続の層に渡されます。

Efficient デカップリング ヘッドを使用すると、畳み込み層のチャネルを 2 つの部分に分解でき、モデルの特徴表現能力と計算効率が向上します。効率的なデカップリング ヘッドは、YOLOv6 などのターゲット検出モデルに適用され、良好な結果を達成しています。
ここに画像の説明を挿入

YOLOV5 の改善 - FasterNet 軽量モデルに基づく C3-Faster

https://blog.csdn.net/qq_37706472/article/details/129352058?spm=1001.2014.3001.5502

C3-Faster は、物体検出タスク用の FasterNet 軽量モデルに基づいて改良された方法です。C3-Faster は、FasterNet に基づいて C3 モジュールを追加することで、モデルの検出精度と計算効率をさらに向上させます。

具体的には、C3-Faster の改善には主に次の 2 つの側面が含まれます。

C3モジュールを追加します。C3 モジュールは、計算効率を確保しながらモデルの特徴表現能力を向上できる軽量の畳み込みモジュールです。C3-Fasterでは、C3モジュールを追加することでモデルの検出精度をさらに向上させることができます。

FasterNetのネットワーク構造を調整します。モデルの計算効率をさらに向上させるために、C3-Faster は FasterNet のネットワーク構造を調整しました。具体的には、C3-Faster は、FasterNet に基づいたいくつかの軽量の畳み込みモジュールを追加して、パラメーターと計算を削減します。

C3-Faster を使用することで、計算効率を確保しながらモデルの検出精度を向上させることができます。C3-Faster はいくつかのターゲット検出データセットで検証され、良好な結果を達成しています。

YOLOV5 の改善 - TIMM に基づいて必要なバックボーンを置き換えます

https://www.bilibili.com/video/BV1Mx4y1A7jy/?spm_id_from=333.788&vd_source=85f7d0d97c49c694901f6886c09b832b
TIMM (pytorch-image-models) に基づいて必要なバックボーンを置き換えるのは、YOLOv5 の改良された方法であり、ユーザーは自由に異なるバックボーンを置き換えることができます。バックボーン ネットワークは、さまざまな物体検出タスクとデータセットに合わせて選択されます。

TIMM は、分類、検出、セグメンテーション、その他のタスクを含む、事前トレーニングされた多数のモデルを提供する PyTorch ベースの画像モデル ライブラリです。TIMM のモデル ライブラリには、モデルの選択と置換を容易にする ResNet、EfficientNet、RegNet などのバックボーン ネットワークが多数含まれています。TIMM を使用すると、YOLOv5 のバックボーン ネットワークを、さまざまなタスクやデータセットに合わせて迅速かつ簡単に置き換えることができます。

具体的には、TIMM に基づいて必要なトランクを交換する方法には、主に次の手順が含まれます。

  1. TIMM から適切なバックボーン ネットワークを選択します。TIMM ベースの方法を使用して必要なバックボーンを置き換える場合は、まず TIMM から適切なバックボーン ネットワークを選択する必要があります。タスクとデータセットに応じて、最適な検出結果を得るためにさまざまなバックボーン ネットワークを選択できます。
  2. バックボーン ネットワークを YOLOv5 と統合します。バックボーン ネットワークを選択したら、YOLOv5 と統合する必要があります。具体的には、TIMM が提供する事前トレーニング モデルを初期化に使用したり、事前トレーニング モデルの特徴抽出部分を YOLOv5 の元のバックボーン ネットワークの置き換えに使用したりできます。
  3. トレーニングやチューニングに。バックボーン ネットワークを統合した後、最高の検出効果を得るためにトレーニングおよび調整する必要があります。特定のタスクとデータセットに従って、ハイパーパラメーターの調整とモデルの最適化を実行して、モデルのパフォーマンスを向上させることができます。

TIMM に基づいて必要なバックボーンを置き換える方法を使用すると、さまざまなバックボーン ネットワークを柔軟に選択して、さまざまなターゲット検出タスクやデータ セットに適応できるため、モデルの検出精度と計算効率が向上します。

YOLOV5 変更 - タスク固有コンテキスト分離の追加 (オブジェクト検出のためのタスク固有コンテキスト分離)

https://www.bilibili.com/video/BV1nT411z7on/?spm_id_from=333.788&vd_source=85f7d0d97c49c694901f6886c09b832b

タスク固有コンテキスト分離 (TSCD) は、物体検出タスク用に改良された方法であり、物体の周囲環境に対するモデルの認識を向上させることができます。TSCD の主なアイデアは、ターゲットのコンテキスト情報をタスク関連情報から分離して、コンテキスト情報をより有効に活用し、ターゲット検出の精度を向上させることです。

具体的には、TSCD の改善には主に次の 2 つの側面が含まれます。

コンテキスト情報の分離。TSCD では、分離モジュールを使用してターゲットのコンテキスト情報をタスク関連情報から分離し、2 つの異なる特徴ベクトルを取得します。その中で、コンテキスト情報は、モデルがターゲットの周囲の環境をより適切に認識するのに役立ち、タスク関連情報は、モデルがターゲット検出タスクをより適切に完了するのに役立ちます。

機能の融合。コンテキスト情報とタスク関連情報を分離した後、TSCD は特別な融合方法を使用してこれら 2 つの特徴ベクトルを融合します。具体的には、TSCD はアダプティブ アテンション メカニズムを使用して、ターゲットのサイズと位置情報に応じてコンテキスト情報とタスク関連情報の重みを動的に調整し、より正確な特徴表現を取得します。

TSCD を使用することで、ターゲットの周囲のコンテキスト情報をより有効に活用でき、モデルの知覚能力と検出精度を向上させることができます。TSCD は YOLOv5 モデルに適用され、良好な結果を達成しました。

YOLOV5 の改善 - FasterNet を使用して yolov5 のバックボーン ネットワークを置き換えます

FasterNet を使用して YOLOv5 のバックボーン ネットワークを置き換えることは、モデルの計算効率と検出精度を向上させることができる改善方法です。FasterNet は、計算効率を確保しながらモデルの特徴表現能力を向上できる軽量のバックボーン ネットワークです。

具体的には、FasterNet を使用して YOLOv5 のバックボーン ネットワークを置き換える方法には、主に次の手順が含まれます。

適切な FasterNet モデルを選択します。FasterNet を使用して YOLOv5 のバックボーン ネットワークを置き換える場合は、適切な FasterNet モデルを選択する必要があります。FasterNet は、特定のタスクやデータ セットに応じて選択できるさまざまなモデルを提供します。

FasterNet を YOLOv5 と統合します。FasterNet を YOLOv5 と統合するには、事前トレーニングされた FasterNet モデルを使用して初期化するか、事前トレーニングされたモデルの特徴抽出部分を使用して YOLOv5 の元のバックボーン ネットワークを置き換えることができます。

トレーニングやチューニングに。FasterNet を統合した後、最適な検出効果を得るにはトレーニングとチューニングが必要です。特定のタスクとデータセットに従って、ハイパーパラメーターの調整とモデルの最適化を実行して、モデルのパフォーマンスを向上させることができます。

YOLOv5 のバックボーン ネットワークを FasterNet に置き換えることにより、モデルの計算効率と検出精度を向上させることができます。FasterNet はターゲット検出タスクに適用され、良好な結果を達成しました。

YOLOV5 の改善 - 小さなターゲットに効果的な BiFormer アテンション メカニズム

BiFormer アテンション メカニズムは小さなオブジェクトに効果的で、オブジェクト検出タスクの改良された方法であり、小さなオブジェクトのモデルの検出精度を向上させることができます。この手法は BiFormer の注目メカニズムに基づいており、特徴マップに重み付けを行うことで、モデルの注意が小さな物体に集中し、小さな物体の検出効果が向上します。

具体的には、小さなターゲットに有効な BiFormer アテンション メカニズムの改善には、主に次の 2 つの側面が含まれます。

  1. BiFormer ベースのアテンション メカニズム。小さなオブジェクトに効果的な BiFormer アテンション メカニズムでは、BiFormer ベースのアテンション メカニズムを使用して特徴マップに重み付けが行われます。具体的には、この方法では、Transformer のセルフ アテンション メカニズムを使用して、異なる位置の特徴ベクトル間の類似度を計算することで各位置の重みを動的に調整し、より正確な特徴表現を取得します。
  2. 小さな物の特別な取り扱い。小さなオブジェクトを検出する場合、通常、小さなオブジェクトの検出精度を向上させるために、特徴マップの特別な処理が必要になります。この場合、小さなオブジェクトに効果的な BiFormer アテンション メカニズムは、特別な重み付け方法を使用して、モデルの注意を小さなオブジェクトに集中させます。具体的には、適応重み付け法を利用して物体のサイズや位置情報に応じて注目重みを動的に調整することで、小さな物体の検出精度を向上させる。

微小物体に有効なBiFormerアテンション機構を利用することで、微小物体モデルの検出精度が向上し、物体検出システム全体の性能が向上します。この方法は YOLOv5 モデルに適用され、良好な結果が得られました。

YOLOV5 の改善 - CFPNet に EVCBlock を追加

CFPNet への EVCBlock の追加は、物体検出タスクの改良された方法であり、モデルの計算効率と検出精度を向上させることができます。EVCBlock は、モデルの特徴表現能力を向上させながら、モデルの計算を高速化できる軽量のネットワーク モジュールです。

具体的には、CFPNet に EVCBlock を追加する方法には、主に次の手順が含まれます。

  1. 適切な EVCBlock モデルを選択します。EVCBlock を使用して CFPNet を改善する場合、適切な EVCBlock モデルを選択する必要があります。EVCBlock は、特定のタスクやデータセットに応じて選択できるさまざまなモデルを提供します。
  2. EVCBlock を CFPNet と統合します。EVCBlock を CFPNet と統合するには、事前トレーニングされた EVCBlock モデルを使用して初期化するか、事前トレーニングされたモデルの特徴抽出部分を使用して CFPNet の一部のモジュールを置き換えます。
  3. トレーニングやチューニングに。EVCBlock を統合した後、最適な検出効果を得るにはトレーニングとチューニングが必要です。特定のタスクとデータセットに従って、ハイパーパラメーターの調整とモデルの最適化を実行して、モデルのパフォーマンスを向上させることができます。

CFPNetにEVCBlockを追加することで、モデルの計算効率と検出精度を向上させることができます。EVCBlock はターゲット検出タスクに適用され、良好な結果を達成しました。

YOLOV5 の改善 - 軽量アップサンプリング オペレーター CARAFE を追加

軽量のアップサンプリング オペレーター CARAFE を追加することで、オブジェクト検出タスクの方法が改善され、アップサンプリングの効果とモデルの検出精度を向上させることができます。CARAFE は、計算効率を確保しながらモデルのアップサンプリング効果を向上させることができる軽量のアップサンプリング オペレーターです。

具体的には、CARAFE を追加する方法は主に次の手順で行われます。

  1. 適切な CARAFE モデルを選択してください。CARAFE を使用して YOLOv5 を改善する場合は、適切な CARAFE モデルを選択する必要があります。CARAFE は、特定のタスクやデータセットに応じて選択できるさまざまなモデルを提供します。
  2. CARAFE を YOLOv5 と統合します。CARAFE を YOLOv5 と統合するには、事前トレーニングされた CARAFE モデルを初期化に使用するか、事前トレーニング モデルの特徴抽出部分を使用して YOLOv5 の一部のモジュールを置き換えることができます。
  3. トレーニングやチューニングに。CARAFE を統合した後、最適な検出効果を得るにはトレーニングとチューニングが必要です。特定のタスクとデータセットに従って、ハイパーパラメーターの調整とモデルの最適化を実行して、モデルのパフォーマンスを向上させることができます。

CARAFEを追加することで、アップサンプリング効果とモデルの検出精度を向上させることができます。CARAFE はターゲット検出タスクに適用され、良好な結果を達成しました。YOLOv5 で CARAFE を使用すると、特に小さなターゲットの検出のパフォーマンスがさらに向上します。

YOLOV5 の改善 - Omni-Dimensional Dynamic Convolution バックボーンの Conv と BN fusion 操作チュートリアル

Omni-Dimensional Dynamic Convolution (ODDC) は、YOLOv5 のバックボーンを改善する畳み込み演算であり、モデルの精度と計算効率を向上させることができます。ODDC 操作は Conv 操作と BN 操作を組み合わせたもので、モデル内の計算量とメモリ使用量を削減できます。

ODDC の操作には主に次の手順が含まれます。

  1. Conv 演算と BN 演算を 1 つの畳み込み演算に結合します。これにより、モデル内の計算とメモリのフットプリントが削減されます。
  2. 結合された畳み込み演算を ODDC 演算に変換します。ODDC 演算は Tensor
    ベースの動的畳み込み演算であり、入力データの形状とサイズに従って畳み込みカーネルを動的に生成できます。
  3. ODDC 操作用に最適化されています。ODDC 操作は、コンボリューション カーネルの形状とサイズを調整することで、さまざまな入力データに適応できます。モデルの精度と計算効率は、コンボリューション カーネルの形状とサイズを調整することで最適化できます。

以下は、ODDC 操作を実装するためのチュートリアルです。

ODDC クラスを定義します。ODDC クラスは、PyTorch の nn.Module クラスを使用して定義できます。次に例を示します。

import torch
import torch.nn as nn

class ODDC(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=1, groups=1, dim=2):
        super(ODDC, self).__init__()
        self.dim = dim
        self.kernel_size = kernel_size

        if dim == 1:
            self.conv = nn.Conv1d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups, bias=False)
            self.bn = nn.BatchNorm1d(out_channels)
        elif dim == 2:
            self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups, bias=False)
            self.bn = nn.BatchNorm2d(out_channels)
        else:
            self.conv = nn.Conv3d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups, bias=False)
            self.bn = nn.BatchNorm3d(out_channels)

    def forward(self, x):
        # 计算均值和方差
        mean = torch.mean(x, dim=(2, 3), keepdim=True)
        var = torch.var(x, dim=(2, 3), keepdim=True)
        # 计算归一化的输入数据
        x_norm = (x - mean) / torch.sqrt(var + 1e-5)
        # 计算动态卷积核
        kernel_size = (self.kernel_size,) * self.dim
        weight = self.conv.weight
        weight_norm = torch.norm(weight.view(weight.size(0), -1), dim=1, keepdim=True)
        weight_norm = weight_norm.view(-1, *([1] * self.dim))
        weight_norm = weight_norm.repeat(1, *kernel_size)
        weight_norm = weight_norm.expand(-1, *x.size(1), *[-1] * self.dim)
        weight_norm = weight_norm * x_norm.size(1)
        kernel = weight / weight_norm
        # 执行动态卷积操作
        out = torch.nn.functional.conv2d(x_norm, kernel, stride=self.conv.stride, padding=self.conv.padding, dilation=self.conv.dilation, groups=self.conv.groups)
        # 进行 BN 操作
        out = self.bn(out)
        return out
使用 ODDC 类替换 Conv 和 BN 模块。可以使用 PyTorch 中的 nn.Sequential 类来定义模型,例如:
import torch.nn as nn

model = nn.Sequential(
    ODDC(3, 64, kernel_size=3, stride=2, padding=1),
    nn.ReLU(),
    ODDC(64, 128, kernel_size=3, stride=2, padding=1),
    nn.ReLU(),
    ODDC(128, 256, kernel_size=3, stride=2, padding=1),
    nn.ReLU(),
    ODDC(256, 512, kernel_size=3, stride=2, padding=1),
    nn.ReLU(),
    ODDC(512, 1024, kernel_size=3, stride=2, padding=1

トレーニングやチューニングに。Conv および BN モジュールを ODDC に置き換えた後、標準のトレーニングおよび調整方法を使用してモデルをトレーニングできます。特定のタスクとデータセットに従って、ハイパーパラメーターの調整とモデルの最適化を実行して、モデルのパフォーマンスを向上させることができます。
ODDC を使用して YOLOv5 バックボーンを改善する完全なコード例を次に示します。

import torch
import torch.nn as nn
from models.common import Conv, Bottleneck, SPP, DWConv

class ODDC(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=1, groups=1, dim=2):
        super(ODDC, self).__init__()
        self.dim = dim
        self.kernel_size = kernel_size

        if dim == 1:
            self.conv = nn.Conv1d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups, bias=False)
            self.bn = nn.BatchNorm1d(out_channels)
        elif dim == 2:
            self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups, bias=False)
            self.bn = nn.BatchNorm2d(out_channels)
        else:
            self.conv = nn.Conv3d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, padding=padding, groups=groups, bias=False)
            self.bn = nn.BatchNorm3d(out_channels)

    def forward(self, x):
        # 计算均值和方差
        mean = torch.mean(x, dim=(2, 3), keepdim=True)
        var = torch.var(x, dim=(2, 3), keepdim=True)
        # 计算归一化的输入数据
        x_norm = (x - mean) / torch.sqrt(var + 1e-5)
        # 计算动态卷积核
        kernel_size = (self.kernel_size,) * self.dim
        weight = self.conv.weight
        weight_norm = torch.norm(weight.view(weight.size(0), -1), dim=1, keepdim=True)
        weight_norm = weight_norm.view(-1, *([1] * self.dim))
        weight_norm = weight_norm.repeat(1, *x.size(1), *[-1] * self.dim)
        weight_norm = weight_norm * x_norm.size(1)
        kernel = weight / weight_norm
        # 执行动态卷积操作
        out = torch.nn.functional.conv2d(x_norm, kernel, stride=self.conv.stride, padding=self.conv.padding, dilation=self.conv.dilation, groups=self.conv.groups)
        # 进行 BN 操作
        out = self.bn(out)
        return out

class YOLOv5(nn.Module):
    def __init__(self, cfg='models/yolov5s.yaml'):
        super(YOLOv5, self).__init__()
        self.module_defs = parse_model_cfg(cfg)
        self.module_list, self.routs = create_modules(self.module_defs)
        self.yolo_head = YOLOLayer([(512, 1024), (256, 512), (128, 256)], 80)

    def forward(self, x):
        outputs = []
        route_idx = 0
        for i, (module_def, module) in enumerate(zip(self.module_defs, self.module_list)):
            if module_def['type'] in ['convolutional', 'depthwise_convolutional', 'ODDC']:
                x = module(x)
            elif module_def['type'] == 'shortcut':
                x = outputs[-1] + outputs[int(module_def['from'])]
            elif module_def['type'] == 'route':
                layers = module_def['layers'].split(',')
                layers = [int(l) if int(l) > 0 else i + int(l) for l in layers]
                if len(layers) == 1:
                    x = outputs[layers[0]]
                else:
                    try:
                        x = torch.cat([outputs[i] for i in layers], 1)
                    except ValueError:
                        import pdb; pdb.set_trace()
            elif module_def['type'] == 'yolo':
                x = self.yolo_head(x)
                outputs.append(x)
            outputs.append(x)
        return outputs[1:]

def create_modules(module_defs):
    """
    Constructs module list of layer blocks from module configuration in module_defs
    """
    hyperparams = module_defs.pop(0)
    output_filters = [int(hyperparams['channels'])]
    module_list = nn.ModuleList()
    routs = []
    for i, module_def in enumerate(module_defs):
modules = nn.Sequential()
if module_def['type'] == 'convolutional':
bn = int(module_def['batch_normalize'])
filters = int(module_def['filters'])
kernel_size = int(module_def['size'])
pad = (kernel_size - 1) // 2 if int(module_def['pad']) else 0
modules.add_module(f'conv{
      
      i}', Conv(output_filters[-1], filters, kernel_size, stride=int(module_def['stride']), padding=pad, bias=not bn))
if bn:
modules.add_module(f'bn{
      
      i}', nn.BatchNorm2d(filters, momentum=0.1))
if module_def['activation'] == 'leaky':
modules.add_module(f'leaky{
      
      i}', nn.LeakyReLU(0.1))
elif module_def['type'] == 'depthwise_convolutional':
bn = int(module_def['batch_normalize'])
filters = output_filters[-1]
kernel_size = int(module_def['size'])
pad = (kernel_size - 1) // 2 if int(module_def['pad']) else 0
modules.add_module(f'conv{
      
      i}', DWConv(filters, kernel_size, stride=int(module_def['stride']), padding=pad, bias=not bn))
if bn:
modules.add_module(f'bn{
      
      i}', nn.BatchNorm2d(filters, momentum=0.1))
if module_def['activation'] == 'leaky':
modules.add_module(f'leaky{
      
      i}', nn.LeakyReLU(0.1))
elif module_def['type'] == 'ODDC':
bn = int(module_def['batch_normalize'])
filters = int(module_def['filters'])
kernel_size = int(module_def['size'])
pad = (kernel_size - 1) // 2 if int(module_def['pad']) else 0
modules.add_module(f'oddc{
      
      i}', ODDC(output_filters[-1], filters, kernel_size, stride=int(module_def['stride']), padding=pad, bias=not bn))
if bn:
modules.add_module(f'bn{
      
      i}', nn.BatchNorm2d(filters, momentum=0.1))
if module_def['activation'] == 'leaky':
modules.add_module(f'leaky{
      
      i}', nn.LeakyReLU(0.1))
elif module_def['type'] == 'spp':
filters = output_filters[-1]
modules.add_module(f'spp{
      
      i}', SPP(filters, filters, [5, 9, 13]))
elif module_def['type'] == 'bottleneck':
bn = int(module_def['batch_normalize'])
filters = output_filters[-1]
internal_filters = int(module_def['internal_filters']) if 'internal_filters' in module_def else filters
modules.add_module(f'bot{
      
      i}', Bottleneck(filters, internal_filters, shortcut=int(module_def['shortcut']), expansion=2))
if bn:
modules.add_module(f'bn{
      
      i}', nn.BatchNorm2d(filters, momentum=0.1))
if module_def['activation'] == 'leaky':
modules.add_module(f'leaky{
      
      i}', nn.LeakyReLU(0.1))
elif module_def['type'] == 'route':
layers = module_def['layers'].split(',')
layers = [int(l) if int(l) > 0 else i + int(l) for l in layers]
filters = sum([output_filters[l] for l in layers])
modules.add_module(f'route{
      
      i}', nn.Sequential())
routs.extend([i + l if l < 0 else l for l in layers])
elif module_def['type'] == 'shortcut':
filters = output_filters[-1]
modules.add_module(f'shortcut{
      
      i}', nn.Sequential())
routs.append(i + int(module_def['from']))
elif module_def['type'] == 'yolo':
modules.add_module(f'yolo{
      
      i}', YOLOLayer([int(x) for x in module_def['anchors'].split(',')], int(module_def['classes']), int(module_def['num']), int(module_def['iou_thresh']), int(module_def['conf_thresh'])))
filters = output_filters[-1]
else:
print(f"Warning: Unrecognized Layer Type: {
      
      module_def['type']}")
filters = output_filters[-1]
output_filters.append(filters)
module_list.append(modules)
return module_list, routs, output_filters<|im_sep|>

このコードは、YOLOv3 ニューラル ネットワーク アーキテクチャを定義する PyTorch 関数です。この関数は辞書のリストを受け入れます。各辞書はニューラル ネットワーク内の層を表します。各ディクショナリには、レイヤー タイプ、パラメーター、ハイパーパラメーターに関する情報が含まれています。

この関数は辞書のリストを反復処理し、その型に基づいて PyTorch モジュールを作成します。これらのモジュールは PyTorch の Sequential コンテナに追加され、ニューラル ネットワーク アーキテクチャ全体が作成されます。

この関数でサポートされるさまざまなレイヤー タイプは次のとおりです。

convolutional: オプションのバッチ正規化とアクティブ化を備えた標準の畳み込み層。
Depthwise_convolutional: オプションのバッチ正規化とアクティブ化を備えた深さ方向の分離可能な畳み込み層。
ODDC: オプションのバッチ正規化とアクティブ化を備えた ODDC (Offset Dynamic Depthwise Convolution) と呼ばれるカスタム レイヤー。
spp: 空間ピラミッド プーリング層。
bottleneck: ResNet アーキテクチャで一般的に使用されるボトルネック層。
ルート: 2 つ以上の前の層の出力を接続する層。
ショートカット: 前のレイヤーの出力を現在のレイヤーの出力に追加するレイヤー。
yolo: 境界ボックス、オブジェクト スコア、クラス確率を予測するためにオブジェクト検出モデルで使用されるカスタム レイヤー。
この関数は、ニューラル ネットワーク モジュールを含む PyTorch Sequential コンテナ、出力がどのレイヤーにルーティングされるかを示すインデックスのリスト、および各レイヤーの出力内のフィルター数のリストを返します。これらの値は、後で YOLOv3 のトレーニングおよび推論コードで使用されます。

bnとは何ですか

「bn」とはディープラーニングの略称で、Batch
Normalization(バッチ正規化)技術のことを指します。バッチ正規化は、ディープ ニューラル ネットワークのトレーニングを高速化し、安定させるために一般的に使用される手法です。ディープ ニューラル ネットワークでは、各層の入力と出力に分布シフトの
問題が発生する可能性があり、これによりネットワークのトレーニングが困難になり、収束が遅くなります。バッチ正規化では、各層でネットワーク入力の分布を正規化することでネットワークのトレーニングと最適化が容易になり、ネットワークの汎化パフォーマンスを向上させることができます。

PyTorch では、
nn.BatchNorm2d() を呼び出すことでバッチ正規化レイヤーを作成できます。この層は入力テンソルを受け取り、そのバッチ次元を正規化し、正規化されたテンソルを出力できます。バッチ正規化層は通常、畳み込み層または完全接続層の後に使用され、ネットワークの収束を高速化し、モデルの精度と汎化パフォーマンスを向上させることができます。
深層学習では、畳み込み層とバッチ正規化層が
一般的に使用されるタイプのニューラル ネットワーク層です。これら 2 つの層を組み合わせることで、ニューラル ネットワークのトレーニング効果と汎化能力を向上させることができます。

PyTorchでは畳み込み層とバッチ正規化層を組み合わせることで、より複雑なネットワーク層を形成できます。具体的には、
nn.Sequential()次のようにして連結できます。

    nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding),
    nn.BatchNorm2d(out_channels),
    nn.ReLU(inplace=True) ) 

この例では、nn.Conv2d()畳み込み層が作成され、nn.BatchNorm2d()バッチ正規化層が作成され、両方の層の後に
nn.ReLU()活性化関数が続きます。このような層の組み合わせは、基本的な畳み込みバッチ正規化層ユニットとして使用でき、実際のニューラル ネットワークで再利用できます。

畳み込み層とバッチ正規化層を組み合わせる場合、入力次元と出力次元が一致しているかどうかに特別な注意を払う必要があることに注意してください。上の例では、nn.Conv2d()
出力のチャネル数は のnn.BatchNorm2d()入力チャネル数と一致する必要があります。この方法によってのみ、2 つの層をスムーズに接続することができます。

さらに、畳み込みバッチ正規化層の効果をさらに改善するために使用できる最適化手法がいくつかあります。たとえば、 のパラメータを使用してnn.Conv2d()のオフセット パラメータbiasを置き換えるなどです。
nn.BatchNorm2d()これらの技術は、特定のアプリケーション シナリオや実験結果に応じて選択および調整できます。

ODDC 操作は Conv 操作と BN 操作をどのように統合しますか

ODDC (Offset Dynamic Depthwise Convolution) は、深さ方向に分離可能な畳み込みとバッチ正規化操作を組み合わせたカスタム ニューラル ネットワーク層です。ODDC の目的は、モデルのパフォーマンスと汎化能力を向上させることです。

ODDC では、深さ方向に分離可能な畳み込み演算とバッチ正規化演算がどのように組み合わされるのでしょうか? サンプルコードは次のとおりです。

class ODDC(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride, padding, dilation=1, groups=1, bias=True):
        super(ODDC, self).__init__()

        # depthwise convolution with bias
        self.conv_dw = nn.Conv2d(in_channels, in_channels, kernel_size, stride, padding, dilation=dilation, groups=in_channels, bias=True)

        # batch normalization
        self.bn = nn.BatchNorm2d(in_channels)

        # pointwise convolution with bias
        self.conv_pw = nn.Conv2d(in_channels, out_channels, 1, 1, 0, bias=bias)

        # activation function
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x):
        # depthwise convolution
        x = self.conv_dw(x)

        # batch normalization
        x = self.bn(x)

        # pointwise convolution
        x = self.conv_pw(x)

        # activation function
        x = self.relu(x)

        return x

この例では、ODDC 層には、深さ方向の分離可能な畳み込み、バッチ正規化、ポイント畳み込み、および ReLU アクティベーション関数が含まれています。深さ方向に分離可能な畳み込み演算とバッチ正規化演算は、それぞれ self.conv_dw 層と self.bn 層に実装されています。順方向パス中、入力テンソル x は最初に深さ方向の分離可能な畳み込みを受け、次にバッチ正規化操作によって正規化されます。その後、点畳み込みと ReLU 活性化関数の処理を経て、最終的な出力結果が得られます。

深さ方向に分離可能な畳み込み演算とバッチ正規化演算は、それぞれ 2 つの異なる層で実装されることに注意してください。これは、深さ方向分離可能コンボリューションの計算プロセスが標準のコンボリューションとは異なるため、グループ パラメーターを使用して入力チャンネルをグループ化する必要があるためです。一方、バッチ正規化では、畳み込み層の出力を正規化する必要があります。したがって、ODDC 層は、これら 2 つの操作を実現するために 2 つの異なる層を使用し、それらを連結して全体のニューラル ネットワーク層として使用する必要があります。

YOLOV5 の改善 - 小さなターゲット向けのポイントを備えた全次元動的畳み込みバックボーン

全次元ダイナミック コンボリューション (ODDC) は、さまざまな次元でコンボリューション カーネルの形状とサイズを動的に調整できる適応型コンボリューション操作です。YOLOv5 では、小さなオブジェクトをより適切に処理するためのバックボーン ネットワークの改良点として ODDC が使用されています。

YOLOv5 のバックボーン ネットワークは、複数の畳み込み層と残差ブロックを含む CSPDarknet53 アーキテクチャを使用します。これらの畳み込み層と残差ブロックでは、小さなオブジェクトの検出タスクによりよく適応するために、ODDC が元の標準畳み込み演算の代わりに使用されます。

ODDC の具体的な実装は、深さ方向に分離可能な畳み込みとバッチ正規化操作を組み合わせ、動的畳み込みカーネルを使用して適応畳み込みを実現することです。実際のアプリケーションでは、ODDC は、さまざまなサイズのターゲットに適応するために、コンボリューション カーネルの形状とサイズを自動的に調整できます。

ODDC を使用することにより、YOLOv5 のバックボーン ネットワークは小さなオブジェクトをより適切に処理できるようになり、検出精度と汎化能力が向上します。さらに、ODDC には高い計算効率と小さいメモリ使用量という利点もあるため、YOLOv5 は高精度を維持しながら検出速度が速くなり、モデル サイズが小さくなります。

要約すると、ODDC は小さなオブジェクトの検出に適した適応畳み込み演算であり、モデルの精度と汎化能力を効果的に向上させることができます。YOLOv5 では、バックボーン ネットワークの改良として ODDC が使用され、良好な検出結果とパフォーマンスの最適化が実現されました。
odcの利点は何ですか?

全次元ダイナミック コンボリューション (ODDC) は、次の利点がある適応型コンボリューション演算です。

  • 適応型コンボリューション カーネル: ODDC は、コンボリューション カーネルの形状とサイズを自動的に調整して、さまざまなサイズのターゲットに適応し、モデルの適応性と一般化能力を向上させることができます。
  • 高い計算効率: ODDC の適応コンボリューション カーネルは、計算量を効果的に削減し、モデルの複雑さと計算時間を短縮します。
  • 小さいメモリ フットプリント: ODDC の適応コンボリューション カーネルにより、モデルのパラメータ数とメモリ フットプリントを削減できるため、モデルが軽量になり、展開が容易になります。
  • 幅広い適用性: ODDC は、画像分類、ターゲット検出、セマンティック セグメンテーションなど、さまざまなコンピューター ビジョン タスクに適用できます。
  • 高精度: ODDC は、コンボリューション カーネルの形状とサイズを適応的に調整することで、さまざまなサイズのターゲットに適切に適応できるため、モデルの精度と汎化能力が向上します。

結論として、ODDC は、適応性、高い計算効率、小さなメモリ使用量、幅広い適用性、高精度という利点を備えた畳み込み演算であり、コンピュータ ビジョン タスクのパフォーマンスと効率を効果的に向上させることができます。
odcのデメリットは何ですか?

全次元ダイナミック コンボリューション (ODDC) には多くの利点がありますが、いくつかの欠点もあります。

  1. 大量の計算: ODDC の適応コンボリューション カーネルは動的に計算する必要があるため、モデルの計算量が増加し、モデルのトレーニングと推論の速度が遅くなります。
  2. 不安定性: ODDC の適応的な性質により、コンボリューション カーネルが小さすぎる、または大きすぎるなど、いくつかの特殊なケースではモデルが不安定になる可能性があります。
  3. パラメーターの調整が難しい: ODDC の適応コンボリューション カーネルには複数の次元とパラメーターがあるため、複雑な調整と最適化が必要となり、モデルの設計とデバッグが難しくなります。
  4. 解釈可能性が低い: ODDC の適応コンボリューション カーネルは動的に生成され、各コンボリューション カーネルの特定の機能と意味を説明するのが難しく、モデルの解釈と理解に一定の困難が生じます。

つまり、ODDC の欠点は、主に計算量の多さ、不安定さ、パラメータ調整の難しさ、解釈のしやすさであり、実際のアプリケーションでは総合的に考慮して比較検討し、適切な畳み込み演算とモデル構造を選択する必要があります。

おすすめ

転載: blog.csdn.net/qq_44089890/article/details/130120649#comments_26920106