Este es un artículo sobre el diseño de los bloques de extracción de características desarrollados para mejorar la detección de objetos a múltiples escalas mientras se mantiene la inferencia rápida en las aplicaciones del mundo real. Conexiones parciales transversales (CSP) En primer lugar, WongKinYiu et al. [ ] introdujo esta innovación arquitectónica y abordó el problema de la información de gradientes redundantes en las vértebras de la red neural convolucional más grandes. Su objetivo principal es enriquecer las interacciones de gradientes al tiempo que se reducen los costos computacionales. Las conexiones parciales transversales (CSP) conservan la diversidad de gradientes al combinar mapas de características desde el comienzo y el final de cada etapa de la red: los mapas de características de la capa base se dividen en dos partes: uno pasa a través de un bloque denso y una capa de transición, mientras que el otro oculta este camino y se conecta directamente a la siguiente etapa. Esta arquitectura está diseñada para abordar múltiples problemas, incluyendo el aumento de la capacidad de aprendizaje de la CNN, la eliminación de las barreras computacionales y la 1 CSP-DenseNet mantiene los beneficios de reutilización de características de DenseNet al mismo tiempo que reduce la información de gradiente duplicada al recortar el flujo de gradiente, logrado a través de una estrategia de fusión de características jerárquica en una capa de transición parcial. Según la , este enfoque reduce la computación en un 20% al tiempo que se logra una precisión equivalente o incluso superior en el conjunto de datos de ImageNet. Experimentos de los autores C3 YOLOv4 y YOLOv5 utilizan el módulo Cross Stage Partial (CSP) para mejorar la extracción de características en el botellón.El bloque C3 es una implementación práctica de esta arquitectura CSP en Los modelos de YOLO. Ultralíticos En el bloque C3, los mapas de características de entrada se dividen en dos partes. Una parte es procesada por una convolución 1×1 seguida por los bloques de botella paralelos, mientras que la otra parte pasa a través de una convolución 1×1 separada y salta de las botellas por completo. Estas dos ramas son luego concatenadas a lo largo de la dimensión del canal y fusionadas por otra convolución 1×1 para producir la salida. n Input (x) │ ┌────────┴─────────┐ │ │ [1x1 Conv] [1x1 Conv] (cv1) (cv2) │ │ [Bottlenecks] │ (m: n blocks) │ │ │ └────────┬─────────┘ │ [Concat along C] │ [1x1 Conv → cv3] │ Output Con la implantación de ultralytics ( ) de : GitHub enlaces 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)) Cross-Stage Parcial con conexiones 2F (C2F) El bloque C2f se basa en CSPNet, extendiéndolo aún más: en lugar de un único camino de fusión, introduce dos conexiones de fusión de características paralelas, cada una con la mitad del número de canales de salida. ] [ ], sigue los mismos principios que CSP al dividir el mapa de características de entrada para reducir la redundancia computacional y mejorar el reuso de las características. 2 3 En un bloque C2f, el tensor de entrada se divide en dos caminos: uno oculta las capas de Bottleneck como un recorrido corto, mientras que el otro pasa a través de múltiples capas de Bottleneck. A diferencia del CSP original, que utiliza solo la salida final de Bottleneck, C2f recoge todas las salidas intermedias de Bottleneck y las conecta - aumentando la diversidad de características y la representación. Esta estrategia de fusión de funciones dual (2F) también ayuda a la red a manejar mejor la oclución, haciendo que las detecciones sean más robustas en escenas desafiantes. Implementación de las ecuaciones lineales ( ) de : GitHub enlaces 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 Parcial con bloque de tamaño de núcleo 2 (C3k2) Yucatán 11 [ ] utiliza los siguientes bloques C3K2 en la cabeza para la extracción de características en varias etapas de su columna vertebral para procesar características multicanal — otra evolución del clásico CSP bottleneck. El bloque C3K2 divide el mapa de características y lo procesa con múltiples convoluciones ligeras 3×3, fusionando los resultados después. Esto mejora el flujo de información mientras permanece más compacto que un completo CSP bottleneck, reduciendo el número de parámetros entrenables. 4 El bloque C3K mantiene la misma estructura básica que C2f pero no divide la salida después de la convolución inicial. Las capas de Bottleneck con concatenamientos intermedios terminan con una convolución final de 1×1. A diferencia de C2f, C3K agrega flexibilidad con tamaños de núcleo personalizables, ayudando al modelo a capturar mejor detalles finos en diferentes escalas de objetos. n Basándose en esta idea, C3K2 reemplaza a Bottlenecks simples con múltiples bloques de C3K. Comienza con un bloque Conv, empieza a empacar varios bloques de C3K en secuencia, concatenando sus salidas con la entrada original y termina con otra capa de Conv, mezclando el concepto de fusión dividida de CSP con núcleos flexibles para equilibrar la velocidad, la eficiencia de parámetros y una extracción de características multiescala más rica. 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] Cada bloque C3K utiliza Bottlenecks paralelos con núcleos personalizados, proporcionando más flexibilidad para la extracción de características y permitiendo al modelo adaptarse mejor a patrones complejos. 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] Implementación de las ecuaciones lineales ( ) de : GitHub enlaces 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) ) Conclusión En resumen, las arquitecturas modernas de YOLO continúan evolucionando al agregar bloques como C3, C2f, C3k y C3k2 —todos construidos en torno a la idea central de las conexiones parciales (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 Botellas paralelas Botellas Núcleos fijos C2F Botas de serie Botellas Núcleos fijos C3K Botellas paralelas Botellas Núcleos personalizados C3K2 Bloques de serie C3K Cada C3k tiene botellas paralelas Núcleos personalizados Estos refinamientos arquitectónicos ayudan colectivamente a los modelos YOLO a mantener una alta precisión de detección, al tiempo que se mantienen lo suficientemente rápidos y ligeros para la implementación en tiempo real, una ventaja crítica para diversas aplicaciones. La izquierda 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