Това е статия за проектирането на блокове за извличане на функции, разработени за подобряване на откриването на обекти в множество мащаби, като същевременно се поддържа бързо заключение в реални приложения. Кръстостепенни частични връзки (CSP) На първо място, Гьотев и др. Неговата основна цел е да обогати градиентните взаимодействия, като същевременно намалява изчислителните разходи. Кръстостепенните частични връзки (CSP) запазват градиентното многообразие чрез комбиниране на карти на характеристиките от началото и края на всеки етап на мрежата: картите на характеристиките на базовия слой са разделени на две части: единият преминава през плътен блок и преходен слой, а другият заобикаля този път и се свързва директно към следващия етап. 1 CSP-DenseNet запазва предимствата от повторното използване на функциите на DenseNet, като същевременно намалява дублиращата се информация за градиент чрез подрязване на потока на градиент, постигнат чрез йерархична стратегия за сливане на функции в частичен преходен слой. Според , този подход намалява изчисленията с 20% при постигане на еквивалентна или дори по-висока точност на набора от данни на ImageNet. Експерименти на авторите С3 YOLOv4 и YOLOv5 използват модула Cross Stage Partial (CSP) за подобряване на екстракцията на функции в бутилката. Модели на йога. ултразвук В блока C3 входните карти на функциите се разделят на две части. Едната част се обработва от 1×1 конвулсия, последвана от паралелни бутилирани блокове, докато другата част преминава през отделна 1×1 конвулсия и напълно прескача бутилираните блокове. Тези две клона след това се съединяват по размера на канала и се сливат с друга 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, разширявайки го по-нататък: вместо един единствен път на сливане, той въвежда две паралелни функции на сливане на връзки, всяка с половината от броя на изходните канали. ][ на ], следва същите принципи като CSP чрез разделяне на входната карта на функциите, за да се намали изчислителната излишност и да се подобри повторното използване на функциите. 2 3 В блок C2f входният тензор се разделя на два пътя: единият заобикаля слоевете Bottleneck като съкращение, а другият преминава през множество слоеве Bottleneck. За разлика от оригиналния CSP, който използва само окончателния изход Bottleneck, C2f събира всички междинни Bottleneck изходи и ги съединява – увеличавайки разнообразието и представянето на функциите. Използване на ултразвук ( ) на : 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)) Кръстосано етапно частично с блок с размер на ядрото 2 (C3k2) Епизод 11 [ ] използва следните C3K2 блокове в главата за извличане на функции на различни етапи от гръбначния му стълб, за да обработва многомащабни функции - друга еволюция на класическия CSP бутилка. Блокът C3K2 разделя картата на функциите и я обработва с множество леки 3×3 конволции, сливайки резултатите след това. 4 Блокът C3K запазва същата основна структура като C2f, но не разделя изхода след първоначалната конволуция. За разлика от C2f, C3K добавя гъвкавост с персонализируеми размери на ядрото, което помага на модела по-добре да улавя фини детайли на различни обекти. n Въз основа на тази идея C3K2 заменя обикновените Bottlenecks с няколко блока C3K. Той започва с блок Conv, натрупва няколко блока C3K в последователност, съединява техните изходи с оригиналния вход и завършва с друг слой Conv - смесвайки концепцията за разделено сливане на 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 С3 Паралелни бутилки Бутилките Фиксирани ядра К2Ф Серийни бутилки Бутилките Фиксирани ядра К3К Паралелни бутилки Бутилките Кумулативни ядра К3К2 Серийни C3K блокове Всеки C3k има паралелни Bottlenecks Кумулативни ядра Тези архитектурни усъвършенствания помагат на 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