feat: initial HSAP platform
Huaxu Sentinel Active Safety Platform with embedded algorithm code, Docker Compose setup, and vendored dataset scaffolds for clone-and-run. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
import torch
|
||||
|
||||
|
||||
def build_optimizer(cfg, net):
|
||||
params = []
|
||||
cfg_cp = cfg.optimizer.copy()
|
||||
cfg_type = cfg_cp.pop('type')
|
||||
|
||||
if cfg_type not in dir(torch.optim):
|
||||
raise ValueError("{} is not defined.".format(cfg_type))
|
||||
|
||||
_optim = getattr(torch.optim, cfg_type)
|
||||
return _optim(net.parameters(), **cfg_cp)
|
||||
@@ -0,0 +1,22 @@
|
||||
from clrnet.utils import Registry, build_from_cfg
|
||||
|
||||
TRAINER = Registry('trainer')
|
||||
EVALUATOR = Registry('evaluator')
|
||||
|
||||
|
||||
def build(cfg, registry, default_args=None):
|
||||
if isinstance(cfg, list):
|
||||
modules = [
|
||||
build_from_cfg(cfg_, registry, default_args) for cfg_ in cfg
|
||||
]
|
||||
return nn.Sequential(*modules)
|
||||
else:
|
||||
return build_from_cfg(cfg, registry, default_args)
|
||||
|
||||
|
||||
def build_trainer(cfg):
|
||||
return build(cfg.trainer, TRAINER, default_args=dict(cfg=cfg))
|
||||
|
||||
|
||||
def build_evaluator(cfg):
|
||||
return build(cfg.evaluator, EVALUATOR, default_args=dict(cfg=cfg))
|
||||
148
algorithms/lane_ufld/code/CLRNet-main/clrnet/engine/runner.py
Normal file
148
algorithms/lane_ufld/code/CLRNet-main/clrnet/engine/runner.py
Normal file
@@ -0,0 +1,148 @@
|
||||
import time
|
||||
import cv2
|
||||
import torch
|
||||
from tqdm import tqdm
|
||||
import pytorch_warmup as warmup
|
||||
import numpy as np
|
||||
import random
|
||||
import os
|
||||
|
||||
from clrnet.models.registry import build_net
|
||||
from .registry import build_trainer, build_evaluator
|
||||
from .optimizer import build_optimizer
|
||||
from .scheduler import build_scheduler
|
||||
from clrnet.datasets import build_dataloader
|
||||
from clrnet.utils.recorder import build_recorder
|
||||
from clrnet.utils.net_utils import save_model, load_network, resume_network
|
||||
from mmcv.parallel import MMDataParallel
|
||||
|
||||
|
||||
class Runner(object):
|
||||
def __init__(self, cfg):
|
||||
torch.manual_seed(cfg.seed)
|
||||
np.random.seed(cfg.seed)
|
||||
random.seed(cfg.seed)
|
||||
self.cfg = cfg
|
||||
self.recorder = build_recorder(self.cfg)
|
||||
self.net = build_net(self.cfg)
|
||||
self.net = MMDataParallel(self.net,
|
||||
device_ids=range(self.cfg.gpus)).cuda()
|
||||
self.recorder.logger.info('Network: \n' + str(self.net))
|
||||
self.resume()
|
||||
self.optimizer = build_optimizer(self.cfg, self.net)
|
||||
self.scheduler = build_scheduler(self.cfg, self.optimizer)
|
||||
self.metric = 0.
|
||||
self.val_loader = None
|
||||
self.test_loader = None
|
||||
|
||||
def to_cuda(self, batch):
|
||||
for k in batch:
|
||||
if not isinstance(batch[k], torch.Tensor):
|
||||
continue
|
||||
batch[k] = batch[k].cuda()
|
||||
return batch
|
||||
|
||||
def resume(self):
|
||||
if not self.cfg.load_from and not self.cfg.finetune_from:
|
||||
return
|
||||
load_network(self.net, self.cfg.load_from, finetune_from=self.cfg.finetune_from, logger=self.recorder.logger)
|
||||
|
||||
def train_epoch(self, epoch, train_loader):
|
||||
self.net.train()
|
||||
end = time.time()
|
||||
max_iter = len(train_loader)
|
||||
for i, data in enumerate(train_loader):
|
||||
if self.recorder.step >= self.cfg.total_iter:
|
||||
break
|
||||
date_time = time.time() - end
|
||||
self.recorder.step += 1
|
||||
data = self.to_cuda(data)
|
||||
output = self.net(data)
|
||||
self.optimizer.zero_grad()
|
||||
loss = output['loss'].sum()
|
||||
loss.backward()
|
||||
self.optimizer.step()
|
||||
if not self.cfg.lr_update_by_epoch:
|
||||
self.scheduler.step()
|
||||
batch_time = time.time() - end
|
||||
end = time.time()
|
||||
self.recorder.update_loss_stats(output['loss_stats'])
|
||||
self.recorder.batch_time.update(batch_time)
|
||||
self.recorder.data_time.update(date_time)
|
||||
|
||||
if i % self.cfg.log_interval == 0 or i == max_iter - 1:
|
||||
lr = self.optimizer.param_groups[0]['lr']
|
||||
self.recorder.lr = lr
|
||||
self.recorder.record('train')
|
||||
|
||||
def train(self):
|
||||
self.recorder.logger.info('Build train loader...')
|
||||
train_loader = build_dataloader(self.cfg.dataset.train,
|
||||
self.cfg,
|
||||
is_train=True)
|
||||
|
||||
self.recorder.logger.info('Start training...')
|
||||
start_epoch = 0
|
||||
if self.cfg.resume_from:
|
||||
start_epoch = resume_network(self.cfg.resume_from, self.net,
|
||||
self.optimizer, self.scheduler,
|
||||
self.recorder)
|
||||
for epoch in range(start_epoch, self.cfg.epochs):
|
||||
self.recorder.epoch = epoch
|
||||
self.train_epoch(epoch, train_loader)
|
||||
if (epoch +
|
||||
1) % self.cfg.save_ep == 0 or epoch == self.cfg.epochs - 1:
|
||||
self.save_ckpt()
|
||||
if (epoch +
|
||||
1) % self.cfg.eval_ep == 0 or epoch == self.cfg.epochs - 1:
|
||||
self.validate()
|
||||
if self.recorder.step >= self.cfg.total_iter:
|
||||
break
|
||||
if self.cfg.lr_update_by_epoch:
|
||||
self.scheduler.step()
|
||||
|
||||
|
||||
def test(self):
|
||||
if not self.test_loader:
|
||||
self.test_loader = build_dataloader(self.cfg.dataset.test,
|
||||
self.cfg,
|
||||
is_train=False)
|
||||
self.net.eval()
|
||||
predictions = []
|
||||
for i, data in enumerate(tqdm(self.test_loader, desc=f'Testing')):
|
||||
data = self.to_cuda(data)
|
||||
with torch.no_grad():
|
||||
output = self.net(data)
|
||||
output = self.net.module.heads.get_lanes(output)
|
||||
predictions.extend(output)
|
||||
if self.cfg.view:
|
||||
self.test_loader.dataset.view(output, data['meta'])
|
||||
|
||||
metric = self.test_loader.dataset.evaluate(predictions,
|
||||
self.cfg.work_dir)
|
||||
if metric is not None:
|
||||
self.recorder.logger.info('metric: ' + str(metric))
|
||||
|
||||
def validate(self):
|
||||
if not self.val_loader:
|
||||
self.val_loader = build_dataloader(self.cfg.dataset.val,
|
||||
self.cfg,
|
||||
is_train=False)
|
||||
self.net.eval()
|
||||
predictions = []
|
||||
for i, data in enumerate(tqdm(self.val_loader, desc=f'Validate')):
|
||||
data = self.to_cuda(data)
|
||||
with torch.no_grad():
|
||||
output = self.net(data)
|
||||
output = self.net.module.heads.get_lanes(output)
|
||||
predictions.extend(output)
|
||||
if self.cfg.view:
|
||||
self.val_loader.dataset.view(output, data['meta'])
|
||||
|
||||
metric = self.val_loader.dataset.evaluate(predictions,
|
||||
self.cfg.work_dir)
|
||||
self.recorder.logger.info('metric: ' + str(metric))
|
||||
|
||||
def save_ckpt(self, is_best=False):
|
||||
save_model(self.net, self.optimizer, self.scheduler, self.recorder,
|
||||
is_best)
|
||||
@@ -0,0 +1,15 @@
|
||||
import torch
|
||||
import math
|
||||
|
||||
|
||||
def build_scheduler(cfg, optimizer):
|
||||
|
||||
cfg_cp = cfg.scheduler.copy()
|
||||
cfg_type = cfg_cp.pop('type')
|
||||
|
||||
if cfg_type not in dir(torch.optim.lr_scheduler):
|
||||
raise ValueError("{} is not defined.".format(cfg_type))
|
||||
|
||||
_scheduler = getattr(torch.optim.lr_scheduler, cfg_type)
|
||||
|
||||
return _scheduler(optimizer, **cfg_cp)
|
||||
Reference in New Issue
Block a user