これは、複数のスケールのオブジェクト検出を改善するために開発された機能抽出ブロックの設計についての記事で、リアルなアプリケーションで迅速な推論を維持します。 クロスステージ部分接続(CSP) まず、ウォンキンヤウス et al. [ ]はこの建築革新を導入し、より大規模な結合型ニューラルネットワークのバックボーンにおける過剰なグレディント情報の問題に対処しました。その主な目的は、計算コストを削減しながらグレディント相互作用を豊かにすることです。Cross-stage partial connections (CSP) は、各ネットワーク段階の開始と終了の両方から機能マップを組み合わせることによって、グレディントの多様性を維持します:ベース層の機能マップは2つの部分に分かれています:一つは密集したブロックと移行層を通過し、もう一つはこのパスを回避し、次の段階に直接接続します。このアーキテクチャは、CNNの学習能力を向上させ、コンピュータのボトル 1 CSP-DenseNet は、DenseNet の機能再利用の利点を維持し、部分的な過渡層における機能統合戦略を通じて達成されたグラディエントフローを縮小することで、重複したグラディエント情報を削減します。 」によると、The このアプローチは、計算を20%削減し、ImageNetデータセットで同等のまたは優れた精度を達成します。 著者の「実験」 C3 YOLOv4 と YOLOv5 は、Cross Stage Partial (CSP) モジュールを使用して、ボトルネックの機能抽出を改善します。 YOLOモデル 超音波 C3 ブロックでは、入力機能マップは 2 つの部分に分けられ、1 つの部分は 1 × 1 回転によって処理され、次に 1 × 1 回転によって処理されます。 平行ボトルネックブロックは、他の部分は別々の1×1コンボリューションを通過し、ボトルネックを完全に飛び越えます。これらの2つの枝は、チャネルサイズに沿って結合され、出力を生成するために別の1×1コンボリューションによって合併します。 n Input (x) │ ┌────────┴─────────┐ │ │ [1x1 Conv] [1x1 Conv] (cv1) (cv2) │ │ [Bottlenecks] │ (m: n blocks) │ │ │ └────────┬─────────┘ │ [Concat along C] │ [1x1 Conv → cv3] │ Output オリジナルタイトル( ) : GitHub リンク class C3(nn.Module): """CSP Bottleneck with 3 convolutions.""" def __init__(self, c1: int, c2: int, n: int = 1, shortcut: bool = True, g: int = 1, e: float = 0.5): """ Initialize the CSP Bottleneck with 3 convolutions. Args: c1 (int): Input channels. c2 (int): Output channels. n (int): Number of Bottleneck blocks. shortcut (bool): Whether to use shortcut connections. g (int): Groups for convolutions. e (float): Expansion ratio. """ super().__init__() c_ = int(c2 * e) # hidden channels self.cv1 = Conv(c1, c_, 1, 1) self.cv2 = Conv(c1, c_, 1, 1) self.cv3 = Conv(2 * c_, c2, 1) self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, k=((1, 1), (3, 3)), e=1.0) for _ in range(n))) def forward(self, x: torch.Tensor) -> torch.Tensor: """Forward pass through the CSP bottleneck with 3 convolutions.""" return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1)) クロスステージ部分 2F接続(C2F) C2fブロックはCSPNetに基づいて構築され、さらに拡張する:単一の合併経路の代わりに、それぞれ出力チャネルの半数を持つ2つの並行機能合併接続を導入します。 (※) ]、CSPと同じ原則に従って、入力機能マップを分割して、計算過剰性を減らし、機能の再利用を改善します。 2 3 C2f ブロックでは、入力テンサーは 2 つのパスに分かれています: 1 つは Bottleneck レイヤーをブロックとして回避し、もう1つは複数の Bottleneck レイヤーを通過します。 最終的な Bottleneck 出力のみを使用するオリジナル CSP とは異なり、C2f はすべての中間的な Bottleneck 出力を収集し、それらをコンタクトします - 機能の多様性と代表性を高めます。 この二重機能融合 (2F) 戦略はまた、ネットワークがオクルシウムをよりよく処理するのを助け、挑戦的なシーンで検出をより強力にします。 オリジナルタイトル( ) : GitHub リンク class C2f(nn.Module): """Faster Implementation of CSP Bottleneck with 2 convolutions.""" def __init__(self, c1: int, c2: int, n: int = 1, shortcut: bool = False, g: int = 1, e: float = 0.5): """ Initialize a CSP bottleneck with 2 convolutions. Args: c1 (int): Input channels. c2 (int): Output channels. n (int): Number of Bottleneck blocks. shortcut (bool): Whether to use shortcut connections. g (int): Groups for convolutions. e (float): Expansion ratio. """ super().__init__() self.c = int(c2 * e) # hidden channels self.cv1 = Conv(c1, 2 * self.c, 1, 1) self.cv2 = Conv((2 + n) * self.c, c2, 1) # optional act=FReLU(c2) self.m = nn.ModuleList(Bottleneck(self.c, self.c, shortcut, g, k=((3, 3), (3, 3)), e=1.0) for _ in range(n)) def forward(self, x: torch.Tensor) -> torch.Tensor: """Forward pass through C2f layer.""" y = list(self.cv1(x).chunk(2, 1)) y.extend(m(y[-1]) for m in self.m) return self.cv2(torch.cat(y, 1)) def forward_split(self, x: torch.Tensor) -> torch.Tensor: """Forward pass using split() instead of chunk().""" y = self.cv1(x).split((self.c, self.c), 1) y = [y[0], y[1]] y.extend(m(y[-1]) for m in self.m) return self.cv2(torch.cat(y, 1)) Cross Stage Partial with kernel size 2 (C3k2) ブロック 第11話(笑) ] 頭部の以下のC3K2ブロックを使用して、その脊椎のさまざまな段階で機能を抽出して、複数のスケール機能を処理します - 古典的なCSPボトルネックのもう一つの進化です。 C3K2ブロックは、機能マップを分割し、複数の軽量3×3コンボリューションで処理し、その後結果を合併します。 4 C3K ブロックは C2f と同じ基本構造を維持しますが、初期回転後に出力を分割しません。 Bottleneck レイヤーは中間コンカテネーションで、最終的な 1×1 コンボレーションで終わります。C2fとは異なり、C3K はカスタマイズ可能なカーネルサイズで柔軟性を追加し、モデルが異なるオブジェクトスケールで細部をよりよくキャプチャするのに役立ちます。 n このアイデアに基づいて、C3K2は単純なBottlenecksを複数のC3Kブロックに置き換え、Convブロックから始まり、いくつかのC3Kブロックを順序に積み重ね、その出力を元の入力と結合し、CSPの分割合併コンセプトを柔軟なカーネルと組み合わせ、速度、パラメータ効率、より豊かなマルチスケール機能抽出をバランスをとる。 Input: [Batch, c1, H, W] │ [cv1] (1x1 Conv) → splits channels into 2c │ ┌─────────────┐ │ │ Branch 1 Branch 2 (Bypass) (Bottleneck chain) │ │ ├─> C3k Block #1 │ ├─> C3k Block #2 │ ... (n times) │ └─────────────┬─────────────┐ Concatenate [Bypass, Split, C3k outputs] │ [cv2] (1x1 Conv) │ Output: [Batch, c2, H, W] 各 C3K ブロックは、カスタム カーネルと並列の Bottlenecks を使用し、機能抽出のためのより多くの柔軟性を提供し、モデルが複雑なパターンに適応することを可能にします。 C3k Input: [Batch, c, H, W] │ [cv1] (1x1 Conv, expand/split) │ ┌───────────────┐ │ │ ByPass Bottleneck blocks │ ┌─────────────┐ │ B1, B2, ...Bn (parallel) └─────────────┘ └───────────────┬───────┘ Concatenate │ [cv2] (1x1 Conv) │ C3k Output: [Batch, c, H, W] オリジナルタイトル( ) : GitHub リンク class C3k(C3): """C3k is a CSP bottleneck module with customizable kernel sizes for feature extraction in neural networks.""" def __init__(self, c1: int, c2: int, n: int = 1, shortcut: bool = True, g: int = 1, e: float = 0.5, k: int = 3): """ Initialize C3k module. Args: c1 (int): Input channels. c2 (int): Output channels. n (int): Number of Bottleneck blocks. shortcut (bool): Whether to use shortcut connections. g (int): Groups for convolutions. e (float): Expansion ratio. k (int): Kernel size. """ super().__init__(c1, c2, n, shortcut, g, e) c_ = int(c2 * e) # hidden channels # self.m = nn.Sequential(*(RepBottleneck(c_, c_, shortcut, g, k=(k, k), e=1.0) for _ in range(n))) self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, k=(k, k), e=1.0) for _ in range(n))) class C3k2(C2f): """Faster Implementation of CSP Bottleneck with 2 convolutions.""" def __init__( self, c1: int, c2: int, n: int = 1, c3k: bool = False, e: float = 0.5, g: int = 1, shortcut: bool = True ): """ Initialize C3k2 module. Args: c1 (int): Input channels. c2 (int): Output channels. n (int): Number of blocks. c3k (bool): Whether to use C3k blocks. e (float): Expansion ratio. g (int): Groups for convolutions. shortcut (bool): Whether to use shortcut connections. """ super().__init__(c1, c2, n, shortcut, g, e) self.m = nn.ModuleList( C3k(self.c, self.c, 2, shortcut, g) if c3k else Bottleneck(self.c, self.c, shortcut, g) for _ in range(n) ) 結論 要するに、現代のYOLOアーキテクチャは、C3、C2f、C3k、C3k2などのブロックを追加することによって進化し続けています - これらはすべて、クロスステージ部分接続(CSP)のコアアイデアに基づいて構築されています。 Block Outer Structure Inner Structure Kernel flexibility C3 Parallel Bottlenecks Bottlenecks Fixed kernels C2f Serial Bottlenecks Bottlenecks Fixed kernels C3k Parallel Bottlenecks Bottlenecks Custom kernels C3k2 Serial C3k blocks Each C3k has parallel Bottlenecks Custom kernels C3 パラレルボトル ボトルネック 固定カーネル C2F シリーズボトルネック ボトルネック 固定カーネル C3K パラレルボトル ボトルネック Custom Kernel C3K2 シリアルC3Kブロック 各 C3k には並列ボトルネックがあります。 Custom Kernel これらのアーキテクチャの改良により、YOLOモデルは高い検出精度を保ちながら、リアルタイムでの展開に十分に速く、軽量な状態を保ち、さまざまなアプリケーションにとって重要な利点となっています。 左利き https://arxiv.org/pdf/1911.11929 https://arxiv.org/pdf/2207.02696 https://arxiv.org/pdf/2408.15857 https://arxiv.org/html/2410.17725v1#S3