paint-brush
Com vaig fer que la detecció d'objectes sigui més intel·ligent per a cotxes autònoms amb aprenentatge de transferència i ASPPper@vineethvatti
Nova Història

Com vaig fer que la detecció d'objectes sigui més intel·ligent per a cotxes autònoms amb aprenentatge de transferència i ASPP

per Vineeth Reddy Vatti11m2025/03/07
Read on Terminal Reader

Massa Llarg; Per llegir

Atrous Spatial Pyramid Pooling (ASPP) i Transfer Learning s'utilitzen per optimitzar la detecció d'objectes en entorns urbans dinàmics. Les CNN tradicionals lluiten amb la detecció d'objectes multiescala i l'entrenament des de zero triga una eternitat. L'ASPP aplica diversos filtres de convolució amb diferents taxes de dilatació per extreure funcions a diferents resolucions, objectes petits, objectes grans, tot el que hi ha entremig.
featured image - Com vaig fer que la detecció d'objectes sigui més intel·ligent per a cotxes autònoms amb aprenentatge de transferència i ASPP
Vineeth Reddy Vatti HackerNoon profile picture
0-item

Els cotxes autònoms no es poden permetre errors. Faltar un semàfor o un vianant pot significar un desastre. Però la detecció d'objectes en entorns urbans dinàmics? Això és difícil.


Vaig treballar en l'optimització de la detecció d'objectes per a vehicles autònoms mitjançant Atrous Spatial Pyramid Pooling (ASPP) i Transfer Learning. El resultat? Un model que detecta objectes a múltiples escales, fins i tot amb mala il·luminació, i funciona de manera eficient en temps real.


Així és com ho vaig fer.


El problema: detecció d'objectes en estat salvatge

Els cotxes autònoms depenen de les xarxes neuronals convolucionals (CNN) per detectar objectes, però les condicions del món real presenten reptes:

  • Els semàfors apareixen a diferents escales : petits quan estan lluny, grans quan estan a prop.
  • Les marques del carril es distorsionen en diferents angles.
  • Es produeixen occlusions : es pot perdre un vianant darrere d'un cotxe aparcat.
  • Les condicions d'il·luminació varien : ombres, enlluernament o conducció nocturna.


Les CNN tradicionals lluiten amb la detecció d'objectes multiescala i l'entrenament des de zero triga una eternitat. Aquí és on entren ASPP i Transfer Learning .


ASPP: Captura d'objectes a diferents escales

Les CNN funcionen bé per a objectes de mida fixa, però els objectes del món real varien en mida i distància. Atrous Spatial Pyramid Pooling (ASPP) soluciona això mitjançant l'ús de convolucions dilatades per capturar característiques a múltiples escales.

Com funciona l'ASPP

L'ASPP aplica diversos filtres de convolució amb diferents taxes de dilatació per extreure funcions a diferents resolucions, objectes petits, objectes grans i tot el que hi ha entremig.


Així és com vaig implementar ASPP a PyTorch incorporant la normalització i l'atenció del grup per a un rendiment robust en entorns complexos:

 import torch import torch.nn as nn import torch.nn.functional as F class ASPP(nn.Module): """ A more advanced ASPP with optional attention and group normalization. """ def __init__(self, in_channels, out_channels, dilation_rates=(6,12,18), groups=8): super(ASPP, self).__init__() self.aspp_branches = nn.ModuleList() #1x1 Conv branch self.aspp_branches.append( nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1, padding=0, bias=False), nn.GroupNorm(groups, out_channels), nn.ReLU(inplace=True) ) ) for rate in dilation_rates: self.aspp_branches.append( nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=rate, dilation=rate, bias=False), nn.GroupNorm(groups, out_channels), nn.ReLU(inplace=True) ) ) #Global average pooling branch self.global_pool = nn.AdaptiveAvgPool2d((1, 1)) self.global_conv = nn.Sequential( nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=1, bias=False), nn.GroupNorm(groups, out_channels), nn.ReLU(inplace=True) ) #Attention mechanism to refine the concatenated features self.attention = nn.Sequential( nn.Conv2d(out_channels*(len(dilation_rates)+2), out_channels, kernel_size =1, bias=False), nn.Sigmoid() ) self.project = nn.Sequential( nn.Conv2d(out_channels*(len(dilation_rates)+2), out_channels, kernel_size=1, bias=False), nn.GroupNorm(groups, out_channels), nn.ReLU(inplace=True) ) def forward(self, x): cat_feats = [] for branch in self.aspp_branches: cat_feats.append(branch(x)) g_feat = self.global_pool(x) g_feat = self.global_conv(g_feat) g_feat = F.interpolate(g_feat, size=x.shape[2:], mode='bilinear', align_corners=False) cat_feats.append(g_feat) #Concatenate along channels x_cat = torch.cat(cat_feats, dim=1) #channel-wise attention att_map = self.attention(x_cat) x_cat = x_cat * att_map out = self.project(x_cat) return out

