Este es un artículo sobre el diseño de bloques de extracción de características desarrollados para mejorar la detección de objetos a múltiples escala mientras se mantiene una inferencia rápida en aplicaciones del mundo actual.
Conexiones parciales de etapa cruzada (CSP)
Primero, Wongkinyiu et al. [1] introdujo esta innovación arquitectónica y abordó el problema de la información de gradiente redundante en redes troncales de redes neuronales convolucionales más grandes. Su objetivo principal es enriquecer las interacciones de gradiente al tiempo que scale back el costo computacional. Las conexiones parciales de etapa cruzada (CSP) conservan la diversidad de gradiente combinando mapas de características tanto del principio como del last de cada etapa de crimson: 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 pasa por alto esta ruta y se conecta directamente a la siguiente etapa. Esta arquitectura está diseñada para abordar múltiples problemas, incluida la mejora de la capacidad de aprendizaje de la CNN, eliminar los cuellos de botella computacionales y reducir los costos de memoria.
CSP-Densenet mantiene los beneficios de reutilización de características de Densenet al tiempo que scale back la información de gradiente duplicada al podar el flujo de gradiente, logrado a través de una estrategia de fusión de características jerárquicas en una capa de transición parcial.
Según los experimentos de los autores, este enfoque scale back el cálculo en un 20% al tiempo que logran una precisión equivalente o incluso superior en el conjunto de datos de ImageNet.
C3
Yolov4 y Yolov5 usan el módulo parcial de la etapa cruzada (CSP) para mejorar la extracción de características en el cuello de botella. El bloque C3 es una implementación práctica de esta arquitectura CSP en Ultraalítico Modelos de yolo.
En el bloque C3, los mapas de características de entrada se dividen en dos partes. Una parte se procesa por una convolución 1 × 1 seguida de norte Bloques de cuello de botella paralelos, mientras que la otra parte pasa a través de una convolución 1 × 1 separada y omite los cuellos de botella por completo. Estas dos ramas se concatenan a lo largo de la dimensión del canal y se fusionan con otra convolución 1 × 1 para producir la salida.
Enter (x)
│
┌────────┴─────────┐
│ │
[1x1 Conv] [1x1 Conv]
(cv1) (cv2)
│ │
[Bottlenecks] │
(m: n blocks) │
│ │
└────────┬─────────┘
│
[Concat along C]
│
[1x1 Conv → cv3]
│
Output
con implementación ultraalítica (enlace 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): Enter channels.
c2 (int): Output channels.
n (int): Variety of Bottleneck blocks.
shortcut (bool): Whether or not to make use of shortcut connections.
g (int): Teams for convolutions.
e (float): Growth ratio.
"""
tremendous().__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, ok=((1, 1), (3, 3)), e=1.0) for _ in vary(n)))
def ahead(self, x: torch.Tensor) -> torch.Tensor:
"""Ahead cross by means of the CSP bottleneck with 3 convolutions."""
return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))
Etapa cruzada parcial con conexiones 2F (C2F)
El bloque C2F se basa en CSPNet, extendiéndolo aún más: en lugar de una sola ruta 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. Esta concept, que apareció por primera vez en Yolov7 y Yolov8 [2][3]sigue los mismos principios que CSP al dividir el mapa de características de entrada para reducir la redundancia computacional y mejorar la reutilización de características.
En un bloque C2F, el tensor de entrada se divide en dos caminos: uno omite las capas del cuello de botella como un atajo, mientras que el otro pasa a través de múltiples capas de cuello de botella. A diferencia del CSP unique, que usa solo la salida last del cuello de botella, C2F reúne todas las salidas de cuello de botella intermedios y las concatena, aumentando la diversidad y la representación de características. Esta estrategia de fusión de doble función (2F) también ayuda a la crimson a manejar mejor la oclusión, lo que hace que las detecciones sean más robustas en escenas desafiantes.
Implementación ultraalítica (enlace GitHub):
class C2f(nn.Module):
"""Quicker 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): Enter channels.
c2 (int): Output channels.
n (int): Variety of Bottleneck blocks.
shortcut (bool): Whether or not to make use of shortcut connections.
g (int): Teams for convolutions.
e (float): Growth ratio.
"""
tremendous().__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) # non-obligatory act=FReLU(c2)
self.m = nn.ModuleList(Bottleneck(self.c, self.c, shortcut, g, ok=((3, 3), (3, 3)), e=1.0) for _ in vary(n))
def ahead(self, x: torch.Tensor) -> torch.Tensor:
"""Ahead cross by means of C2f layer."""
y = record(self.cv1(x).chunk(2, 1))
y.prolong(m(y[-1]) for m in self.m)
return self.cv2(torch.cat(y, 1))
def forward_split(self, x: torch.Tensor) -> torch.Tensor:
"""Ahead cross utilizing break up() as a substitute of chunk()."""
y = self.cv1(x).break up((self.c, self.c), 1)
y = [y[0], y[1]]
y.prolong(m(y[-1]) for m in self.m)
return self.cv2(torch.cat(y, 1))
Ambiente cruzado parcial con bloque de tamaño de núcleo 2 (C3K2)
Yolov11 [4] Utiliza los siguientes bloques C3K2 en la cabeza para la extracción de características en varias etapas de su columna vertebral para procesar las características múltiples, otra evolución del clásico cuello de botella CSP. El bloque C3K2 divide el mapa de características y lo procesa con múltiples convoluciones livianas 3 × 3, fusionando los resultados posteriormente. Esto mejora el flujo de información mientras permanece más compacto que un cuello de botella CSP completo, reduciendo el número de parámetros capacitables.
El bloque C3K mantiene la misma estructura básica que C2F pero no divide la salida después de la convolución inicial. En su lugar, ejecuta la entrada a través de norte Capas de cuello de botella con concatenaciones intermedias, que terminan con una convolución last 1 × 1. A diferencia de C2F, C3K agrega flexibilidad con los tamaños de núcleo personalizables, lo que ayuda al modelo a capturar mejor los detalles finos a diferentes escalas de objetos.
Sobre la base de esta concept, C3K2 reemplaza los cuellos de botella lisos con múltiples bloques C3K. Comienza con un bloque de convivir, apila varios bloques C3K en secuencia, concatena sus salidas con la entrada unique y termina con otra capa de convivir, combinando el concepto de fusión dividida de CSP con núcleos flexibles para equilibrar la velocidad, la eficiencia de los parámetros y la extracción de características a escala múltiple más rica.
Enter: [Batch, c1, H, W]
│
[cv1] (1x1 Conv) → splits channels into 2c
│
┌─────────────┐
│ │
Department 1 Department 2
(Bypass) (Bottleneck chain)
│ │
├─> C3k Block #1
│
├─> C3k Block #2
│
... (n instances)
│
└─────────────┬─────────────┐
Concatenate [Bypass, Split, C3k outputs]
│
[cv2] (1x1 Conv)
│
Output: [Batch, c2, H, W]
Cada bloque C3K utiliza cuellos de botella paralelos con núcleos personalizados, proporcionando más flexibilidad para la extracción de características y permitiendo que el modelo se adapte mejor a los patrones complejos.
C3k Enter: [Batch, c, H, W]
│
[cv1] (1x1 Conv, broaden/break up)
│
┌───────────────┐
│ │
ByPass Bottleneck blocks
│ ┌─────────────┐
│ B1, B2, ...Bn (parallel)
└─────────────┘
└───────────────┬───────┘
Concatenate
│
[cv2] (1x1 Conv)
│
C3k Output: [Batch, c, H, W]
Implementación ultraalítica (enlace GitHub):
class C3k(C3):
"""C3k is a CSP bottleneck module with customizable kernel sizes for function extraction in neural networks."""
def __init__(self, c1: int, c2: int, n: int = 1, shortcut: bool = True, g: int = 1, e: float = 0.5, ok: int = 3):
"""
Initialize C3k module.
Args:
c1 (int): Enter channels.
c2 (int): Output channels.
n (int): Variety of Bottleneck blocks.
shortcut (bool): Whether or not to make use of shortcut connections.
g (int): Teams for convolutions.
e (float): Growth ratio.
ok (int): Kernel dimension.
"""
tremendous().__init__(c1, c2, n, shortcut, g, e)
c_ = int(c2 * e) # hidden channels
# self.m = nn.Sequential(*(RepBottleneck(c_, c_, shortcut, g, ok=(ok, ok), e=1.0) for _ in vary(n)))
self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, ok=(ok, ok), e=1.0) for _ in vary(n)))
class C3k2(C2f):
"""Quicker 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): Enter channels.
c2 (int): Output channels.
n (int): Variety of blocks.
c3k (bool): Whether or not to make use of C3k blocks.
e (float): Growth ratio.
g (int): Teams for convolutions.
shortcut (bool): Whether or not to make use of shortcut connections.
"""
tremendous().__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 vary(n)
)
Conclusión
En resumen, las arquitecturas de yolo modernas siguen evolucionando al agregar bloques como C3, C2F, C3K y C3K2, todas construidas alrededor de la concept central de las conexiones parciales (CSP) de etapa cruzada. Este enfoque CSP scale back el cálculo y aumenta la representación de las características al mismo tiempo.
Bloquear |
Estructura exterior |
Estructura interna |
Flexibilidad del núcleo |
---|---|---|---|
C3 |
Cuellos de botella paralelos |
Cuellos de botella |
Núcleos fijos |
C2F |
Cuellos de botella en serie |
Cuellos de botella |
Núcleos fijos |
C3K |
Cuellos de botella paralelos |
Cuellos de botella |
Núcleos personalizados |
C3K2 |
Bloques C3K en serie |
Cada C3K tiene cuellos de botella paralelos |
Núcleos personalizados |
Estas refinamientos arquitectónicos ayudan colectivamente a los modelos YOLO a mantener una alta precisión de detección mientras permanecen lo suficientemente rápidos y livianos para la implementación en tiempo actual, una ventaja crítica para varias aplicaciones