#PBS -N bytetrack_17_on_17half | |||||
#PBS -m abe | |||||
#PBS -M [email protected] | |||||
#PBS -l nodes=1:ppn=1:gpus=1 | |||||
#PBS -q cuda9 | |||||
export LD_LIBRARY_PATH=/share/apps/cuda/cuda-10.1/lib64:$LD_LIBRARY_PATH | |||||
export PATH=/share/apps/cuda/cuda-10.1/bin/:$PATH | |||||
source /share/apps/Anaconda/anaconda3.6/bin/activate abdollahpour.ce.sharif | |||||
conda activate abd_env | |||||
cd /home/abdollahpour.ce.sharif/ByteTrack | |||||
python tools/track.py -t mot -f exps/example/mot/yolox_x_mot17_half.py -d 1 -b 1 --fp16 -c /home/abdollahpour.ce.sharif/ByteTrackModels/bytetrack_x_mot17.pth.tar --local_rank 0 -expn bytetrack_17_on_17half |
#PBS -N bytetrack_17_on_20 | |||||
#PBS -m abe | |||||
#PBS -M [email protected] | |||||
#PBS -l nodes=1:ppn=1:gpus=1 | |||||
#PBS -q cuda9 | |||||
export LD_LIBRARY_PATH=/share/apps/cuda/cuda-10.1/lib64:$LD_LIBRARY_PATH | |||||
export PATH=/share/apps/cuda/cuda-10.1/bin/:$PATH | |||||
source /share/apps/Anaconda/anaconda3.6/bin/activate abdollahpour.ce.sharif | |||||
conda activate abd_env | |||||
cd /home/abdollahpour.ce.sharif/ByteTrack | |||||
python tools/track.py -t mot -f exps/example/mot/yolox_x_mot20_on_mot20.py -d 1 -b 1 --fp16 -c /home/abdollahpour.ce.sharif/ByteTrackModels/bytetrack_x_mot17.pth.tar --local_rank 0 -expn bytetrack_17_on_20 --mot20 |
export LD_LIBRARY_PATH=/share/apps/cuda/cuda-10.1/lib64:$LD_LIBRARY_PATH | export LD_LIBRARY_PATH=/share/apps/cuda/cuda-10.1/lib64:$LD_LIBRARY_PATH | ||||
export PATH=/share/apps/cuda/cuda-10.1/bin/:$PATH | export PATH=/share/apps/cuda/cuda-10.1/bin/:$PATH | ||||
source /share/apps/Anaconda/anaconda3.6/bin/activate abdollahpour.ce.sharif | source /share/apps/Anaconda/anaconda3.6/bin/activate abdollahpour.ce.sharif | ||||
conda activate abd_env | conda activate abd_env | ||||
python tools/train.py -t metamot -f exps/example/metamot/yolox_x_mot17_on_mot20.py -d 1 -b 1 --fp16 -o --resume --start_epoch 2 -c /home/abdollahpour.ce.sharif/ByteTrack/meta_experiments/train_17_on_20/latest_ckpt.pth.tar --local_rank 0 -expn train_17_on_20_resume | |||||
python tools/train.py -t metamot -f exps/example/metamot/yolox_x_mot17_on_mot20.py -d 1 -b 1 --fp16 -o --resume --start_epoch 6 -c /home/abdollahpour.ce.sharif/ByteTrack/meta_experiments/train_17_on_20_resume/latest_ckpt.pth.tar --local_rank 0 -expn train_17_on_20_resume2 |
export LD_LIBRARY_PATH=/share/apps/cuda/cuda-10.1/lib64:$LD_LIBRARY_PATH | |||||
export PATH=/share/apps/cuda/cuda-10.1/bin/:$PATH | |||||
source /share/apps/Anaconda/anaconda3.6/bin/activate abdollahpour.ce.sharif | |||||
conda activate abd_env | |||||
cd /home/abdollahpour.ce.sharif/ByteTrack | |||||
python tools/test.py |
#PBS -N track_metamot17_on_17_no_adapt | |||||
#PBS -m abe | |||||
#PBS -M [email protected] | |||||
#PBS -l nodes=1:ppn=1:gpus=1 | |||||
#PBS -q cuda9 | |||||
export LD_LIBRARY_PATH=/share/apps/cuda/cuda-10.1/lib64:$LD_LIBRARY_PATH | |||||
export PATH=/share/apps/cuda/cuda-10.1/bin/:$PATH | |||||
source /share/apps/Anaconda/anaconda3.6/bin/activate abdollahpour.ce.sharif | |||||
conda activate abd_env | |||||
cd /home/abdollahpour.ce.sharif/ByteTrack | |||||
python tools/track.py -t metamot -f exps/example/metamot/yolox_x_mot17_on_mot17.py -d 1 -b 1 --fp16 -c /home/abdollahpour.ce.sharif/ByteTrack/meta_experiments/train_17_on_20_resume2/best_ckpt.pth.tar --local_rank 0 -expn track_metamot17_on_17 |
#PBS -N track_17_on_20_ada_12 | |||||
#PBS -m abe | |||||
#PBS -M [email protected] | |||||
#PBS -l nodes=1:ppn=1:gpus=1 | |||||
#PBS -q cuda9 | |||||
export LD_LIBRARY_PATH=/share/apps/cuda/cuda-10.1/lib64:$LD_LIBRARY_PATH | |||||
export PATH=/share/apps/cuda/cuda-10.1/bin/:$PATH | |||||
source /share/apps/Anaconda/anaconda3.6/bin/activate abdollahpour.ce.sharif | |||||
conda activate abd_env | |||||
cd /home/abdollahpour.ce.sharif/ByteTrack | |||||
python tools/track.py -t metamot -f exps/example/metamot/yolox_x_mot17_on_mot20.py -d 1 -b 1 -c /home/abdollahpour.ce.sharif/ByteTrack/meta_experiments/train_17_on_20_resume2/best_ckpt.pth.tar --local_rank 0 -expn track_17_on_20_ada_12 --mot20 --adaptation_period 12 |
#PBS -N weak_labels | |||||
#PBS -m abe | |||||
#PBS -M [email protected] | |||||
#PBS -l nodes=1:ppn=1:gpus=1 | |||||
#PBS -q cuda9 | |||||
export LD_LIBRARY_PATH=/share/apps/cuda/cuda-10.1/lib64:$LD_LIBRARY_PATH | |||||
export PATH=/share/apps/cuda/cuda-10.1/bin/:$PATH | |||||
source /share/apps/Anaconda/anaconda3.6/bin/activate abdollahpour.ce.sharif | |||||
conda activate abd_env | |||||
cd /home/abdollahpour.ce.sharif/ByteTrack | |||||
python tools/generate_weak_labels.py |
# encoding: utf-8 | |||||
import os | |||||
import random | |||||
import torch | |||||
import torch.nn as nn | |||||
import torch.distributed as dist | |||||
from yolox.exp import MetaExp as MyMetaExp | |||||
from yolox.data import get_yolox_datadir | |||||
from os import listdir | |||||
from os.path import isfile, join | |||||
class Exp(MyMetaExp): | |||||
def __init__(self): | |||||
super(Exp, self).__init__() | |||||
self.num_classes = 1 | |||||
self.depth = 1.33 | |||||
self.width = 1.25 | |||||
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0] | |||||
self.train_dir = '/home/abdollahpour.ce.sharif/ByteTrackData/MOT17/annotations' | |||||
onlyfiles = [f for f in listdir(self.train_dir) if isfile(join(self.train_dir, f))] | |||||
self.train_anns = [file for file in onlyfiles if file.__contains__('train') and file.__contains__('FRCNN')] | |||||
# # TODO: remove | |||||
# self.train_anns = self.train_anns[3:] | |||||
self.val_dir = '/home/abdollahpour.ce.sharif/ByteTrackData/MOT17/annotations' | |||||
onlyfiles = [f for f in listdir(self.val_dir) if isfile(join(self.val_dir, f))] | |||||
self.val_anns = [file for file in onlyfiles if file.__contains__('train') and file.__contains__('FRCNN')] | |||||
# self.val_anns = self.val_anns[-1:] | |||||
print('train_anns', self.train_anns) | |||||
print('val_anns', self.val_anns) | |||||
self.input_size = (800, 1440) | |||||
self.test_size = (800, 1440) | |||||
# self.test_size = (736, 1920) | |||||
self.random_size = (20, 36) | |||||
self.max_epoch = 80 | |||||
self.print_interval = 250 | |||||
self.eval_interval = 5 | |||||
self.test_conf = 0.1 | |||||
self.nmsthre = 0.7 | |||||
self.no_aug_epochs = 10 | |||||
# self.basic_lr_per_img = 0.001 / 64.0 | |||||
self.basic_lr_per_img = 0.0001 / 64.0 | |||||
self.warmup_epochs = 1 | |||||
def get_data_loaders(self, batch_size, is_distributed, no_aug=False): | |||||
from yolox.data import ( | |||||
MOTDataset, | |||||
TrainTransform, | |||||
YoloBatchSampler, | |||||
DataLoader, | |||||
InfiniteSampler, | |||||
MosaicDetection, | |||||
) | |||||
train_loaders = [] | |||||
for train_ann in self.train_anns: | |||||
dataset = MOTDataset( | |||||
data_dir=os.path.join(get_yolox_datadir(), "MOT17"), | |||||
json_file=train_ann, | |||||
name='train', | |||||
img_size=self.input_size, | |||||
preproc=TrainTransform( | |||||
rgb_means=(0.485, 0.456, 0.406), | |||||
std=(0.229, 0.224, 0.225), | |||||
max_labels=500, | |||||
), | |||||
) | |||||
dataset = MosaicDetection( | |||||
dataset, | |||||
mosaic=not no_aug, | |||||
img_size=self.input_size, | |||||
preproc=TrainTransform( | |||||
rgb_means=(0.485, 0.456, 0.406), | |||||
std=(0.229, 0.224, 0.225), | |||||
max_labels=1000, | |||||
), | |||||
degrees=self.degrees, | |||||
translate=self.translate, | |||||
scale=self.scale, | |||||
shear=self.shear, | |||||
perspective=self.perspective, | |||||
enable_mixup=self.enable_mixup, | |||||
) | |||||
self.dataset = dataset | |||||
if is_distributed: | |||||
batch_size = batch_size // dist.get_world_size() | |||||
sampler = InfiniteSampler( | |||||
len(self.dataset), seed=self.seed if self.seed else 0 | |||||
) | |||||
batch_sampler = YoloBatchSampler( | |||||
sampler=sampler, | |||||
batch_size=batch_size, | |||||
drop_last=False, | |||||
input_dimension=self.input_size, | |||||
mosaic=not no_aug, | |||||
) | |||||
dataloader_kwargs = {"num_workers": self.data_num_workers, "pin_memory": True} | |||||
dataloader_kwargs["batch_sampler"] = batch_sampler | |||||
train_loader = DataLoader(self.dataset, **dataloader_kwargs) | |||||
train_loaders.append(train_loader) | |||||
return train_loaders | |||||
def get_eval_loaders(self, batch_size, is_distributed, testdev=False): | |||||
from yolox.data import MOTDataset, ValTransform, ValTransformWithPseudo | |||||
val_loaders = [] | |||||
for val_ann in self.val_anns: | |||||
valdataset = MOTDataset( | |||||
data_dir=os.path.join(get_yolox_datadir(), "MOT17"), | |||||
json_file=val_ann, | |||||
img_size=self.test_size, | |||||
name='train', # change to train when running on training set | |||||
preproc=ValTransformWithPseudo( | |||||
rgb_means=(0.485, 0.456, 0.406), | |||||
std=(0.229, 0.224, 0.225), | |||||
), | |||||
) | |||||
if is_distributed: | |||||
batch_size = batch_size // dist.get_world_size() | |||||
sampler = torch.utils.data.distributed.DistributedSampler( | |||||
valdataset, shuffle=False | |||||
) | |||||
else: | |||||
sampler = torch.utils.data.SequentialSampler(valdataset) | |||||
dataloader_kwargs = { | |||||
"num_workers": self.data_num_workers, | |||||
"pin_memory": True, | |||||
"sampler": sampler, | |||||
} | |||||
dataloader_kwargs["batch_size"] = batch_size | |||||
val_loader = torch.utils.data.DataLoader(valdataset, **dataloader_kwargs) | |||||
val_loaders.append(val_loader) | |||||
return val_loaders | |||||
def get_evaluator(self, batch_size, is_distributed, testdev=False): | |||||
from yolox.evaluators import COCOEvaluator | |||||
val_loaders = self.get_eval_loaders(batch_size, is_distributed, testdev=testdev) | |||||
evaluators = [] | |||||
for val_loader in val_loaders: | |||||
evaluator = COCOEvaluator( | |||||
dataloader=val_loader, | |||||
img_size=self.test_size, | |||||
confthre=self.test_conf, | |||||
nmsthre=self.nmsthre, | |||||
num_classes=self.num_classes, | |||||
testdev=testdev, | |||||
) | |||||
evaluators.append(evaluator) | |||||
return evaluators |
onlyfiles = [f for f in listdir(self.val_dir) if isfile(join(self.val_dir, f))] | onlyfiles = [f for f in listdir(self.val_dir) if isfile(join(self.val_dir, f))] | ||||
self.val_anns = [file for file in onlyfiles if file.__contains__('train') and file.__contains__( | self.val_anns = [file for file in onlyfiles if file.__contains__('train') and file.__contains__( | ||||
'MOT20')] | 'MOT20')] | ||||
# self.val_anns = self.val_anns[-1:] | |||||
print('train_anns', self.train_anns) | print('train_anns', self.train_anns) | ||||
print('val_anns', self.val_anns) | print('val_anns', self.val_anns) | ||||
self.input_size = (800, 1440) | self.input_size = (800, 1440) | ||||
# self.test_size = (736, 1920) | # self.test_size = (736, 1920) | ||||
self.random_size = (20, 36) | self.random_size = (20, 36) | ||||
self.max_epoch = 80 | self.max_epoch = 80 | ||||
self.print_interval = 100 | |||||
self.print_interval = 250 | |||||
self.eval_interval = 5 | self.eval_interval = 5 | ||||
self.test_conf = 0.001 | self.test_conf = 0.001 | ||||
self.nmsthre = 0.7 | self.nmsthre = 0.7 | ||||
self.no_aug_epochs = 10 | self.no_aug_epochs = 10 | ||||
self.basic_lr_per_img = 0.001 / 64.0 | |||||
# self.basic_lr_per_img = 0.001 / 64.0 | |||||
self.basic_lr_per_img = 0.0001 / 64.0 | |||||
self.warmup_epochs = 1 | self.warmup_epochs = 1 | ||||
def get_data_loaders(self, batch_size, is_distributed, no_aug=False): | def get_data_loaders(self, batch_size, is_distributed, no_aug=False): | ||||
return train_loaders | return train_loaders | ||||
def get_eval_loaders(self, batch_size, is_distributed, testdev=False): | def get_eval_loaders(self, batch_size, is_distributed, testdev=False): | ||||
from yolox.data import MOTDataset, ValTransform | |||||
from yolox.data import MOTDataset, ValTransform, ValTransformWithPseudo | |||||
val_loaders = [] | val_loaders = [] | ||||
for val_ann in self.val_anns: | for val_ann in self.val_anns: | ||||
valdataset = MOTDataset( | valdataset = MOTDataset( | ||||
json_file=val_ann, | json_file=val_ann, | ||||
img_size=self.test_size, | img_size=self.test_size, | ||||
name='train', # change to train when running on training set | name='train', # change to train when running on training set | ||||
preproc=ValTransform( | |||||
preproc=ValTransformWithPseudo( | |||||
rgb_means=(0.485, 0.456, 0.406), | rgb_means=(0.485, 0.456, 0.406), | ||||
std=(0.229, 0.224, 0.225), | std=(0.229, 0.224, 0.225), | ||||
), | ), | ||||
load_weak=True | |||||
) | ) | ||||
if is_distributed: | if is_distributed: | ||||
def get_evaluator(self, batch_size, is_distributed, testdev=False): | def get_evaluator(self, batch_size, is_distributed, testdev=False): | ||||
from yolox.evaluators import COCOEvaluator | from yolox.evaluators import COCOEvaluator | ||||
val_loader = self.get_eval_loaders(batch_size, is_distributed, testdev=testdev) | |||||
evaluator = COCOEvaluator( | |||||
dataloader=val_loader, | |||||
img_size=self.test_size, | |||||
confthre=self.test_conf, | |||||
nmsthre=self.nmsthre, | |||||
num_classes=self.num_classes, | |||||
testdev=testdev, | |||||
) | |||||
return evaluator | |||||
val_loaders = self.get_eval_loaders(batch_size, is_distributed, testdev=testdev) | |||||
evaluators = [] | |||||
for val_loader in val_loaders: | |||||
evaluator = COCOEvaluator( | |||||
dataloader=val_loader, | |||||
img_size=self.test_size, | |||||
confthre=self.test_conf, | |||||
nmsthre=self.nmsthre, | |||||
num_classes=self.num_classes, | |||||
testdev=testdev, | |||||
) | |||||
evaluators.append(evaluator) | |||||
return evaluators |
) | ) | ||||
dataset = MOTDataset( | dataset = MOTDataset( | ||||
data_dir=os.path.join(get_yolox_datadir(), "mot"), | |||||
data_dir=os.path.join(get_yolox_datadir(), "MOT17"), | |||||
json_file=self.train_ann, | json_file=self.train_ann, | ||||
name='train', | name='train', | ||||
img_size=self.input_size, | img_size=self.input_size, | ||||
from yolox.data import MOTDataset, ValTransform | from yolox.data import MOTDataset, ValTransform | ||||
valdataset = MOTDataset( | valdataset = MOTDataset( | ||||
data_dir=os.path.join(get_yolox_datadir(), "mot"), | |||||
data_dir=os.path.join(get_yolox_datadir(), "MOT17"), | |||||
json_file=self.val_ann, | json_file=self.val_ann, | ||||
img_size=self.test_size, | img_size=self.test_size, | ||||
name='train', | name='train', |
# encoding: utf-8 | |||||
import os | |||||
import random | |||||
import torch | |||||
import torch.nn as nn | |||||
import torch.distributed as dist | |||||
from yolox.exp import Exp as MyExp | |||||
from yolox.data import get_yolox_datadir | |||||
class Exp(MyExp): | |||||
def __init__(self): | |||||
super(Exp, self).__init__() | |||||
self.num_classes = 1 | |||||
self.depth = 1.33 | |||||
self.width = 1.25 | |||||
self.exp_name = os.path.split(os.path.realpath(__file__))[1].split(".")[0] | |||||
self.train_ann = "train.json" | |||||
self.val_ann = "train.json" # change to train.json when running on training set | |||||
self.input_size = (896, 1600) | |||||
self.test_size = (896, 1600) | |||||
#self.test_size = (736, 1920) | |||||
self.random_size = (20, 36) | |||||
self.max_epoch = 80 | |||||
self.print_interval = 20 | |||||
self.eval_interval = 5 | |||||
self.test_conf = 0.001 | |||||
self.nmsthre = 0.7 | |||||
self.no_aug_epochs = 10 | |||||
self.basic_lr_per_img = 0.001 / 64.0 | |||||
self.warmup_epochs = 1 | |||||
def get_data_loader(self, batch_size, is_distributed, no_aug=False): | |||||
from yolox.data import ( | |||||
MOTDataset, | |||||
TrainTransform, | |||||
YoloBatchSampler, | |||||
DataLoader, | |||||
InfiniteSampler, | |||||
MosaicDetection, | |||||
) | |||||
dataset = MOTDataset( | |||||
data_dir=os.path.join(get_yolox_datadir(), "MOT20"), | |||||
json_file=self.train_ann, | |||||
name='', | |||||
img_size=self.input_size, | |||||
preproc=TrainTransform( | |||||
rgb_means=(0.485, 0.456, 0.406), | |||||
std=(0.229, 0.224, 0.225), | |||||
max_labels=600, | |||||
), | |||||
) | |||||
dataset = MosaicDetection( | |||||
dataset, | |||||
mosaic=not no_aug, | |||||
img_size=self.input_size, | |||||
preproc=TrainTransform( | |||||
rgb_means=(0.485, 0.456, 0.406), | |||||
std=(0.229, 0.224, 0.225), | |||||
max_labels=1200, | |||||
), | |||||
degrees=self.degrees, | |||||
translate=self.translate, | |||||
scale=self.scale, | |||||
shear=self.shear, | |||||
perspective=self.perspective, | |||||
enable_mixup=self.enable_mixup, | |||||
) | |||||
self.dataset = dataset | |||||
if is_distributed: | |||||
batch_size = batch_size // dist.get_world_size() | |||||
sampler = InfiniteSampler( | |||||
len(self.dataset), seed=self.seed if self.seed else 0 | |||||
) | |||||
batch_sampler = YoloBatchSampler( | |||||
sampler=sampler, | |||||
batch_size=batch_size, | |||||
drop_last=False, | |||||
input_dimension=self.input_size, | |||||
mosaic=not no_aug, | |||||
) | |||||
dataloader_kwargs = {"num_workers": self.data_num_workers, "pin_memory": True} | |||||
dataloader_kwargs["batch_sampler"] = batch_sampler | |||||
train_loader = DataLoader(self.dataset, **dataloader_kwargs) | |||||
return train_loader | |||||
def get_eval_loader(self, batch_size, is_distributed, testdev=False): | |||||
from yolox.data import MOTDataset, ValTransform | |||||
valdataset = MOTDataset( | |||||
data_dir=os.path.join(get_yolox_datadir(), "MOT20"), | |||||
json_file=self.val_ann, | |||||
img_size=self.test_size, | |||||
name='train', # change to train when running on training set | |||||
preproc=ValTransform( | |||||
rgb_means=(0.485, 0.456, 0.406), | |||||
std=(0.229, 0.224, 0.225), | |||||
), | |||||
) | |||||
if is_distributed: | |||||
batch_size = batch_size // dist.get_world_size() | |||||
sampler = torch.utils.data.distributed.DistributedSampler( | |||||
valdataset, shuffle=False | |||||
) | |||||
else: | |||||
sampler = torch.utils.data.SequentialSampler(valdataset) | |||||
dataloader_kwargs = { | |||||
"num_workers": self.data_num_workers, | |||||
"pin_memory": True, | |||||
"sampler": sampler, | |||||
} | |||||
dataloader_kwargs["batch_size"] = batch_size | |||||
val_loader = torch.utils.data.DataLoader(valdataset, **dataloader_kwargs) | |||||
return val_loader | |||||
def get_evaluator(self, batch_size, is_distributed, testdev=False): | |||||
from yolox.evaluators import COCOEvaluator | |||||
val_loader = self.get_eval_loader(batch_size, is_distributed, testdev=testdev) | |||||
evaluator = COCOEvaluator( | |||||
dataloader=val_loader, | |||||
img_size=self.test_size, | |||||
confthre=self.test_conf, | |||||
nmsthre=self.nmsthre, | |||||
num_classes=self.num_classes, | |||||
testdev=testdev, | |||||
) | |||||
return evaluator |
import os | |||||
import numpy as np | |||||
import json | |||||
import cv2 | |||||
# Use the same script for MOT16 | |||||
DATA_PATH = '/media/external_10TB/10TB/vision/ByteTrackData/MOT20' | |||||
OUT_PATH = os.path.join(DATA_PATH, 'annotations') | |||||
SPLITS = ['train', 'test'] # --> split training data to train_half and val_half. | |||||
HALF_VIDEO = True | |||||
CREATE_SPLITTED_ANN = True | |||||
CREATE_SPLITTED_DET = True | |||||
if __name__ == '__main__': | |||||
if not os.path.exists(OUT_PATH): | |||||
os.makedirs(OUT_PATH) | |||||
for split in SPLITS: | |||||
if split == "test": | |||||
data_path = os.path.join(DATA_PATH, 'test') | |||||
else: | |||||
data_path = os.path.join(DATA_PATH, 'train') | |||||
seqs = os.listdir(data_path) | |||||
for seq in sorted(seqs): | |||||
out_path = os.path.join(OUT_PATH, '{}_{}_weak.json'.format(split, seq)) | |||||
out = {'images': [], 'annotations': [], 'videos': [], | |||||
'categories': [{'id': 1, 'name': 'pedestrian'}]} | |||||
image_cnt = 0 | |||||
ann_cnt = 0 | |||||
video_cnt = 0 | |||||
tid_curr = 0 | |||||
tid_last = -1 | |||||
if '.DS_Store' in seq: | |||||
continue | |||||
video_cnt += 1 # video sequence number. | |||||
out['videos'].append({'id': video_cnt, 'file_name': seq}) | |||||
seq_path = os.path.join(data_path, seq) | |||||
img_path = os.path.join(seq_path, 'img1') | |||||
ann_path = os.path.join(seq_path, 'gt/gt.txt') | |||||
images = os.listdir(img_path) | |||||
num_images = len([image for image in images if 'jpg' in image]) # half and half | |||||
if HALF_VIDEO and ('half' in split): | |||||
image_range = [0, num_images // 2] if 'train' in split else \ | |||||
[num_images // 2 + 1, num_images - 1] | |||||
else: | |||||
image_range = [0, num_images - 1] | |||||
for i in range(num_images): | |||||
if i < image_range[0] or i > image_range[1]: | |||||
continue | |||||
img = cv2.imread(os.path.join(data_path, '{}/img1/{:06d}.jpg'.format(seq, i + 1))) | |||||
height, width = img.shape[:2] | |||||
image_info = {'file_name': '{}/img1/{:06d}.jpg'.format(seq, i + 1), # image name. | |||||
'id': image_cnt + i + 1, # image number in the entire training set. | |||||
'frame_id': i + 1 - image_range[0], | |||||
# image number in the video sequence, starting from 1. | |||||
'prev_image_id': image_cnt + i if i > 0 else -1, | |||||
# image number in the entire training set. | |||||
'next_image_id': image_cnt + i + 2 if i < num_images - 1 else -1, | |||||
'video_id': video_cnt, | |||||
'height': height, 'width': width} | |||||
out['images'].append(image_info) | |||||
print('{}: {} images'.format(seq, num_images)) | |||||
if split != 'test': | |||||
det_path = os.path.join(seq_path, 'det/det.txt') | |||||
anns = np.loadtxt(ann_path, dtype=np.float32, delimiter=',') | |||||
dets = np.loadtxt(det_path, dtype=np.float32, delimiter=',') | |||||
print('{} ann images'.format(int(anns[:, 0].max()))) | |||||
for i in range(anns.shape[0]): | |||||
frame_id = int(anns[i][0]) | |||||
if frame_id - 1 < image_range[0] or frame_id - 1 > image_range[1]: | |||||
continue | |||||
track_id = int(anns[i][1]) | |||||
cat_id = int(anns[i][7]) | |||||
ann_cnt += 1 | |||||
if not ('15' in DATA_PATH): | |||||
# if not (float(anns[i][8]) >= 0.25): # visibility. | |||||
# continue | |||||
if not (int(anns[i][6]) == 1): # whether ignore. | |||||
continue | |||||
if int(anns[i][7]) in [3, 4, 5, 6, 9, 10, 11]: # Non-person | |||||
continue | |||||
if int(anns[i][7]) in [2, 7, 8, 12]: # Ignored person | |||||
# category_id = -1 | |||||
continue | |||||
else: | |||||
category_id = 1 # pedestrian(non-static) | |||||
if not track_id == tid_last: | |||||
tid_curr += 1 | |||||
tid_last = track_id | |||||
else: | |||||
category_id = 1 | |||||
ann = {'id': ann_cnt, | |||||
'category_id': category_id, | |||||
'image_id': image_cnt + frame_id, | |||||
'track_id': -1, | |||||
'bbox': '', | |||||
'conf': '', | |||||
'iscrowd': 0, | |||||
'area': ''} | |||||
# float(anns[i][4] * anns[i][5]) | |||||
out['annotations'].append(ann) | |||||
image_cnt += num_images | |||||
print(tid_curr, tid_last) | |||||
print('loaded {} for {} images and {} samples'.format(split, len(out['images']), len(out['annotations']))) | |||||
json.dump(out, open(out_path, 'w')) |
# Mahdi Abdollahpour, 22/12/2021, 02:26 PM, PyCharm, ByteTrack | |||||
import os | |||||
import time | |||||
from loguru import logger | |||||
# from opts import opts | |||||
from os import listdir | |||||
from os.path import isfile, join | |||||
import cv2 | |||||
import numpy as np | |||||
import torch | |||||
from yolox.data.data_augment import ValTransform | |||||
# from yolox.data.datasets import COCO_CLASSES | |||||
from yolox.exp import get_exp | |||||
from yolox.utils import fuse_model, get_model_info, postprocess, vis | |||||
from yolox import statics | |||||
COCO_CLASSES = ( | |||||
"person", | |||||
"bicycle", | |||||
"car", | |||||
"motorcycle", | |||||
"airplane", | |||||
"bus", | |||||
"train", | |||||
"truck", | |||||
"boat", | |||||
"traffic light", | |||||
"fire hydrant", | |||||
"stop sign", | |||||
"parking meter", | |||||
"bench", | |||||
"bird", | |||||
"cat", | |||||
"dog", | |||||
"horse", | |||||
"sheep", | |||||
"cow", | |||||
"elephant", | |||||
"bear", | |||||
"zebra", | |||||
"giraffe", | |||||
"backpack", | |||||
"umbrella", | |||||
"handbag", | |||||
"tie", | |||||
"suitcase", | |||||
"frisbee", | |||||
"skis", | |||||
"snowboard", | |||||
"sports ball", | |||||
"kite", | |||||
"baseball bat", | |||||
"baseball glove", | |||||
"skateboard", | |||||
"surfboard", | |||||
"tennis racket", | |||||
"bottle", | |||||
"wine glass", | |||||
"cup", | |||||
"fork", | |||||
"knife", | |||||
"spoon", | |||||
"bowl", | |||||
"banana", | |||||
"apple", | |||||
"sandwich", | |||||
"orange", | |||||
"broccoli", | |||||
"carrot", | |||||
"hot dog", | |||||
"pizza", | |||||
"donut", | |||||
"cake", | |||||
"chair", | |||||
"couch", | |||||
"potted plant", | |||||
"bed", | |||||
"dining table", | |||||
"toilet", | |||||
"tv", | |||||
"laptop", | |||||
"mouse", | |||||
"remote", | |||||
"keyboard", | |||||
"cell phone", | |||||
"microwave", | |||||
"oven", | |||||
"toaster", | |||||
"sink", | |||||
"refrigerator", | |||||
"book", | |||||
"clock", | |||||
"vase", | |||||
"scissors", | |||||
"teddy bear", | |||||
"hair drier", | |||||
"toothbrush", | |||||
) | |||||
IMAGE_EXT = [".jpg", ".jpeg", ".webp", ".bmp", ".png"] | |||||
use_cuda = True | |||||
MOT = 'MOT20' | |||||
section = 'train' | |||||
root_dir = os.path.join(statics.DATA_PATH, MOT, section) | |||||
classes = ['person', 'bicycle', 'car', 'motorcycle', 'truck', 'bus'] | |||||
fuse = False | |||||
def get_labels(bboxes, cls, scores, th, tw): | |||||
id = 0 | |||||
labels = [] | |||||
# print(pred['scores']) | |||||
n, _ = bboxes.shape | |||||
for i in range(n): | |||||
if COCO_CLASSES[int(cls[i])] not in classes: | |||||
# print('Rejecting',COCO_CLASSES[int(cls[i])],scores[i]) | |||||
continue | |||||
if use_cuda: | |||||
box = bboxes[i, :].detach().cpu().numpy() | |||||
else: | |||||
box = bboxes[i, :].detach().numpy() | |||||
## TODO: check if matches | |||||
# print(box[0], box[1], box[2], box[3], '--', th, tw) | |||||
# print(box[0] / th, box[1] / tw, box[2] / th, box[3] / tw) | |||||
x = box[0] / th | |||||
y = box[1] / tw | |||||
w = (box[2] - box[0]) / th | |||||
h = (box[3] - box[1]) / tw | |||||
x += w / 2 | |||||
y += h / 2 | |||||
label = [0, id, x, y, w, h] | |||||
# label = [0, id, box[0], box[1], (box[2] - box[0]), (box[3] - box[1])] | |||||
id += 1 | |||||
labels.append(label) | |||||
# print(id) | |||||
labels0 = np.array(labels) | |||||
return labels0 | |||||
class Predictor(object): | |||||
def __init__( | |||||
self, | |||||
model, | |||||
exp, | |||||
cls_names=COCO_CLASSES, | |||||
trt_file=None, | |||||
decoder=None, | |||||
device="cpu", | |||||
fp16=False, | |||||
legacy=False, | |||||
): | |||||
self.model = model | |||||
self.cls_names = cls_names | |||||
self.decoder = decoder | |||||
self.num_classes = exp.num_classes | |||||
self.confthre = 0.1 | |||||
self.nmsthre = 0.3 | |||||
self.test_size = exp.test_size | |||||
self.device = device | |||||
self.fp16 = fp16 | |||||
self.preproc = ValTransform() | |||||
# if trt_file is not None: | |||||
# from torch2trt import TRTModule | |||||
# | |||||
# model_trt = TRTModule() | |||||
# model_trt.load_state_dict(torch.load(trt_file)) | |||||
# | |||||
# x = torch.ones(1, 3, exp.test_size[0], exp.test_size[1]).cuda() | |||||
# self.model(x) | |||||
# self.model = model_trt | |||||
def inference(self, img): | |||||
img_info = {"id": 0} | |||||
if isinstance(img, str): | |||||
img_info["file_name"] = os.path.basename(img) | |||||
img = cv2.imread(img) | |||||
else: | |||||
img_info["file_name"] = None | |||||
height, width = img.shape[:2] | |||||
img_info["height"] = height | |||||
img_info["width"] = width | |||||
img_info["raw_img"] = img | |||||
ratio = min(self.test_size[0] / img.shape[0], self.test_size[1] / img.shape[1]) | |||||
# print(self.test_size[0] , img.shape[0], self.test_size[1] , img.shape[1]) | |||||
img_info["ratio"] = ratio | |||||
img, _ = self.preproc(img, None, self.test_size) | |||||
img = torch.from_numpy(img).unsqueeze(0) | |||||
img = img.float() | |||||
if self.device == "gpu": | |||||
img = img.cuda() | |||||
# if self.fp16: | |||||
# img = img.half() # to FP16 | |||||
with torch.no_grad(): | |||||
t0 = time.time() | |||||
outputs = self.model(img) | |||||
if self.decoder is not None: | |||||
outputs = self.decoder(outputs, dtype=outputs.type()) | |||||
outputs = postprocess( | |||||
outputs, self.num_classes, self.confthre, | |||||
self.nmsthre | |||||
) | |||||
# logger.info("Infer time: {:.4f}s".format(time.time() - t0)) | |||||
# print(img.shape) | |||||
_, _, tw, th = img.shape | |||||
img_info['tw'] = tw | |||||
img_info['th'] = th | |||||
return outputs, img_info | |||||
def visual(self, output, img_info, cls_conf=0.35): | |||||
ratio = img_info["ratio"] | |||||
img = img_info["raw_img"] | |||||
if output is None: | |||||
return img | |||||
output = output.cpu() | |||||
bboxes = output[:, 0:4] | |||||
# preprocessing: resize | |||||
bboxes /= ratio | |||||
cls = output[:, 6] | |||||
scores = output[:, 4] * output[:, 5] | |||||
vis_res = vis(img, bboxes, scores, cls, cls_conf, self.cls_names) | |||||
return vis_res | |||||
def image_demo(predictor, path): | |||||
folders = [f for f in listdir(path)] | |||||
# folders = folders[3:] | |||||
for folder in folders: | |||||
print(folder) | |||||
images_folder = join(join(path, folder), 'img1') | |||||
images = [f for f in listdir(images_folder) if isfile(join(images_folder, f))] | |||||
images = [a for a in images if a.endswith('.jpg')] | |||||
images.sort() | |||||
for i, image_name in enumerate(images): | |||||
if i % 300 == 0: | |||||
print(folder, i) | |||||
outputs, img_info = predictor.inference(join(images_folder, image_name)) | |||||
ratio = img_info["ratio"] | |||||
# print(ratio) | |||||
img = img_info["raw_img"] | |||||
output = outputs[0] | |||||
if output is None: | |||||
continue | |||||
output = output.cpu() | |||||
bboxes = output[:, 0:4] | |||||
# preprocessing: resize | |||||
bboxes /= ratio | |||||
cls = output[:, 6] | |||||
scores = output[:, 4] * output[:, 5] | |||||
# print('cls',cls) | |||||
labels0 = get_labels(bboxes, cls, scores, img_info["width"], img_info["height"]) | |||||
# out_path = join(images_folder, 'weak_' + imm + '.npy') | |||||
# print(imm) | |||||
np.savetxt(join(images_folder, image_name + '_weak_' + model_name + '.txt'), labels0, delimiter=' ') | |||||
def main(exp, ckpt_file): | |||||
model = exp.get_model() | |||||
if use_cuda: | |||||
model = model.cuda() | |||||
device = 'gpu' | |||||
else: | |||||
device = 'cpu' | |||||
model.eval() | |||||
logger.info("loading checkpoint") | |||||
ckpt = torch.load(ckpt_file, map_location="cpu") | |||||
# load the model state dict | |||||
model.load_state_dict(ckpt["model"]) | |||||
logger.info("loaded checkpoint done.") | |||||
if fuse: | |||||
logger.info("\tFusing model...") | |||||
model = fuse_model(model) | |||||
trt_file = None | |||||
decoder = None | |||||
predictor = Predictor( | |||||
model, exp, COCO_CLASSES, trt_file, decoder, | |||||
device, False, False, | |||||
) | |||||
current_time = time.localtime() | |||||
image_demo(predictor, root_dir) | |||||
model_name = 'yolox-x' | |||||
# cuda = torch.device('cuda:1') | |||||
if __name__ == "__main__": | |||||
# print(COCO_CLASSES) | |||||
# if use_cuda: | |||||
# torch.cuda.set_device(1) | |||||
# with torch.cuda.device(1): | |||||
# os.environ['CUDA_VISIBLE_DEVICES'] = '1' | |||||
ckpt_file = '/home/abdollahpour.ce.sharif/yolox_x.pth' | |||||
exp = get_exp(None, model_name) | |||||
main(exp, ckpt_file) |
# Mahdi Abdollahpour, 30/12/2021, 07:47 PM, PyCharm, ByteTrack | |||||
from yolox.core import launch | |||||
from yolox.data import MOTDataset, ValTransform, ValTransformWithPseudo | |||||
test_size = (896, 1600) | |||||
import os | |||||
from yolox.data import get_yolox_datadir | |||||
if __name__ == "__main__": | |||||
valdataset = MOTDataset( | |||||
data_dir=os.path.join(get_yolox_datadir(), "MOT20"), | |||||
json_file='train_MOT20-01.json', | |||||
img_size=test_size, | |||||
name='train', # change to train when running on training set | |||||
preproc=ValTransformWithPseudo( | |||||
rgb_means=(0.485, 0.456, 0.406), | |||||
std=(0.229, 0.224, 0.225), | |||||
), | |||||
load_weak=True | |||||
) | |||||
for batch in valdataset: | |||||
print(batch) | |||||
exit() |
import motmetrics as mm | import motmetrics as mm | ||||
from collections import OrderedDict | from collections import OrderedDict | ||||
from pathlib import Path | from pathlib import Path | ||||
import learn2learn as l2l | |||||
import yolox.statics as statics | |||||
def make_parser(): | def make_parser(): | ||||
parser.add_argument("-expn", "--experiment-name", type=str, default=None) | parser.add_argument("-expn", "--experiment-name", type=str, default=None) | ||||
parser.add_argument("-n", "--name", type=str, default=None, help="model name") | parser.add_argument("-n", "--name", type=str, default=None, help="model name") | ||||
parser.add_argument( | |||||
"--adaptation_period", default=4, type=int, help="if 4, then adapts to one batch in four batches" | |||||
) | |||||
# distributed | # distributed | ||||
parser.add_argument( | parser.add_argument( | ||||
"--dist-backend", default="nccl", type=str, help="distributed backend" | "--dist-backend", default="nccl", type=str, help="distributed backend" | ||||
parser.add_argument("--match_thresh", type=float, default=0.9, help="matching threshold for tracking") | parser.add_argument("--match_thresh", type=float, default=0.9, help="matching threshold for tracking") | ||||
parser.add_argument("--min-box-area", type=float, default=100, help='filter out tiny boxes') | parser.add_argument("--min-box-area", type=float, default=100, help='filter out tiny boxes') | ||||
parser.add_argument("--mot20", dest="mot20", default=False, action="store_true", help="test mot20.") | parser.add_argument("--mot20", dest="mot20", default=False, action="store_true", help="test mot20.") | ||||
parser.add_argument("--use_existing_files", default=False, action="store_true", help="to use already created files") | |||||
return parser | return parser | ||||
return accs, names | return accs, names | ||||
def process_loader(args, val_loader, model, is_distributed): | |||||
if args.seed is not None: | |||||
random.seed(args.seed) | |||||
torch.manual_seed(args.seed) | |||||
cudnn.deterministic = True | |||||
warnings.warn( | |||||
"You have chosen to seed testing. This will turn on the CUDNN deterministic setting, " | |||||
) | |||||
# set environment variables for distributed training | |||||
cudnn.benchmark = True | |||||
rank = args.local_rank | |||||
# rank = get_local_rank() | |||||
def process_loader(args, exp, val_loader, model, is_distributed, trt_file, decoder, val_ann): | |||||
file_name = os.path.join(exp.output_dir, args.experiment_name) | file_name = os.path.join(exp.output_dir, args.experiment_name) | ||||
rank = args.local_rank | |||||
if rank == 0: | if rank == 0: | ||||
os.makedirs(file_name, exist_ok=True) | os.makedirs(file_name, exist_ok=True) | ||||
results_folder = os.path.join(file_name, "track_results") | results_folder = os.path.join(file_name, "track_results") | ||||
os.makedirs(results_folder, exist_ok=True) | os.makedirs(results_folder, exist_ok=True) | ||||
setup_logger(file_name, distributed_rank=rank, filename="val_log.txt", mode="a") | |||||
logger.info("Args: {}".format(args)) | |||||
if args.conf is not None: | |||||
exp.test_conf = args.conf | |||||
if args.nms is not None: | |||||
exp.nmsthre = args.nms | |||||
if args.tsize is not None: | |||||
exp.test_size = (args.tsize, args.tsize) | |||||
adaptation_period = None | |||||
if args.task == 'metamot': | |||||
adaptation_period = args.adaptation_period | |||||
evaluator = MOTEvaluator( | evaluator = MOTEvaluator( | ||||
args=args, | args=args, | ||||
nmsthre=exp.nmsthre, | nmsthre=exp.nmsthre, | ||||
num_classes=exp.num_classes, | num_classes=exp.num_classes, | ||||
) | ) | ||||
torch.cuda.set_device(rank) | |||||
model.cuda(rank) | |||||
model.eval() | |||||
if not args.speed and not args.trt: | |||||
if args.ckpt is None: | |||||
ckpt_file = os.path.join(file_name, "best_ckpt.pth.tar") | |||||
else: | |||||
ckpt_file = args.ckpt | |||||
logger.info("loading checkpoint") | |||||
loc = "cuda:{}".format(rank) | |||||
ckpt = torch.load(ckpt_file, map_location=loc) | |||||
# load the model state dict | |||||
model.load_state_dict(ckpt["model"]) | |||||
logger.info("loaded checkpoint done.") | |||||
if is_distributed: | |||||
model = DDP(model, device_ids=[rank]) | |||||
if args.fuse: | |||||
logger.info("\tFusing model...") | |||||
model = fuse_model(model) | |||||
if args.trt: | |||||
assert ( | |||||
not args.fuse and not is_distributed and args.batch_size == 1 | |||||
), "TensorRT model is not support model fusing and distributed inferencing!" | |||||
trt_file = os.path.join(file_name, "model_trt.pth") | |||||
assert os.path.exists( | |||||
trt_file | |||||
), "TensorRT model is not found!\n Run tools/trt.py first!" | |||||
model.head.decode_in_inference = False | |||||
decoder = model.head.decode_outputs | |||||
else: | |||||
trt_file = None | |||||
decoder = None | |||||
# start evaluate | # start evaluate | ||||
*_, summary = evaluator.evaluate( | *_, summary = evaluator.evaluate( | ||||
model, is_distributed, args.fp16, trt_file, decoder, exp.test_size, results_folder | |||||
model, is_distributed, args.fp16, trt_file, decoder, exp.test_size, results_folder, | |||||
adaptation_period=adaptation_period, | |||||
) | ) | ||||
logger.info("\n" + summary) | logger.info("\n" + summary) | ||||
def eval_MOT(args, exp, val_ann=None): | |||||
file_name = os.path.join(exp.output_dir, args.experiment_name) | |||||
rank = args.local_rank | |||||
if rank == 0: | |||||
os.makedirs(file_name, exist_ok=True) | |||||
results_folder = os.path.join(file_name, "track_results") | |||||
os.makedirs(results_folder, exist_ok=True) | |||||
# evaluate MOTA | # evaluate MOTA | ||||
mm.lap.default_solver = 'lap' | mm.lap.default_solver = 'lap' | ||||
if exp.val_ann == 'val_half.json': | |||||
if val_ann == 'val_half.json': | |||||
gt_type = '_val_half' | gt_type = '_val_half' | ||||
else: | else: | ||||
gt_type = '' | gt_type = '' | ||||
print('gt_type', gt_type) | print('gt_type', gt_type) | ||||
if args.mot20: | if args.mot20: | ||||
gtfiles = glob.glob(os.path.join('datasets/MOT20/train', '*/gt/gt{}.txt'.format(gt_type))) | |||||
gtfiles = glob.glob(os.path.join(statics.DATA_PATH, 'MOT20/train', '*/gt/gt{}.txt'.format(gt_type))) | |||||
else: | else: | ||||
gtfiles = glob.glob(os.path.join('datasets/mot/train', '*/gt/gt{}.txt'.format(gt_type))) | |||||
gtfiles = glob.glob(os.path.join(statics.DATA_PATH, 'MOT17/train', '*/gt/gt{}.txt'.format(gt_type))) | |||||
print('gt_files', gtfiles) | print('gt_files', gtfiles) | ||||
tsfiles = [f for f in glob.glob(os.path.join(results_folder, '*.txt')) if | tsfiles = [f for f in glob.glob(os.path.join(results_folder, '*.txt')) if | ||||
not os.path.basename(f).startswith('eval')] | not os.path.basename(f).startswith('eval')] | ||||
logger.info('Completed') | logger.info('Completed') | ||||
def load_model(args, exp, is_distributed): | |||||
model = exp.get_model() | |||||
logger.info("Model Summary: {}".format(get_model_info(model, exp.test_size))) | |||||
if args.seed is not None: | |||||
random.seed(args.seed) | |||||
torch.manual_seed(args.seed) | |||||
cudnn.deterministic = True | |||||
warnings.warn( | |||||
"You have chosen to seed testing. This will turn on the CUDNN deterministic setting, " | |||||
) | |||||
# set environment variables for distributed training | |||||
cudnn.benchmark = True | |||||
rank = args.local_rank | |||||
# rank = get_local_rank() | |||||
file_name = os.path.join(exp.output_dir, args.experiment_name) | |||||
if rank == 0: | |||||
os.makedirs(file_name, exist_ok=True) | |||||
setup_logger(file_name, distributed_rank=rank, filename="val_log.txt", mode="a") | |||||
logger.info("Args: {}".format(args)) | |||||
if args.conf is not None: | |||||
exp.test_conf = args.conf | |||||
if args.nms is not None: | |||||
exp.nmsthre = args.nms | |||||
if args.tsize is not None: | |||||
exp.test_size = (args.tsize, args.tsize) | |||||
if args.task == "metamot": | |||||
model = l2l.algorithms.MAML(model, lr=exp.inner_lr, first_order=exp.first_order, allow_nograd=True) | |||||
torch.cuda.set_device(rank) | |||||
model.cuda(rank) | |||||
model.eval() | |||||
if not args.speed and not args.trt: | |||||
if args.ckpt is None: | |||||
ckpt_file = os.path.join(file_name, "best_ckpt.pth.tar") | |||||
else: | |||||
ckpt_file = args.ckpt | |||||
logger.info("loading checkpoint") | |||||
loc = "cuda:{}".format(rank) | |||||
ckpt = torch.load(ckpt_file, map_location=loc) | |||||
# handling meta models | |||||
new_dict = {} | |||||
if (not list(ckpt["model"].keys())[0].startswith('module')) and args.task == "metamot": | |||||
for key in ckpt["model"].keys(): | |||||
if not key.startswith('module.'): | |||||
new_dict['module.' + key] = ckpt["model"][key] | |||||
else: | |||||
new_dict[key] = ckpt["model"][key] | |||||
del ckpt["model"] | |||||
ckpt["model"] = new_dict | |||||
# load the model state dict | |||||
model.load_state_dict(ckpt["model"]) | |||||
logger.info("loaded checkpoint done.") | |||||
if is_distributed: | |||||
model = DDP(model, device_ids=[rank]) | |||||
if args.fuse: | |||||
logger.info("\tFusing model...") | |||||
model = fuse_model(model) | |||||
if args.trt: | |||||
assert ( | |||||
not args.fuse and not is_distributed and args.batch_size == 1 | |||||
), "TensorRT model is not support model fusing and distributed inferencing!" | |||||
trt_file = os.path.join(file_name, "model_trt.pth") | |||||
assert os.path.exists( | |||||
trt_file | |||||
), "TensorRT model is not found!\n Run tools/trt.py first!" | |||||
model.head.decode_in_inference = False | |||||
decoder = model.head.decode_outputs | |||||
else: | |||||
trt_file = None | |||||
decoder = None | |||||
return model, trt_file, decoder | |||||
@logger.catch | @logger.catch | ||||
def main(exp, args, num_gpu): | def main(exp, args, num_gpu): | ||||
is_distributed = num_gpu > 1 | is_distributed = num_gpu > 1 | ||||
print('is_distributed', is_distributed) | print('is_distributed', is_distributed) | ||||
print('num_gpu', num_gpu) | print('num_gpu', num_gpu) | ||||
model = exp.get_model() | |||||
logger.info("Model Summary: {}".format(get_model_info(model, exp.test_size))) | |||||
# logger.info("Model Structure:\n{}".format(str(model))) | # logger.info("Model Structure:\n{}".format(str(model))) | ||||
model, trt_file, decoder = load_model(args, exp, is_distributed) | |||||
if args.task == 'metamot': | if args.task == 'metamot': | ||||
val_loaders = exp.get_eval_loaders(args.batch_size, is_distributed, args.test) | val_loaders = exp.get_eval_loaders(args.batch_size, is_distributed, args.test) | ||||
for val_loader in val_loaders: | |||||
learner = model.clone() | |||||
process_loader(args, val_loader, learner, is_distributed) | |||||
if not args.use_existing_files: | |||||
for val_loader, val_ann in zip(val_loaders, exp.val_anns): | |||||
logger.info('processing loader...') | |||||
process_loader(args, exp, val_loader, model, is_distributed, trt_file, decoder, val_ann) | |||||
eval_MOT(args, exp) | |||||
else: | else: | ||||
val_loader = exp.get_eval_loader(args.batch_size, is_distributed, args.test) | |||||
process_loader(args, val_loader, model, is_distributed) | |||||
if not args.use_existing_files: | |||||
val_loader = exp.get_eval_loader(args.batch_size, is_distributed, args.test) | |||||
process_loader(args, exp, val_loader, model, is_distributed, trt_file, decoder, exp.val_ann) | |||||
eval_MOT(args, exp, exp.val_ann) | |||||
if __name__ == "__main__": | if __name__ == "__main__": |
self.after_train() | self.after_train() | ||||
def train_in_epoch(self): | def train_in_epoch(self): | ||||
# self.evaluate_and_save_model() | |||||
for self.epoch in range(self.start_epoch, self.max_epoch): | for self.epoch in range(self.start_epoch, self.max_epoch): | ||||
self.before_epoch() | self.before_epoch() | ||||
self.train_in_task() | self.train_in_task() | ||||
# self.model = model | # self.model = model | ||||
self.model.train() | self.model.train() | ||||
self.evaluator = self.exp.get_evaluator( | |||||
self.evaluators = self.exp.get_evaluators( | |||||
batch_size=self.args.batch_size, is_distributed=self.is_distributed | batch_size=self.args.batch_size, is_distributed=self.is_distributed | ||||
) | ) | ||||
# Tensorboard logger | # Tensorboard logger | ||||
ckpt = torch.load(ckpt_file, map_location=self.device) | ckpt = torch.load(ckpt_file, map_location=self.device) | ||||
# TODO: handle pretrained BYTETrack | |||||
# handling meta models | # handling meta models | ||||
# new_dict = {} | # new_dict = {} | ||||
# for key in ckpt["model"].keys(): | # for key in ckpt["model"].keys(): | ||||
return model | return model | ||||
def evaluate_and_save_model(self): | def evaluate_and_save_model(self): | ||||
logger.info("starting eval...") | |||||
evalmodel = self.ema_model.ema if self.use_model_ema else self.model | evalmodel = self.ema_model.ema if self.use_model_ema else self.model | ||||
ap50_95, ap50, summary = self.exp.eval( | ap50_95, ap50, summary = self.exp.eval( | ||||
evalmodel, self.evaluator, self.is_distributed | |||||
evalmodel, self.evaluators, self.is_distributed | |||||
) | ) | ||||
self.model.train() | self.model.train() | ||||
if self.rank == 0: | if self.rank == 0: |
# -*- coding:utf-8 -*- | # -*- coding:utf-8 -*- | ||||
# Copyright (c) Megvii, Inc. and its affiliates. | # Copyright (c) Megvii, Inc. and its affiliates. | ||||
from .data_augment import TrainTransform, ValTransform | |||||
from .data_augment import TrainTransform, ValTransform,ValTransformWithPseudo | |||||
from .data_prefetcher import DataPrefetcher | from .data_prefetcher import DataPrefetcher | ||||
from .dataloading import DataLoader, get_yolox_datadir | from .dataloading import DataLoader, get_yolox_datadir | ||||
from .datasets import * | from .datasets import * |
def __call__(self, img, res, input_size): | def __call__(self, img, res, input_size): | ||||
img, _ = preproc(img, input_size, self.means, self.std, self.swap) | img, _ = preproc(img, input_size, self.means, self.std, self.swap) | ||||
return img, np.zeros((1, 5)) | return img, np.zeros((1, 5)) | ||||
class ValTransformWithPseudo: | |||||
""" | |||||
Defines the transformations that should be applied to test PIL image | |||||
for input into the network | |||||
dimension -> tensorize -> color adj | |||||
Arguments: | |||||
resize (int): input dimension to SSD | |||||
rgb_means ((int,int,int)): average RGB of the dataset | |||||
(104,117,123) | |||||
swap ((int,int,int)): final order of channels | |||||
Returns: | |||||
transform (transform) : callable transform to be applied to test/val | |||||
data | |||||
""" | |||||
def __init__(self, rgb_means=None, std=None, swap=(2, 0, 1), max_labels=100): | |||||
self.means = rgb_means | |||||
self.swap = swap | |||||
self.std = std | |||||
self.max_labels = max_labels | |||||
def __call__(self, image, targets, input_dim): | |||||
boxes = targets[:, :4].copy() | |||||
labels = targets[:, 4].copy() | |||||
ids = targets[:, 5].copy() | |||||
if len(boxes) == 0: | |||||
targets = np.zeros((self.max_labels, 6), dtype=np.float32) | |||||
image, r_o = preproc(image, input_dim, self.means, self.std) | |||||
image = np.ascontiguousarray(image, dtype=np.float32) | |||||
return image, targets | |||||
image_o = image.copy() | |||||
targets_o = targets.copy() | |||||
height_o, width_o, _ = image_o.shape | |||||
boxes_o = targets_o[:, :4] | |||||
labels_o = targets_o[:, 4] | |||||
ids_o = targets_o[:, 5] | |||||
# bbox_o: [xyxy] to [c_x,c_y,w,h] | |||||
boxes_o = xyxy2cxcywh(boxes_o) | |||||
# image_t = _distort(image) | |||||
image_t = image | |||||
# image_t, boxes = _mirror(image_t, boxes) | |||||
height, width, _ = image_t.shape | |||||
image_t, r_ = preproc(image_t, input_dim, self.means, self.std) | |||||
# boxes [xyxy] 2 [cx,cy,w,h] | |||||
boxes = xyxy2cxcywh(boxes) | |||||
boxes *= r_ | |||||
mask_b = np.minimum(boxes[:, 2], boxes[:, 3]) > 1 | |||||
boxes_t = boxes[mask_b] | |||||
labels_t = labels[mask_b] | |||||
ids_t = ids[mask_b] | |||||
if len(boxes_t) == 0: | |||||
image_t, r_o = preproc(image_o, input_dim, self.means, self.std) | |||||
boxes_o *= r_o | |||||
boxes_t = boxes_o | |||||
labels_t = labels_o | |||||
ids_t = ids_o | |||||
labels_t = np.expand_dims(labels_t, 1) | |||||
ids_t = np.expand_dims(ids_t, 1) | |||||
targets_t = np.hstack((labels_t, boxes_t, ids_t)) | |||||
padded_labels = np.zeros((self.max_labels, 6)) | |||||
padded_labels[range(len(targets_t))[: self.max_labels]] = targets_t[ | |||||
: self.max_labels | |||||
] | |||||
padded_labels = np.ascontiguousarray(padded_labels, dtype=np.float32) | |||||
image_t = np.ascontiguousarray(image_t, dtype=np.float32) | |||||
return image_t, padded_labels | |||||
""" | """ | ||||
def __init__( | def __init__( | ||||
self, | |||||
data_dir=None, | |||||
json_file="train_half.json", | |||||
name="train", | |||||
img_size=(608, 1088), | |||||
preproc=None, | |||||
self, | |||||
data_dir=None, | |||||
json_file="train_half.json", | |||||
name="train", | |||||
img_size=(608, 1088), | |||||
preproc=None, | |||||
load_weak=False, | |||||
): | ): | ||||
""" | """ | ||||
COCO dataset initialization. Annotation data are read into memory by COCO API. | COCO dataset initialization. Annotation data are read into memory by COCO API. | ||||
self.name = name | self.name = name | ||||
self.img_size = img_size | self.img_size = img_size | ||||
self.preproc = preproc | self.preproc = preproc | ||||
self.load_weak = load_weak | |||||
def __len__(self): | def __len__(self): | ||||
return len(self.ids) | return len(self.ids) | ||||
img_file = os.path.join( | img_file = os.path.join( | ||||
self.data_dir, self.name, file_name | self.data_dir, self.name, file_name | ||||
) | ) | ||||
head_tail = os.path.split(img_file) | |||||
# label_path = os.path.join(head_tail[0], head_tail[1].replace('.jpg','.txt')) | |||||
if self.load_weak: | |||||
weak_label_path = os.path.join(head_tail[0], head_tail[1] + '_weak_yolox-x.txt') | |||||
# load weak labels from weak_label_path | |||||
width = img_info[1] | |||||
height = img_info[0] | |||||
labels = np.loadtxt(weak_label_path) | |||||
res = np.ones_like(labels) | |||||
labels[2, :] *= width | |||||
labels[4, :] *= width | |||||
labels[3, :] *= height | |||||
labels[5, :] *= height | |||||
labels[4, :] += labels[2, :] | |||||
labels[5, :] += labels[3, :] | |||||
res[:, 0:4] = labels[:, -4:] | |||||
res[:, 5] = labels[:, 1] | |||||
# all are from class one | |||||
# res[:, 4] = labels[:, 0] | |||||
img = cv2.imread(img_file) | img = cv2.imread(img_file) | ||||
# if img is None: | |||||
# print('img_file is None',img_file) | |||||
if img is None: | |||||
print('img_file is None', img_file) | |||||
assert img is not None | assert img is not None | ||||
return img, res.copy(), img_info, np.array([id_]) | return img, res.copy(), img_info, np.array([id_]) |
info = time_info + "\n" | info = time_info + "\n" | ||||
# Evaluate the Dt (detection) json comparing with the ground truth | |||||
# Evaluate the Dt (detection) jsoncomparing with the ground truth | |||||
if len(data_dict) > 0: | if len(data_dict) > 0: | ||||
cocoGt = self.dataloader.dataset.coco | cocoGt = self.dataloader.dataset.coco | ||||
# TODO: since pycocotools can't process dict in py36, write data to json file. | # TODO: since pycocotools can't process dict in py36, write data to json file. | ||||
from pycocotools import cocoeval as COCOeval | from pycocotools import cocoeval as COCOeval | ||||
logger.warning("Use standard COCOeval.") | logger.warning("Use standard COCOeval.") | ||||
''' | ''' | ||||
#from pycocotools.cocoeval import COCOeval | |||||
from yolox.layers import COCOeval_opt as COCOeval | |||||
# TODO: commenting this and trying to use pycocotools | |||||
from pycocotools.cocoeval import COCOeval | |||||
# from yolox.layers import COCOeval_opt as COCOeval | |||||
cocoEval = COCOeval(cocoGt, cocoDt, annType[1]) | cocoEval = COCOeval(cocoGt, cocoDt, annType[1]) | ||||
cocoEval.evaluate() | cocoEval.evaluate() | ||||
cocoEval.accumulate() | cocoEval.accumulate() |
if track_id < 0: | if track_id < 0: | ||||
continue | continue | ||||
x1, y1, w, h = tlwh | x1, y1, w, h = tlwh | ||||
line = save_format.format(frame=frame_id, id=track_id, x1=round(x1, 1), y1=round(y1, 1), w=round(w, 1), h=round(h, 1), s=round(score, 2)) | |||||
line = save_format.format(frame=frame_id, id=track_id, x1=round(x1, 1), y1=round(y1, 1), w=round(w, 1), | |||||
h=round(h, 1), s=round(score, 2)) | |||||
f.write(line) | f.write(line) | ||||
logger.info('save results to {}'.format(filename)) | logger.info('save results to {}'.format(filename)) | ||||
if track_id < 0: | if track_id < 0: | ||||
continue | continue | ||||
x1, y1, w, h = tlwh | x1, y1, w, h = tlwh | ||||
line = save_format.format(frame=frame_id, id=track_id, x1=round(x1, 1), y1=round(y1, 1), w=round(w, 1), h=round(h, 1)) | |||||
line = save_format.format(frame=frame_id, id=track_id, x1=round(x1, 1), y1=round(y1, 1), w=round(w, 1), | |||||
h=round(h, 1)) | |||||
f.write(line) | f.write(line) | ||||
logger.info('save results to {}'.format(filename)) | logger.info('save results to {}'.format(filename)) | ||||
""" | """ | ||||
def __init__( | def __init__( | ||||
self, args, dataloader, img_size, confthre, nmsthre, num_classes): | |||||
self, args, dataloader, img_size, confthre, nmsthre, num_classes): | |||||
""" | """ | ||||
Args: | Args: | ||||
dataloader (Dataloader): evaluate dataloader. | dataloader (Dataloader): evaluate dataloader. | ||||
self.args = args | self.args = args | ||||
def evaluate( | def evaluate( | ||||
self, | |||||
model, | |||||
distributed=False, | |||||
half=False, | |||||
trt_file=None, | |||||
decoder=None, | |||||
test_size=None, | |||||
result_folder=None | |||||
self, | |||||
model, | |||||
distributed=False, | |||||
half=False, | |||||
trt_file=None, | |||||
decoder=None, | |||||
test_size=None, | |||||
result_folder=None, | |||||
adaptation_period=None, | |||||
): | ): | ||||
""" | """ | ||||
COCO average precision (AP) Evaluation. Iterate inference on the test dataset | COCO average precision (AP) Evaluation. Iterate inference on the test dataset | ||||
ap50 (float) : COCO AP of IoU=50 | ap50 (float) : COCO AP of IoU=50 | ||||
summary (sr): summary info of evaluation. | summary (sr): summary info of evaluation. | ||||
""" | """ | ||||
if adaptation_period is not None: | |||||
logger.info('cloning model...') | |||||
learner = model.clone() | |||||
else: | |||||
learner = model | |||||
# TODO half to amp_test | # TODO half to amp_test | ||||
tensor_type = torch.cuda.HalfTensor if half else torch.cuda.FloatTensor | tensor_type = torch.cuda.HalfTensor if half else torch.cuda.FloatTensor | ||||
model = model.eval() | |||||
learner = learner.eval() | |||||
if half: | if half: | ||||
model = model.half() | |||||
learner = learner.half() | |||||
ids = [] | ids = [] | ||||
data_list = [] | data_list = [] | ||||
results = [] | results = [] | ||||
if trt_file is not None: | if trt_file is not None: | ||||
from torch2trt import TRTModule | from torch2trt import TRTModule | ||||
logger.info('Loading trt file') | |||||
model_trt = TRTModule() | model_trt = TRTModule() | ||||
model_trt.load_state_dict(torch.load(trt_file)) | model_trt.load_state_dict(torch.load(trt_file)) | ||||
x = torch.ones(1, 3, test_size[0], test_size[1]).cuda() | x = torch.ones(1, 3, test_size[0], test_size[1]).cuda() | ||||
model(x) | |||||
model = model_trt | |||||
learner(x) | |||||
learner = model_trt | |||||
tracker = BYTETracker(self.args) | tracker = BYTETracker(self.args) | ||||
ori_thresh = self.args.track_thresh | ori_thresh = self.args.track_thresh | ||||
for cur_iter, (imgs, _, info_imgs, ids) in enumerate( | |||||
progress_bar(self.dataloader) | |||||
): | |||||
with torch.no_grad(): | |||||
# init tracker | |||||
frame_id = info_imgs[2].item() | |||||
video_id = info_imgs[3].item() | |||||
img_file_name = info_imgs[4] | |||||
video_name = img_file_name[0].split('/')[0] | |||||
if video_name == 'MOT17-05-FRCNN' or video_name == 'MOT17-06-FRCNN': | |||||
self.args.track_buffer = 14 | |||||
elif video_name == 'MOT17-13-FRCNN' or video_name == 'MOT17-14-FRCNN': | |||||
self.args.track_buffer = 25 | |||||
else: | |||||
self.args.track_buffer = 30 | |||||
if video_name == 'MOT17-01-FRCNN': | |||||
self.args.track_thresh = 0.65 | |||||
elif video_name == 'MOT17-06-FRCNN': | |||||
self.args.track_thresh = 0.65 | |||||
elif video_name == 'MOT17-12-FRCNN': | |||||
self.args.track_thresh = 0.7 | |||||
elif video_name == 'MOT17-14-FRCNN': | |||||
self.args.track_thresh = 0.67 | |||||
else: | |||||
self.args.track_thresh = ori_thresh | |||||
if video_name == 'MOT20-06' or video_name == 'MOT20-08': | |||||
self.args.track_thresh = 0.3 | |||||
else: | |||||
self.args.track_thresh = ori_thresh | |||||
if video_name not in video_names: | |||||
video_names[video_id] = video_name | |||||
if frame_id == 1: | |||||
tracker = BYTETracker(self.args) | |||||
if len(results) != 0: | |||||
result_filename = os.path.join(result_folder, '{}.txt'.format(video_names[video_id - 1])) | |||||
write_results(result_filename, results) | |||||
results = [] | |||||
imgs = imgs.type(tensor_type) | |||||
for cur_iter, (imgs, targets, info_imgs, ids) in enumerate( | |||||
progress_bar(self.dataloader) | |||||
): | |||||
if cur_iter % 100 == 0: | |||||
logger.info('cur_iter: {}'.format(cur_iter)) | |||||
# with torch.no_grad(): | |||||
# init tracker | |||||
# imgs = imgs.to(self.data_type) | |||||
# targets = targets.to(self.data_type) | |||||
frame_id = info_imgs[2].item() | |||||
video_id = info_imgs[3].item() | |||||
img_file_name = info_imgs[4] | |||||
video_name = img_file_name[0].split('/')[0] | |||||
if video_name == 'MOT17-05-FRCNN' or video_name == 'MOT17-06-FRCNN': | |||||
self.args.track_buffer = 14 | |||||
elif video_name == 'MOT17-13-FRCNN' or video_name == 'MOT17-14-FRCNN': | |||||
self.args.track_buffer = 25 | |||||
else: | |||||
self.args.track_buffer = 30 | |||||
if video_name == 'MOT17-01-FRCNN': | |||||
self.args.track_thresh = 0.65 | |||||
elif video_name == 'MOT17-06-FRCNN': | |||||
self.args.track_thresh = 0.65 | |||||
elif video_name == 'MOT17-12-FRCNN': | |||||
self.args.track_thresh = 0.7 | |||||
elif video_name == 'MOT17-14-FRCNN': | |||||
self.args.track_thresh = 0.67 | |||||
else: | |||||
self.args.track_thresh = ori_thresh | |||||
if video_name == 'MOT20-06' or video_name == 'MOT20-08': | |||||
self.args.track_thresh = 0.3 | |||||
else: | |||||
self.args.track_thresh = ori_thresh | |||||
if video_name not in video_names: | |||||
video_names[video_id] = video_name | |||||
if frame_id == 1: | |||||
tracker = BYTETracker(self.args) | |||||
if len(results) != 0: | |||||
result_filename = os.path.join(result_folder, '{}.txt'.format(video_names[video_id - 1])) | |||||
write_results(result_filename, results) | |||||
results = [] | |||||
imgs = imgs.type(tensor_type) | |||||
# skip the the last iters since batchsize might be not enough for batch inference | |||||
is_time_record = cur_iter < len(self.dataloader) - 1 | |||||
if is_time_record: | |||||
start = time.time() | |||||
if adaptation_period is not None and cur_iter % adaptation_period == 0: | |||||
learner.train() | |||||
targets = targets.type(tensor_type) | |||||
targets.requires_grad = False | |||||
outputs = learner(imgs, targets) | |||||
loss = outputs["total_loss"] | |||||
learner.adapt(loss) | |||||
learner.eval() | |||||
# skip the the last iters since batchsize might be not enough for batch inference | |||||
is_time_record = cur_iter < len(self.dataloader) - 1 | |||||
if is_time_record: | |||||
start = time.time() | |||||
with torch.no_grad(): | |||||
outputs = learner(imgs) | |||||
outputs = model(imgs) | |||||
if decoder is not None: | |||||
outputs = decoder(outputs, dtype=outputs.type()) | |||||
# print('outputs', outputs.shape) | |||||
outputs = postprocess(outputs, self.num_classes, self.confthre, self.nmsthre) | |||||
if decoder is not None: | |||||
outputs = decoder(outputs, dtype=outputs.type()) | |||||
print('outputs', outputs.shape) | |||||
outputs = postprocess(outputs, self.num_classes, self.confthre, self.nmsthre) | |||||
if is_time_record: | |||||
infer_end = time_synchronized() | |||||
inference_time += infer_end - start | |||||
if is_time_record: | |||||
infer_end = time_synchronized() | |||||
inference_time += infer_end - start | |||||
output_results = self.convert_to_coco_format(outputs, info_imgs, ids) | output_results = self.convert_to_coco_format(outputs, info_imgs, ids) | ||||
data_list.extend(output_results) | data_list.extend(output_results) | ||||
if is_time_record: | if is_time_record: | ||||
track_end = time_synchronized() | track_end = time_synchronized() | ||||
track_time += track_end - infer_end | track_time += track_end - infer_end | ||||
if cur_iter == len(self.dataloader) - 1: | if cur_iter == len(self.dataloader) - 1: | ||||
result_filename = os.path.join(result_folder, '{}.txt'.format(video_names[video_id])) | result_filename = os.path.join(result_folder, '{}.txt'.format(video_names[video_id])) | ||||
write_results(result_filename, results) | write_results(result_filename, results) | ||||
return eval_results | return eval_results | ||||
def evaluate_sort( | def evaluate_sort( | ||||
self, | |||||
model, | |||||
distributed=False, | |||||
half=False, | |||||
trt_file=None, | |||||
decoder=None, | |||||
test_size=None, | |||||
result_folder=None | |||||
self, | |||||
model, | |||||
distributed=False, | |||||
half=False, | |||||
trt_file=None, | |||||
decoder=None, | |||||
test_size=None, | |||||
result_folder=None | |||||
): | ): | ||||
""" | """ | ||||
COCO average precision (AP) Evaluation. Iterate inference on the test dataset | COCO average precision (AP) Evaluation. Iterate inference on the test dataset | ||||
x = torch.ones(1, 3, test_size[0], test_size[1]).cuda() | x = torch.ones(1, 3, test_size[0], test_size[1]).cuda() | ||||
model(x) | model(x) | ||||
model = model_trt | model = model_trt | ||||
tracker = Sort(self.args.track_thresh) | tracker = Sort(self.args.track_thresh) | ||||
for cur_iter, (imgs, _, info_imgs, ids) in enumerate( | for cur_iter, (imgs, _, info_imgs, ids) in enumerate( | ||||
progress_bar(self.dataloader) | |||||
progress_bar(self.dataloader) | |||||
): | ): | ||||
if cur_iter % 250 == 0: | |||||
logger.info('cur_iter: {}'.format(cur_iter)) | |||||
with torch.no_grad(): | with torch.no_grad(): | ||||
# init tracker | # init tracker | ||||
frame_id = info_imgs[2].item() | frame_id = info_imgs[2].item() | ||||
outputs = decoder(outputs, dtype=outputs.type()) | outputs = decoder(outputs, dtype=outputs.type()) | ||||
outputs = postprocess(outputs, self.num_classes, self.confthre, self.nmsthre) | outputs = postprocess(outputs, self.num_classes, self.confthre, self.nmsthre) | ||||
if is_time_record: | if is_time_record: | ||||
infer_end = time_synchronized() | infer_end = time_synchronized() | ||||
inference_time += infer_end - start | inference_time += infer_end - start | ||||
if is_time_record: | if is_time_record: | ||||
track_end = time_synchronized() | track_end = time_synchronized() | ||||
track_time += track_end - infer_end | track_time += track_end - infer_end | ||||
if cur_iter == len(self.dataloader) - 1: | if cur_iter == len(self.dataloader) - 1: | ||||
result_filename = os.path.join(result_folder, '{}.txt'.format(video_names[video_id])) | result_filename = os.path.join(result_folder, '{}.txt'.format(video_names[video_id])) | ||||
write_results_no_score(result_filename, results) | write_results_no_score(result_filename, results) | ||||
return eval_results | return eval_results | ||||
def evaluate_deepsort( | def evaluate_deepsort( | ||||
self, | |||||
model, | |||||
distributed=False, | |||||
half=False, | |||||
trt_file=None, | |||||
decoder=None, | |||||
test_size=None, | |||||
result_folder=None, | |||||
model_folder=None | |||||
self, | |||||
model, | |||||
distributed=False, | |||||
half=False, | |||||
trt_file=None, | |||||
decoder=None, | |||||
test_size=None, | |||||
result_folder=None, | |||||
model_folder=None | |||||
): | ): | ||||
""" | """ | ||||
COCO average precision (AP) Evaluation. Iterate inference on the test dataset | COCO average precision (AP) Evaluation. Iterate inference on the test dataset | ||||
x = torch.ones(1, 3, test_size[0], test_size[1]).cuda() | x = torch.ones(1, 3, test_size[0], test_size[1]).cuda() | ||||
model(x) | model(x) | ||||
model = model_trt | model = model_trt | ||||
tracker = DeepSort(model_folder, min_confidence=self.args.track_thresh) | tracker = DeepSort(model_folder, min_confidence=self.args.track_thresh) | ||||
for cur_iter, (imgs, _, info_imgs, ids) in enumerate( | for cur_iter, (imgs, _, info_imgs, ids) in enumerate( | ||||
progress_bar(self.dataloader) | |||||
progress_bar(self.dataloader) | |||||
): | ): | ||||
with torch.no_grad(): | with torch.no_grad(): | ||||
# init tracker | # init tracker | ||||
outputs = decoder(outputs, dtype=outputs.type()) | outputs = decoder(outputs, dtype=outputs.type()) | ||||
outputs = postprocess(outputs, self.num_classes, self.confthre, self.nmsthre) | outputs = postprocess(outputs, self.num_classes, self.confthre, self.nmsthre) | ||||
if is_time_record: | if is_time_record: | ||||
infer_end = time_synchronized() | infer_end = time_synchronized() | ||||
inference_time += infer_end - start | inference_time += infer_end - start | ||||
if is_time_record: | if is_time_record: | ||||
track_end = time_synchronized() | track_end = time_synchronized() | ||||
track_time += track_end - infer_end | track_time += track_end - infer_end | ||||
if cur_iter == len(self.dataloader) - 1: | if cur_iter == len(self.dataloader) - 1: | ||||
result_filename = os.path.join(result_folder, '{}.txt'.format(video_names[video_id])) | result_filename = os.path.join(result_folder, '{}.txt'.format(video_names[video_id])) | ||||
write_results_no_score(result_filename, results) | write_results_no_score(result_filename, results) | ||||
return eval_results | return eval_results | ||||
def evaluate_motdt( | def evaluate_motdt( | ||||
self, | |||||
model, | |||||
distributed=False, | |||||
half=False, | |||||
trt_file=None, | |||||
decoder=None, | |||||
test_size=None, | |||||
result_folder=None, | |||||
model_folder=None | |||||
self, | |||||
model, | |||||
distributed=False, | |||||
half=False, | |||||
trt_file=None, | |||||
decoder=None, | |||||
test_size=None, | |||||
result_folder=None, | |||||
model_folder=None | |||||
): | ): | ||||
""" | """ | ||||
COCO average precision (AP) Evaluation. Iterate inference on the test dataset | COCO average precision (AP) Evaluation. Iterate inference on the test dataset | ||||
x = torch.ones(1, 3, test_size[0], test_size[1]).cuda() | x = torch.ones(1, 3, test_size[0], test_size[1]).cuda() | ||||
model(x) | model(x) | ||||
model = model_trt | model = model_trt | ||||
tracker = OnlineTracker(model_folder, min_cls_score=self.args.track_thresh) | tracker = OnlineTracker(model_folder, min_cls_score=self.args.track_thresh) | ||||
for cur_iter, (imgs, _, info_imgs, ids) in enumerate( | for cur_iter, (imgs, _, info_imgs, ids) in enumerate( | ||||
progress_bar(self.dataloader) | |||||
progress_bar(self.dataloader) | |||||
): | ): | ||||
with torch.no_grad(): | with torch.no_grad(): | ||||
# init tracker | # init tracker | ||||
outputs = decoder(outputs, dtype=outputs.type()) | outputs = decoder(outputs, dtype=outputs.type()) | ||||
outputs = postprocess(outputs, self.num_classes, self.confthre, self.nmsthre) | outputs = postprocess(outputs, self.num_classes, self.confthre, self.nmsthre) | ||||
if is_time_record: | if is_time_record: | ||||
infer_end = time_synchronized() | infer_end = time_synchronized() | ||||
inference_time += infer_end - start | inference_time += infer_end - start | ||||
if is_time_record: | if is_time_record: | ||||
track_end = time_synchronized() | track_end = time_synchronized() | ||||
track_time += track_end - infer_end | track_time += track_end - infer_end | ||||
if cur_iter == len(self.dataloader) - 1: | if cur_iter == len(self.dataloader) - 1: | ||||
result_filename = os.path.join(result_folder, '{}.txt'.format(video_names[video_id])) | result_filename = os.path.join(result_folder, '{}.txt'.format(video_names[video_id])) | ||||
write_results(result_filename, results) | write_results(result_filename, results) | ||||
def convert_to_coco_format(self, outputs, info_imgs, ids): | def convert_to_coco_format(self, outputs, info_imgs, ids): | ||||
data_list = [] | data_list = [] | ||||
for (output, img_h, img_w, img_id) in zip( | for (output, img_h, img_w, img_id) in zip( | ||||
outputs, info_imgs[0], info_imgs[1], ids | |||||
outputs, info_imgs[0], info_imgs[1], ids | |||||
): | ): | ||||
if output is None: | if output is None: | ||||
continue | continue | ||||
[ | [ | ||||
"Average {} time: {:.2f} ms".format(k, v) | "Average {} time: {:.2f} ms".format(k, v) | ||||
for k, v in zip( | for k, v in zip( | ||||
["forward", "track", "inference"], | |||||
[a_infer_time, a_track_time, (a_infer_time + a_track_time)], | |||||
) | |||||
["forward", "track", "inference"], | |||||
[a_infer_time, a_track_time, (a_infer_time + a_track_time)], | |||||
) | |||||
] | ] | ||||
) | ) | ||||
from pycocotools import cocoeval as COCOeval | from pycocotools import cocoeval as COCOeval | ||||
logger.warning("Use standard COCOeval.") | logger.warning("Use standard COCOeval.") | ||||
''' | ''' | ||||
#from pycocotools.cocoeval import COCOeval | |||||
from yolox.layers import COCOeval_opt as COCOeval | |||||
# I changed it | |||||
from pycocotools.cocoeval import COCOeval | |||||
# from yolox.layers import COCOeval_opt as COCOeval | |||||
cocoEval = COCOeval(cocoGt, cocoDt, annType[1]) | cocoEval = COCOeval(cocoGt, cocoDt, annType[1]) | ||||
cocoEval.evaluate() | cocoEval.evaluate() | ||||
cocoEval.accumulate() | cocoEval.accumulate() |
self.seed = None | self.seed = None | ||||
# self.output_dir = "./YOLOX_outputs" | # self.output_dir = "./YOLOX_outputs" | ||||
self.output_dir = "./meta_experiments" | self.output_dir = "./meta_experiments" | ||||
self.print_interval = 100 | |||||
self.print_interval = 250 | |||||
self.eval_interval = 10 | self.eval_interval = 10 | ||||
@abstractmethod | @abstractmethod |
# ----------------- Meta-learning ------------------ # | # ----------------- Meta-learning ------------------ # | ||||
self.first_order = True | self.first_order = True | ||||
self.inner_lr = 1e-5 | |||||
self.inner_lr = 1e-6 | |||||
def get_model(self): | def get_model(self): | ||||
from yolox.models import YOLOPAFPN, YOLOX, YOLOXHead | from yolox.models import YOLOPAFPN, YOLOX, YOLOXHead | ||||
val_loaders.append(val_loader) | val_loaders.append(val_loader) | ||||
return val_loaders | return val_loaders | ||||
def get_evaluator(self, batch_size, is_distributed, testdev=False): | |||||
def get_evaluators(self, batch_size, is_distributed, testdev=False): | |||||
from yolox.evaluators import COCOEvaluator | from yolox.evaluators import COCOEvaluator | ||||
val_loader = self.get_eval_loader(batch_size, is_distributed, testdev=testdev) | |||||
evaluator = COCOEvaluator( | |||||
dataloader=val_loader, | |||||
img_size=self.test_size, | |||||
confthre=self.test_conf, | |||||
nmsthre=self.nmsthre, | |||||
num_classes=self.num_classes, | |||||
testdev=testdev, | |||||
) | |||||
return evaluator | |||||
def eval(self, model, evaluator, is_distributed, half=False): | |||||
return evaluator.evaluate(model, is_distributed, half) | |||||
val_loaders = self.get_eval_loaders(batch_size, is_distributed, testdev=testdev) | |||||
evaluators = [] | |||||
for val_loader in val_loaders: | |||||
evaluator = COCOEvaluator( | |||||
dataloader=val_loader, | |||||
img_size=self.test_size, | |||||
confthre=self.test_conf, | |||||
nmsthre=self.nmsthre, | |||||
num_classes=self.num_classes, | |||||
testdev=testdev, | |||||
) | |||||
evaluators.append(evaluator) | |||||
return evaluators | |||||
def eval(self, model, evaluators, is_distributed, half=False): | |||||
ap50_95s = 0.0 | |||||
ap50s = 0.0 | |||||
summarys = '' | |||||
for evaluator in evaluators: | |||||
ap50_95, ap50, summary = evaluator.evaluate(model, is_distributed, half) | |||||
ap50_95s += ap50_95 | |||||
ap50s += ap50 | |||||
summarys += ("\n" + summary) | |||||
n = len(evaluators) | |||||
return (ap50_95s / n), (ap50s / n), summarys |
if self.training: | if self.training: | ||||
# logger.info("labels.shape:{}".format(labels.shape)) | # logger.info("labels.shape:{}".format(labels.shape)) | ||||
# logger.info("torch.cat(outputs, 1).shape:{}".format(torch.cat(outputs, 1).shape)) | # logger.info("torch.cat(outputs, 1).shape:{}".format(torch.cat(outputs, 1).shape)) | ||||
# if torch.isnan(torch.cat(outputs, 1)).sum().item(): | |||||
# logger.info('There is Nan value in outputs {}'.format(torch.isnan(torch.cat(outputs, 1)).sum().item())) | |||||
return self.get_losses( | return self.get_losses( | ||||
imgs, | imgs, | ||||
x_shifts, | x_shifts, | ||||
if self.use_l1: | if self.use_l1: | ||||
l1_targets = torch.cat(l1_targets, 0) | l1_targets = torch.cat(l1_targets, 0) | ||||
# TODO: check loss parts shapes | # TODO: check loss parts shapes | ||||
num_fg = max(num_fg, 1) | num_fg = max(num_fg, 1) | ||||
# if bbox_preds.view(-1, 4)[fg_masks].shape != reg_targets.shape: | |||||
# logger.info("some shape mismatch") | |||||
# logger.info("bbox_preds.view(-1, 4)[fg_masks].shape {}".format(bbox_preds.view(-1, 4)[fg_masks].shape)) | |||||
# logger.info("reg_targets {}".format(reg_targets.shape)) | |||||
# logger.info("--------------------") | |||||
loss_iou = ( | loss_iou = ( | ||||
self.iou_loss(bbox_preds.view(-1, 4)[fg_masks], reg_targets) | self.iou_loss(bbox_preds.view(-1, 4)[fg_masks], reg_targets) | ||||
).sum() / num_fg | ).sum() / num_fg | ||||
# if obj_preds.view(-1, 1).shape != obj_targets.shape: | |||||
# logger.info("some shape mismatch") | |||||
# logger.info("obj_preds.view(-1, 1).shape {}".format(obj_preds.view(-1, 1).shape)) | |||||
# logger.info("obj_targets.shape {}".format(obj_targets.shape)) | |||||
# logger.info("--------------------") | |||||
loss_obj = ( | loss_obj = ( | ||||
self.bcewithlog_loss(obj_preds.view(-1, 1), obj_targets) | self.bcewithlog_loss(obj_preds.view(-1, 1), obj_targets) | ||||
).sum() / num_fg | ).sum() / num_fg | ||||
# if cls_preds.view(-1, self.num_classes)[fg_masks].shape != cls_targets.shape: | |||||
# logger.info("some shape mismatch") | |||||
# logger.info("cls_preds.view(-1, self.num_classes)[fg_masks].shape {}".format( | |||||
# cls_preds.view(-1, self.num_classes)[fg_masks].shape)) | |||||
# logger.info("cls_targets.shape {}".format(cls_targets.shape)) | |||||
# logger.info("--------------------") | |||||
loss_cls = ( | loss_cls = ( | ||||
self.bcewithlog_loss( | self.bcewithlog_loss( | ||||
cls_preds.view(-1, self.num_classes)[fg_masks], cls_targets | cls_preds.view(-1, self.num_classes)[fg_masks], cls_targets | ||||
) | ) | ||||
).sum() / num_fg | ).sum() / num_fg | ||||
if self.use_l1: | if self.use_l1: | ||||
# if origin_preds.view(-1, 4)[fg_masks].shape != l1_targets.shape: | |||||
# logger.info("some shape mismatch") | |||||
# logger.info("origin_preds.view(-1, 4)[fg_masks].shape {}".format( | |||||
# origin_preds.view(-1, 4)[fg_masks].shape)) | |||||
# logger.info("l1_targets.shape {}".format(l1_targets.shape)) | |||||
# logger.info("--------------------") | |||||
loss_l1 = ( | loss_l1 = ( | ||||
self.l1_loss(origin_preds.view(-1, 4)[fg_masks], l1_targets) | self.l1_loss(origin_preds.view(-1, 4)[fg_masks], l1_targets) | ||||
).sum() / num_fg | ).sum() / num_fg | ||||
imgs, | imgs, | ||||
mode="gpu", | mode="gpu", | ||||
): | ): | ||||
# TODO: check loss mismatches here | |||||
if mode == "cpu": | if mode == "cpu": | ||||
print("------------CPU Mode for This Batch-------------") | print("------------CPU Mode for This Batch-------------") | ||||
gt_bboxes_per_image = gt_bboxes_per_image.cpu().float() | gt_bboxes_per_image = gt_bboxes_per_image.cpu().float() | ||||
num_gt, | num_gt, | ||||
img_size | img_size | ||||
) | ) | ||||
# if torch.isnan(cls_preds).sum().item() or torch.isnan(obj_preds).sum().item() or torch.isnan( | |||||
# bboxes_preds_per_image).sum().item(): | |||||
# logger.info("cls_preds is Nan {}".format(torch.isnan(cls_preds).sum().item())) | |||||
# logger.info("obj_preds is Nan {}".format(torch.isnan(obj_preds).sum().item())) | |||||
# logger.info("bboxes_preds_per_image is Nan {}".format(torch.isnan(bboxes_preds_per_image).sum().item())) | |||||
bboxes_preds_per_image = bboxes_preds_per_image[fg_mask] | bboxes_preds_per_image = bboxes_preds_per_image[fg_mask] | ||||
cls_preds_ = cls_preds[batch_idx][fg_mask] | cls_preds_ = cls_preds[batch_idx][fg_mask] | ||||
.unsqueeze(1) | .unsqueeze(1) | ||||
.repeat(1, num_in_boxes_anchor, 1) | .repeat(1, num_in_boxes_anchor, 1) | ||||
) | ) | ||||
pair_wise_ious_loss = -torch.log(pair_wise_ious + 1e-8) | |||||
pair_wise_ious_loss = -torch.log(pair_wise_ious + 1e-8) | |||||
# if torch.isnan(pair_wise_ious_loss).sum().item(): | |||||
# logger.info("pair_wise_ious_loss is Nan {}".format(torch.isnan(pair_wise_ious_loss).sum().item())) | |||||
if mode == "cpu": | if mode == "cpu": | ||||
cls_preds_, obj_preds_ = cls_preds_.cpu(), obj_preds_.cpu() | cls_preds_, obj_preds_ = cls_preds_.cpu(), obj_preds_.cpu() | ||||
cls_preds_.float().unsqueeze(0).repeat(num_gt, 1, 1).sigmoid_() | cls_preds_.float().unsqueeze(0).repeat(num_gt, 1, 1).sigmoid_() | ||||
* obj_preds_.float().unsqueeze(0).repeat(num_gt, 1, 1).sigmoid_() | * obj_preds_.float().unsqueeze(0).repeat(num_gt, 1, 1).sigmoid_() | ||||
) | ) | ||||
pair_wise_cls_loss = F.binary_cross_entropy( | pair_wise_cls_loss = F.binary_cross_entropy( | ||||
cls_preds_.sqrt_(), gt_cls_per_image, reduction="none" | cls_preds_.sqrt_(), gt_cls_per_image, reduction="none" | ||||
).sum(-1) | ).sum(-1) |