Loading…
Loading…
Attn-LaneNet is a high-speed, lightweight convolutional neural network designed and trained entirely from scratch (zero pretrained backbones, zero transfer learning) for single-class autonomous lane semantic segmentation.
Developed by Jitrakorn Jansang (นายจิตรกร จันทร์สังข์, Student ID: 6710110055) for Assignment-10: Neural Network From Scratch w/ Custom Dataset (10%) in 2569-241-353 AI Ecosystem, instructed by Dr. Rattachai Wongtanawijit.
AttnLaneNet.from_pretrainedimport torch
from model import AttnLaneNet
# 1. Download & load weights directly from Hugging Face Hub
model = AttnLaneNet.from_pretrained("kim2548TH/attn-lanenet-lane-segmentation")
# 2. Forward pass with input (B, 3, 36, 64)
dummy_input = torch.randn(1, 3, 36, 64)
with torch.no_grad():
pred_mask = (torch.sigmoid(model(dummy_input)) > 0.5).float()
print("Prediction shape:", pred_mask.shape) # torch.Size([1, 1, 36, 64])
import torch
import importlib.util
from huggingface_hub import hf_hub_download
# Download code & weights
py_file = hf_hub_download("kim2548TH/attn-lanenet-lane-segmentation", "model.py")
weights_file = hf_hub_download("kim2548TH/attn-lanenet-lane-segmentation", "attn_lanenet_weights.pt")
# Dynamic import
spec = importlib.util.spec_from_file_location("attn_model", py_file)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
# Instantiate & Load
model = mod.AttnLaneNet()
model.load_state_dict(torch.load(weights_file, map_location="cpu"))
model.eval()
# Predict on (B=1, C=3, H=36, W=64)
dummy_input = torch.randn(1, 3, 36, 64)
output_logits = model(dummy_input)
print("Output logits:", output_logits.shape)
Attn-LaneNet is built with strict adherence to real-time embedded edge deployment requirements:
graph TD
In["Input Tensor: 64x36x3 (RGB)"] --> Stem["Stem Conv + ResBlock (32ch, 64x36)"]
Stem --> Down1["MaxPool (2x) + 2x ResBlock-SE (64ch, 32x18)"]
Down1 --> Down2["MaxPool (2x) + 2x ResBlock-SE (128ch, 16x9)"]
Down2 --> Bot["Bottleneck + Dilated Context (d=1,2,4) (256ch, 16x9)"]
Bot --> Up1["Bilinear Upsample (2x) + Skip Fusion (64ch, 32x18)"]
Down1 -.->|Skip Connection| Up1
Up1 --> Up2["Bilinear Upsample (2x) + Skip Fusion (32ch, 64x36)"]
Stem -.->|Skip Connection| Up2
Up2 --> Head["Conv 1x1 Segmentation Head (1ch, 64x36)"]
Head --> Out["Binary Lane Logits / Mask (64x36x1)"]
Evaluated across all 350 unseen test frames (35% split) from the PSU Reservoir Lane Dataset:
| Metric | Target / Standard | Attn-LaneNet Performance |
|---|---|---|
| Detection Rate ($\text{IoU} \ge 0.60$) | Baseline Requirement | 99.71% (349 / 350 frames) |
| Mean IoU (All 350 Frames) | — | 91.97% |
| Mean IoU (Positive Detections) | $\ge 60.0%$ | 92.08% |
| Mean Precision | — | 94.68% |
| Mean Recall | — | 96.98% |
| Mean F1-Score | — | 95.76% |
| Max IoU | — | 94.30% |
| Inference Latency | Local Machine | 3.65 ms / frame |
| Throughput | Real-time ($\ge 30$ FPS) | 274.3 FPS (Apple Silicon MPS) / 226+ FPS |
| RAM Footprint (Process Peak) | Local Laptop/PC | ~307.7 MB |
Trained for 35 epochs using Hybrid BCE + Soft Dice Loss with AdamW and Cosine Annealing:
Qualitative 4-panel visual verification on test frame:
Panel Description: (1) Original Raw Image, (2) Ground Truth YOLO Polygon Annotation, (3) Predicted Binary Lane Mask (Upscaled $1280 \times 720$), (4) Qualitative Overlay (Green=Prediction, Red=Ground Truth, Yellow=Accurate Overlap).
model.safetensors (3.6 MB) - SafeTensors binary formatattn_lanenet_weights.pt (3.6 MB) - PyTorch state dict formatpytorch_model.bin (3.6 MB) - Standard Hugging Face PyTorch binary formatconfig.json - Architecture & metadata configurationmodel.py - Complete standalone PyTorch network definitionThe accompanying dataset with 1,000 frames (650 train / 350 test) annotated with YOLO Class 0 polygons is hosted on Hugging Face:
👉 https://huggingface.co/datasets/kim2548TH/psu-reservoir-lane-dataset