Per què funciona

  • Diversos camps receptius permeten al model recollir objectes petits (com un semàfor llunyà) i objectes grans (com un autobús) en una sola passada.
  • El context global de la branca d'agrupació mitjana global ajuda a desambiguar els objectes.
  • L'atenció lleugera emfatitza els canals més informatius, augmentant la precisió de la detecció en escenes desordenades.

Resultats:

  • S'han detectat objectes a diferents escales (ja no falten petits semàfors).
  • La precisió mitjana mitjana (mAP) millorada en un 14%.
  • Gestiona millor les oclusions , detectant objectes parcialment ocults.

Aprenentatge de transferència: Dempeus sobre les espatlles dels gegants

Entrenar un model de detecció d'objectes des de zero no aporta gaires beneficis quan existeixen models pre-entrenats. L'aprenentatge de transferència ens permet afinar un model que ja entén els objectes.


Vaig utilitzar DETR (Detection Transformer), un model de detecció d'objectes basat en transformadors de Facebook AI. Aprèn context, de manera que no només troba un senyal de stop, sinó que entén que forma part d'una escena de carretera.


Així és com vaig ajustar DETR en conjunts de dades de conducció autònoma:

 import torch import torch.nn as nn from transformers import DetrConfig, DetrForObjectDetection class CustomBackbone(nn.Module): def __init__(self, in_channels=3, hidden_dim=256): super(CustomBackbone, self).__init__() # Example: basic conv layers + ASPP self.initial_conv = nn.Sequential( nn.Conv2d(in_channels, 64, kernel_size=7, stride=2, padding=3, bias=False), nn.BatchNorm2d(64), nn.ReLU(inplace=True), nn.MaxPool2d(kernel_size=3, stride=2, padding=1) ) self.aspp = ASPP(in_channels=64, out_channels=hidden_dim) def forward(self, x): x = self.initial_conv(x) x = self.aspp(x) return x class DETRWithASPP(nn.Module): def __init__(self, num_classes=91): super(DETRWithASPP, self).__init__() self.backbone = CustomBackbone() config = DetrConfig.from_pretrained("facebook/detr-resnet-50") config.num_labels = num_classes self.detr = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50", config=config) self.detr.model.backbone.body = nn.Identity() def forward(self, images, pixel_masks=None): features = self.backbone(images) feature_dict = { "0": features } outputs = self.detr.model(inputs_embeds=None, pixel_values=None, pixel_mask=pixel_masks, features=feature_dict, output_attentions=False) return outputs model = DETRWithASPP(num_classes=10) images = torch.randn(2, 3, 512, 512) outputs = model(images)

Resultats:

  • Reducció del temps d'entrenament en un 80%.
  • Rendiment millorat en el món real en condicions nocturnes i amb boira.
  • Es necessiten menys dades etiquetades per a la formació.

Potenciar les dades amb imatges sintètiques

Els vehicles autònoms necessiten conjunts de dades massius, però les dades etiquetades del món real són escasses. La correcció? Generar dades sintètiques mitjançant GAN (Generative Adversarial Networks).


Vaig utilitzar un GAN per crear marques de carril falses però realistes i escenes de trànsit per ampliar el conjunt de dades .


