Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions experiments/finetune_reid_mot17_dla34.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cd src
python train.py mot --exp_id finetune_reid_mot17_dla34 --load_model '../models/fairmot_dla34.pth' --data_cfg '../src/lib/cfg/mot17.json' --downweight_reid_loss_by_occlusion_percent --freeze_all_layers_except id
cd ..
5 changes: 5 additions & 0 deletions experiments/finetune_reid_mot20_dla34.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

cd src
python train.py mot --exp_id finetune_reid_mot20_dla34 --load_model '../models/fairmot_dla34.pth' --data_cfg '../src/lib/cfg/mot20.json' --downweight_reid_loss_by_occlusion_percent --freeze_all_layers_except id
cd ..
22 changes: 22 additions & 0 deletions src/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
MOT_SEQUENCE_SPLITS = {
"MOT17-train": [
"MOT17-02",
"MOT17-04",
"MOT17-05",
"MOT17-09",
"MOT17-10",
"MOT17-11",
"MOT17-13",
],
"MOT17-test": [
"MOT17-01",
"MOT17-03",
"MOT17-06",
"MOT17-07",
"MOT17-08",
"MOT17-12",
"MOT17-14",
],
"MOT20-train": ["MOT20-01", "MOT20-02", "MOT20-03", "MOT20-05"],
"MOT20-test": ["MOT20-04", "MOT20-06", "MOT20-07", "MOT20-08"],
}
47 changes: 47 additions & 0 deletions src/gen_labels_17.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import os.path as osp
import os
import numpy as np
from tqdm import tqdm


def mkdirs(d):
print(f"creating directory at {d}")
if not osp.exists(d):
os.makedirs(d)


# seq_root = '/data/yfzhang/MOT/JDE/MOT16/images/train'
seq_root = "/app/data/MOT-benchmark/MOT17/train"
label_root = '/app/data/experiments/fairmot_base/labels_with_ids/train'
mkdirs(label_root)
seqs = [s for s in os.listdir(seq_root)]

tid_curr = 0
tid_last = -1
for i, seq in enumerate(seqs):
print(f"Processing {seq} {i + 1} of {len(seqs)}")
seq_info = open(osp.join(seq_root, seq, 'seqinfo.ini')).read()
seq_width = int(seq_info[seq_info.find('imWidth=') + 8:seq_info.find('\nimHeight')])
seq_height = int(seq_info[seq_info.find('imHeight=') + 9:seq_info.find('\nimExt')])

gt_txt = osp.join(seq_root, seq, 'gt', 'gt.txt')
gt = np.loadtxt(gt_txt, dtype=np.float64, delimiter=',')

seq_label_root = osp.join(label_root, seq, 'img1')
mkdirs(seq_label_root)

for fid, tid, x, y, w, h, mark, label, _ in tqdm(gt):
if mark == 0 or not label == 1:
continue
fid = int(fid)
tid = int(tid)
if not tid == tid_last:
tid_curr += 1
tid_last = tid
x += w / 2
y += h / 2
label_fpath = osp.join(seq_label_root, '{:06d}.txt'.format(fid))
label_str = '0 {:d} {:.6f} {:.6f} {:.6f} {:.6f}\n'.format(
tid_curr, x / seq_width, y / seq_height, w / seq_width, h / seq_height)
with open(label_fpath, 'a') as f:
f.write(label_str)
1 change: 1 addition & 0 deletions src/gen_labels_20.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ def mkdirs(d):
os.makedirs(d)


# TODO: change these paths
seq_root = '/data/yfzhang/MOT/JDE/MOT20/images/train'
label_root = '/data/yfzhang/MOT/JDE/MOT20/labels_with_ids/train'
mkdirs(label_root)
Expand Down
5 changes: 3 additions & 2 deletions src/lib/cfg/mot17.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"root":"/home/zyf/dataset",
"root":"/app/data/MOT-benchmark/MOT17/train",
"labels_root":"/app/data/experiments/fairmot_base/labels_with_ids/train/",
"train":
{
"mot17":"./data/mot17.train"
"mot17":"./data/mot17_seq_as_base_path.train"
},
"test_emb":
{
Expand Down
6 changes: 3 additions & 3 deletions src/lib/cfg/mot20.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"root":"/home/zyf/dataset",
"root":"/Users/sean/standard/data/reid-tracking-fix/MOT-benchmark/MOT20",
"train":
{
"mot20":"./data/mot20.train"
"mot20":"./train"
},
"test_emb":
{
"mot20":"./data/mot20.train"
},
"test":
{
"mot20":"./data/mot20.train"
"mot20":"./train"
}
}
5 changes: 2 additions & 3 deletions src/lib/datasets/dataset/jde.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ class JointDataset(LoadImagesAndLabels): # for training
std = None
num_classes = 1

