We basically categorize model components into 5 types.
- tracker: the component that associate the objects across the video with the cues extracted by the components below.
- detector: usually a detector to detect objects from the input image, e.g., Faster R-CNN.
- motion: the component to compute motion information between consecutive frames, e.g., KalmanFilter.
- reid: usually an independent ReID model to extract the feature embeddings from the cropped image, e.g., BaseReID.
- track_head: the component to extract tracking cues but share the same backbone with the detector, e.g., a embedding head or a regression head.
Create a new file mmtrack/models/mot/trackers/my_tracker.py.
We implement a BaseTracker that provide basic APIs to maintain the tracks across the video.
We recommend to inherit the new tracker from it.
The users may refer to the documentations of BaseTracker for the details.
from mmtrack.models import TRACKERS
from .base_tracker import BaseTracker
@TRACKERS.register_module()
class MyTracker(BaseTracker):
def __init__(self,
arg1,
arg2,
*args,
**kwargs):
super().__init__(*args, **kwargs)
pass
def track(self, inputs):
# implementation is ignored
passYou can either add the following line to mmtrack/models/mot/trackers/__init__.py,
from .my_tracker import MyTrackeror alternatively add
custom_imports = dict(
imports=['mmtrack.models.mot.trackers.my_tracker.py'],
allow_failed_imports=False)to the config file and avoid modifying the original code.
tracker=dict(
type='MyTracker',
arg1=xxx,
arg2=xxx)Please refer to tutorial in mmdetection for developping a new detector.
Create a new file mmtrack/models/motion/my_flownet.py.
You can inherit the motion model from BaseModule in mmcv.runner if it is a deep learning module, and from object if not.
from mmcv.runner import BaseModule
from ..builder import MOTION
@MOTION.register_module()
class MyFlowNet(BaseModule):
def __init__(self,
arg1,
arg2):
pass
def forward(self, inputs):
# implementation is ignored
passYou can either add the following line to mmtrack/models/motion/__init__.py,
from .my_flownet import MyFlowNetor alternatively add
custom_imports = dict(
imports=['mmtrack.models.motion.my_flownet.py'],
allow_failed_imports=False)to the config file and avoid modifying the original code.
motion=dict(
type='MyFlowNet',
arg1=xxx,
arg2=xxx)Create a new file mmtrack/models/reid/my_reid.py.
from mmcv.runner import BaseModule
from ..builder import REID
@REID.register_module()
class MyReID(BaseModule):
def __init__(self,
arg1,
arg2):
pass
def forward(self, inputs):
# implementation is ignored
passYou can either add the following line to mmtrack/models/reid/__init__.py,
from .my_reid import MyReIDor alternatively add
custom_imports = dict(
imports=['mmtrack.models.reid.my_reid.py'],
allow_failed_imports=False)to the config file and avoid modifying the original code.
reid=dict(
type='MyReID',
arg1=xxx,
arg2=xxx)Create a new file mmtrack/models/track_heads/my_head.py.
from mmcv.runner import BaseModule
from mmdet.models import HEADS
@HEADS.register_module()
class MyHead(BaseModule):
def __init__(self,
arg1,
arg2):
pass
def forward(self, inputs):
# implementation is ignored
passYou can either add the following line to mmtrack/models/track_heads/__init__.py,
from .my_head import MyHeador alternatively add
custom_imports = dict(
imports=['mmtrack.models.track_heads.my_head.py'],
allow_failed_imports=False)to the config file and avoid modifying the original code.
track_head=dict(
type='MyHead',
arg1=xxx,
arg2=xxx)Assume you want to add a new loss as MyLoss, for bounding box regression.
To add a new loss function, the users need implement it in mmtrack/models/losses/my_loss.py.
The decorator weighted_loss enable the loss to be weighted for each element.
import torch
import torch.nn as nn
from mmdet.models import LOSSES, weighted_loss
@weighted_loss
def my_loss(pred, target):
assert pred.size() == target.size() and target.numel() > 0
loss = torch.abs(pred - target)
return loss
@LOSSES.register_module()
class MyLoss(nn.Module):
def __init__(self, reduction='mean', loss_weight=1.0):
super(MyLoss, self).__init__()
self.reduction = reduction
self.loss_weight = loss_weight
def forward(self,
pred,
target,
weight=None,
avg_factor=None,
reduction_override=None):
assert reduction_override in (None, 'none', 'mean', 'sum')
reduction = (
reduction_override if reduction_override else self.reduction)
loss_bbox = self.loss_weight * my_loss(
pred, target, weight, reduction=reduction, avg_factor=avg_factor)
return loss_bboxThen the users need to add it in the mmtrack/models/losses/__init__.py.
from .my_loss import MyLoss, my_lossAlternatively, you can add
custom_imports=dict(
imports=['mmtrack.models.losses.my_loss'],
allow_failed_imports=False)to the config file and achieve the same goal.
To use it, modify the loss_xxx field.
Since MyLoss is for regression, you need to modify the loss_bbox field in the head.
loss_bbox=dict(type='MyLoss', loss_weight=1.0))