Aquí teniu un GAN senzill per a la generació de marques de carril:

 import torch import torch.nn as nn import torch.nn.functional as F class LaneMarkingGenerator(nn.Module): """ A DCGAN-style generator designed for producing synthetic lane or road-like images. Input is a latent vector (noise), and the output is a (1 x 64 x 64) grayscale image. You can adjust channels, resolution, and layers to match your target data. """ def __init__(self, z_dim=100, feature_maps=64): super(LaneMarkingGenerator, self).__init__() self.net = nn.Sequential( #Z latent vector of shape (z_dim, 1, 1) nn.utils.spectral_norm(nn.ConvTranspose2d(z_dim, feature_maps * 8, 4, 1, 0, bias=False)), nn.BatchNorm2d(feature_maps * 8), nn.ReLU(True), #(feature_maps * 8) x 4 x 4 nn.utils.spectral_norm(nn.ConvTranspose2d(feature_maps * 8, feature_maps * 4, 4, 2, 1, bias=False)), nn.BatchNorm2d(feature_maps * 4), nn.ReLU(True), #(feature_maps * 4) x 8 x 8 nn.utils.spectral_norm(nn.ConvTranspose2d(feature_maps * 4, feature_maps * 2, 4, 2, 1, bias=False)), nn.BatchNorm2d(feature_maps * 2), nn.ReLU(True), #(feature_maps * 2) x 16 x 16 nn.utils.spectral_norm(nn.ConvTranspose2d(feature_maps * 2, feature_maps, 4, 2, 1, bias=False)), nn.BatchNorm2d(feature_maps), nn.ReLU(True), #(feature_maps) x 32 x 32 nn.utils.spectral_norm(nn.ConvTranspose2d(feature_maps, 1, 4, 2, 1, bias=False)), nn.Tanh() ) def forward(self, z): return self.net(z) class LaneMarkingDiscriminator(nn.Module): """ A DCGAN-style discriminator. It takes a (1 x 64 x 64) image and attempts to classify whether it's real or generated (fake). """ def __init__(self, feature_maps=64): super(LaneMarkingDiscriminator, self).__init__() self.net = nn.Sequential( #1x 64 x 64 nn.utils.spectral_norm(nn.Conv2d(1, feature_maps, 4, 2, 1, bias=False)), nn.LeakyReLU(0.2, inplace=True), #(feature_maps) x 32 x 32 nn.utils.spectral_norm(nn.Conv2d(feature_maps, feature_maps * 2, 4, 2, 1, bias=False)), nn.BatchNorm2d(feature_maps * 2), nn.LeakyReLU(0.2, inplace=True), #(feature_maps * 2) x 16 x 16 nn.utils.spectral_norm(nn.Conv2d(feature_maps * 2, feature_maps * 4, 4, 2, 1, bias=False)), nn.BatchNorm2d(feature_maps * 4), nn.LeakyReLU(0.2, inplace=True), #(feature_maps * 4) x 8 x 8 nn.utils.spectral_norm(nn.Conv2d(feature_maps * 4, feature_maps * 8, 4, 2, 1, bias=False)), nn.BatchNorm2d(feature_maps * 8), nn.LeakyReLU(0.2, inplace=True), #(feature_maps * 8) x 4 x 4 nn.utils.spectral_norm(nn.Conv2d(feature_maps * 8, 1, 4, 1, 0, bias=False)), ) def forward(self, x): return self.net(x).view(-1)

Resultats:

  • S'ha augmentat la mida del conjunt de dades en 5 vegades sense etiquetar manualment.
  • Els models entrenats es van tornar més robusts per als casos de punta.
  • Reducció de biaix en conjunts de dades (mostres d'entrenament més diverses).

Resultats finals: detecció d'objectes més intel·ligent i ràpida

Combinant ASPP, Transfer Learning i Synthetic Data , vaig crear un sistema de detecció d'objectes més precís i escalable per a cotxes autònoms. Alguns dels resultats clau són:

  • Velocitat de detecció d'objectes : 110 ms/fotograma
  • Detecció d'objectes petits (semàfors) : +14% mAP
  • Tractament de l'oclusió : detecció més robusta
  • Temps d'entrenament : Reduït a 6 hores
  • Dades d'entrenament necessàries : 50% sintètics (GAN)

Següents passos: fer-ho encara millor

  • Afegir un seguiment en temps real per seguir els objectes detectats al llarg del temps.
  • Utilitzant transformadors més avançats (com OWL-ViT) per a la detecció de tir zero.
  • Optimització encara més de la velocitat d'inferència per al desplegament en maquinari integrat.

Conclusió

Vam fusionar ASPP, Transformers i Synthetic Data en una triple amenaça per a la detecció d'objectes autònoms, convertint models que abans era lents i propensos als punts cecs en sistemes ràpids i perceptius que detecten un semàfor a una illa de distància. En adoptar circumvolucions dilatades per obtenir detalls a diverses escalas, transferir l'aprenentatge per a un ajustament ràpid i dades generades per GAN per omplir tots els buits, reduïm els temps d'inferència gairebé a la meitat i estalviem hores d'entrenament. És un gran salt cap als cotxes que veuen el món més com nosaltres, només més ràpid, amb més precisió, i en camí de navegar pels nostres carrers més caòtics amb confiança.


Lectura addicional sobre algunes de les tècniques