def __init__(self, opt, root, paths, img_size=(1088, 608), augment=False, transforms=None):
def __init__(self, opt, root, labels_root, paths, img_size=(1088, 608), augment=False, transforms=None):
self.opt = opt
dataset_names = paths.keys()
self.img_files = OrderedDict()
Expand All @@ -372,9 +372,8 @@ def __init__(self, opt, root, paths, img_size=(1088, 608), augment=False, transf
self.img_files[ds] = list(filter(lambda x: len(x) > 0, self.img_files[ds]))

self.label_files[ds] = [
x.replace('images', 'labels_with_ids').replace('.png', '.txt').replace('.jpg', '.txt')
x.replace(root, labels_root).replace('.png', '.txt').replace('.jpg', '.txt')
for x in self.img_files[ds]]

for ds, label_paths in self.label_files.items():
max_index = -1
for lp in label_paths:
Expand Down
4 changes: 3 additions & 1 deletion src/lib/opts.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self):
'in the exp dir if load_model is empty.')

# system
self.parser.add_argument('--gpus', default='2, 3',
self.parser.add_argument('--gpus', default='0, 1, 2, 3',
help='-1 for CPU, use comma for multiple gpus')
self.parser.add_argument('--num_workers', type=int, default=8,
help='dataloader threads. 0 for single-thread.')
Expand Down Expand Up @@ -86,6 +86,7 @@ def __init__(self):
self.parser.add_argument('--trainval', action='store_true',
help='include validation in training and '
'test on test set')
# raise NotImplementedError("Add arg for freezing all layers except reid head")

# test
self.parser.add_argument('--K', type=int, default=500,
Expand Down Expand Up @@ -158,6 +159,7 @@ def __init__(self):
help='category specific bounding box size.')
self.parser.add_argument('--not_reg_offset', action='store_true',
help='not regress local offset.')
# raise NotImplementedError("add arg for training with ID downweighted by occlusion percentage")

def parse(self, args=''):
if args == '':
Expand Down
12 changes: 12 additions & 0 deletions src/lib/trains/mot.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
from .base_trainer import BaseTrainer


class PrototypicalMotLoss(torch.nn.Module):
def __init__(self, opt):
super().__init__()
raise NotImplementedError


class MotLoss(torch.nn.Module):
def __init__(self, opt):
super(MotLoss, self).__init__()
Expand All @@ -41,6 +47,8 @@ def __init__(self, opt):
self.emb_scale = math.sqrt(2) * math.log(self.nID - 1)
self.s_det = nn.Parameter(-1.85 * torch.ones(1))
self.s_id = nn.Parameter(-1.05 * torch.ones(1))
# TODO: add attribute from `opt` to parameterize weigthing based on occlusion
# raise NotImplementedError("add arg for training with ID downweighted by occlusion percentage")

def forward(self, outputs, batch):
opt = self.opt
Expand Down Expand Up @@ -75,6 +83,10 @@ def forward(self, outputs, batch):
alpha=0.25, gamma=2.0, reduction="sum"
) / id_output.size(0)
else:
# import pdb; pdb.set_trace()
# print("add arg for training with ID downweighted by occlusion percentage")
# print(id_output.shape)
# print(id_target.shape)
id_loss += self.IDLoss(id_output, id_target)

det_loss = opt.hm_weight * hm_loss + opt.wh_weight * wh_loss + opt.off_weight * off_loss
Expand Down
14 changes: 10 additions & 4 deletions src/train.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# python train.py mot --exp_id finetune_reid_mot17_dla34 --load_model '../models/fairmot_dla34.pth' --data_cfg '../src/lib/cfg/mot17.json' # TODO --downweight_reid_loss_by_occlusion_percent --freeze_all_layers_except id

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
Expand All @@ -14,6 +16,9 @@
from models.model import create_model, load_model, save_model
from models.data_parallel import DataParallel
from logger import Logger

from src.lib.datasets.dataset.jde import JointDataset as Dataset
from src.lib.trains.mot import MotTrainer as Trainer
from datasets.dataset_factory import get_dataset
from trains.train_factory import train_factory

Expand All @@ -23,21 +28,22 @@ def main(opt):
torch.backends.cudnn.benchmark = not opt.not_cuda_benchmark and not opt.test

print('Setting up data...')
Dataset = get_dataset(opt.dataset, opt.task)
# Dataset = get_dataset(opt.dataset, opt.task)
f = open(opt.data_cfg)
data_config = json.load(f)
trainset_paths = data_config['train']
dataset_root = data_config['root']
labels_root = data_config['labels_root']
f.close()
transforms = T.Compose([T.ToTensor()])
dataset = Dataset(opt, dataset_root, trainset_paths, (1088, 608), augment=True, transforms=transforms)
dataset = Dataset(opt, dataset_root, labels_root, trainset_paths, (1088, 608), augment=True, transforms=transforms)
opt = opts().update_dataset_info_and_set_heads(opt, dataset)
print(opt)

logger = Logger(opt)

os.environ['CUDA_VISIBLE_DEVICES'] = opt.gpus_str
opt.device = torch.device('cuda' if opt.gpus[0] >= 0 else 'cpu')
opt.device = torch.device(f'cuda:{opt.gpus[0]}' if len(opt.gpus) >= 0 else 'cpu')

print('Creating model...')
model = create_model(opt.arch, opt.heads, opt.head_conv)
Expand All @@ -56,7 +62,7 @@ def main(opt):
)

print('Starting training...')
Trainer = train_factory[opt.task]
# Trainer = train_factory[opt.task]
trainer = Trainer(opt, model, optimizer)
trainer.set_device(opt.gpus, opt.chunk_sizes, opt.device)

Expand Down