Spaces:
Sleeping
Sleeping
Download models/bev_encoder.py from dheepakkaran/multi-camera-bev: direct link, hf CLI and curl.
- Browser
- Download file 4.65 kB
-
https://huggingface.co/spaces/dheepakkaran/multi-camera-bev/resolve/main/models/bev_encoder.py
- Command line
-
hf download hf://spaces/dheepakkaran/multi-camera-bev/models/bev_encoder.py
-
curl -L -o bev_encoder.py https://huggingface.co/spaces/dheepakkaran/multi-camera-bev/resolve/main/models/bev_encoder.py
4.65 kB
| # ============================================================ | |
| # bev_encoder.py | |
| # ============================================================ | |
| # | |
| # ETHUKU CREATE PANNINOM? | |
| # ββββββββββββββββββββββ | |
| # LSS kuduthathu "raw" BEV - just camera features-ai kotti vachathu. | |
| # Antha map-la neighbour cells-ku thodarbu (context) illa. | |
| # Ithu antha map-ai innum smart-a maathum: "intha 4m neelamana blob = | |
| # oru car", "intha vari = road". | |
| # | |
| # MUNADI FILE ODA CONNECTION: | |
| # ββββββββββββββββββββββββββ | |
| # Input : view_transformer.py output [B,64,200,200] | |
| # Output: center_head.py ku [B,128,200,200] | |
| # | |
| # INNER OPERATIONS: | |
| # ββββββββββββββββ | |
| # ResNet-style downsample (200->100->50) -> aprom upsample thirumba 200. | |
| # Yaen keezha-mela? Downsample panna oru pixel periya area paakkum | |
| # (receptive field). Athu illaina 12m lorry-va oru pixel-la puriya mudiyathu. | |
| # FPN-style: chinna map-ai periya map-oda koottrom (details + context rendum). | |
| # | |
| # INPUT / OUTPUT: | |
| # ββββββββββββββ | |
| # Input : [B, 64, 200, 200] | |
| # Output: [B, 128, 200, 200] | |
| # | |
| # EPADI USE AAGUM: | |
| # βββββββββββββββ | |
| # Detection head-ku rich features kudukka. | |
| # | |
| # ============================================================ | |
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| from data.scripts.constants import BACKBONE_OUT_CHANNELS, BEV_OUT_CHANNELS | |
| class BasicBlock(nn.Module): | |
| """ResNet basic block: conv-bn-relu x2 + skip connection.""" | |
| def __init__(self, in_ch: int, out_ch: int, stride: int = 1): | |
| super().__init__() | |
| self.conv1 = nn.Conv2d(in_ch, out_ch, 3, stride=stride, padding=1, bias=False) | |
| self.bn1 = nn.BatchNorm2d(out_ch) | |
| self.conv2 = nn.Conv2d(out_ch, out_ch, 3, padding=1, bias=False) | |
| self.bn2 = nn.BatchNorm2d(out_ch) | |
| # Skip connection: input-ai output-oda neradiya koottrom. | |
| # Yaen? Deep network-la gradient vanish aagum. Skip = "highway" | |
| # gradient-ku, so training stable. | |
| # Shape match aagalaina 1x1 conv poattu adjust pannurom. | |
| self.shortcut = nn.Identity() | |
| if stride != 1 or in_ch != out_ch: | |
| self.shortcut = nn.Sequential( | |
| nn.Conv2d(in_ch, out_ch, 1, stride=stride, bias=False), | |
| nn.BatchNorm2d(out_ch), | |
| ) | |
| def forward(self, x: torch.Tensor) -> torch.Tensor: | |
| out = F.relu(self.bn1(self.conv1(x)), inplace=True) | |
| out = self.bn2(self.conv2(out)) | |
| return F.relu(out + self.shortcut(x), inplace=True) | |
| class BEVEncoder(nn.Module): | |
| """ResNet-18 style encoder + FPN-style decoder on the BEV map.""" | |
| def __init__(self, in_channels: int = BACKBONE_OUT_CHANNELS, | |
| out_channels: int = BEV_OUT_CHANNELS): | |
| super().__init__() | |
| # --- Encoder (keezha poguthu) --- | |
| self.layer1 = BasicBlock(in_channels, 64, stride=1) # [B,64,200,200] | |
| self.layer2 = BasicBlock(64, 128, stride=2) # [B,128,100,100] | |
| self.layer3 = BasicBlock(128, 256, stride=2) # [B,256,50,50] | |
| # --- Decoder (mela varuthu) --- | |
| # lateral = 1x1 conv, channel count-ai samam pannurathu | |
| self.lat3 = nn.Conv2d(256, out_channels, 1) | |
| self.lat2 = nn.Conv2d(128, out_channels, 1) | |
| self.lat1 = nn.Conv2d(64, out_channels, 1) | |
| # smooth = upsample panna vandha "blocky" artifacts-ai sari pannum | |
| self.smooth = nn.Sequential( | |
| nn.Conv2d(out_channels, out_channels, 3, padding=1, bias=False), | |
| nn.BatchNorm2d(out_channels), | |
| nn.ReLU(inplace=True), | |
| ) | |
| def forward(self, x: torch.Tensor) -> torch.Tensor: | |
| """ | |
| Args: | |
| x: [B, 64, 200, 200] raw BEV from LSS | |
| Returns: | |
| [B, 128, 200, 200] encoded BEV features | |
| """ | |
| c1 = self.layer1(x) # [B, 64, 200, 200] fine details | |
| c2 = self.layer2(c1) # [B,128, 100, 100] medium context | |
| c3 = self.layer3(c2) # [B,256, 50, 50] large context | |
| # Top-down: periya context-ai chinna details-oda koottrom | |
| p3 = self.lat3(c3) # 50x50 | |
| p2 = self.lat2(c2) + F.interpolate(p3, scale_factor=2, mode="bilinear", | |
| align_corners=False) # 100x100 | |
| p1 = self.lat1(c1) + F.interpolate(p2, scale_factor=2, mode="bilinear", | |
| align_corners=False) # 200x200 | |
| return self.smooth(p1) # [B, 128, 200, 200] | |