Trackformer
Trackformer is an end-to-end object tracking model. You can find the source code inside the trackformer directory of this project.
You cn find the source code we used for training the trackformer model in the repositories/trackformer directory of this Git repository.
Environment
Trackformer was built to run in an environment where Python 3.7.x should be installed. There are several options for initializing such an environment on your system. We will show you two ways how you can setup this environment on your machine using Conda or Docker.
Setup with WSL
You can setup Trackformer in a WSL environment under Windows. We have a separate article in this documentation about installing Linux CUDA environments under Windows. Follow the steps of this article and then follow the installation process described below for Conda environments.
Setup with Docker on Windows
It is possible to run Trackformer inside a Docker container on Windows. We will explain the stept for creating the Docker image and how to run this Docker image in the following section.
Spine dataset
Place the Spine MOT dataset in this directory: data/spine. The directory structure should now look like this:
data
|- spine
|- annotations
|- test.json
|- train.json
|- val.json
|- test
|- <stack_name>
|- det
|- gt
|- img
|- seqinfo.ini
|- <stack_name>
|- ...
|- train
|- <stack_name>
|- det
|- gt
|- img
|- seqinfo.ini
|- <stack_name>
|- ...
|- val
|- <stack_name>
|- det
|- gt
|- img
|- seqinfo.ini
|- <stack_name>
|- ...
Build the Docker image
First we need to build the docker image. We have included a Dockerfile inside this repository under trackformer/Dockerfile. For building the image run the following command:
$ docker build -t tnodecode/trackformer-base
This process can take a while because the base image used is very large. After the command has finished you can now create an instance of this docker image and open its shell with the following command:
docker run \
-it \
--gpus all \
--shm-size=16gb \
--rm \
tnodecode/trackformer-base \
bash
Your terminal should now look like this:
root@3139f5fc0c8d:/app#
This means you are using the shell of your docker container. It is similar to connecting to a remote machine via SSH.
Now we have created a Docker image that contains a PyTorch runtime together with the CUDA development tools which are needed for compiling the CUDA operators provided in src/trackformer/models/ops. Unfortunately Docker cannot access the GPU during image built time, so we have install the CUDA runtime and compie the operators via the Docker container shell.
In the docker container shell run the following two commands and DO NOT CLOSE the shell afterwards.
# First switch to the conda trackformer environment inside the container
$ conda init
$ source ~/.bashrc
$ conda activate trackformer
# Install NVIDIA CUDA toolkit
$ apt-get install -y nvidia-cuda-dev nvidia-cuda-toolkit
# Compile the operators
$ python src/trackformer/models/ops/setup.py build --build-base=src/trackformer/models/ops/ install
# Update numpy, scipy and pandas
$ pip install -U numpy scipy pandas
When both commands are executed open a second terminal while the docker shell is still opened. In the second terminal type docker ps to get a list of all running docker containers. Find the container that you started and its name (clever_bhabha in this case).
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3139f5fc0c8d tnodecode/trackformer-base "bash" 2 minutes ago Up 2 minutes clever_bhabha
Now we want to create a new docker image based on our currently running container. We can do this with the following command:
$ docker commit clever_bhabha tnodecode/trackformer
This will create a new docker image with tag tnodecode/trackformer based on the container with the name clever_bhabha. After this command you can close the docker container shell in the first terminal by simply typing "exit" and pressing enter.
Now you can create a container that is based on our new image by executing the following command:
$ docker run \
-it \
--gpus all \
--shm-size=16gb \
--rm \
tnodecode/trackformer \
bash
Train model on Windows with Docker
Now that we have built the image we can start training a Trackformer model. First download the pretrained models and place them inside the models directory. Then place the dataset inside the data/spine directory. Also create a directory named checkpoints where trackformer will store the ResNet50 or ResNet101 pretrained models.
Now you can run the following command:
docker run \
--gpus all \
--shm-size=16gb \
--rm \
-v $PWD/cfgs:/app/cfgs \
-v $PWD/data:/app/data \
-v $PWD/models:/app/models \
-v $PWD/src:/app/src \
-v $PWD/checkpoints:/root/.cache/torch/hub/checkpoints \
tnodecode/trackformer \
conda run --no-capture-output -n trackformer \
python src/train.py with \
mot17 \
deformable \
multi_frame \
tracking \
device=cuda:0 \
output_dir=checkpoints/custom_dataset_deformable \
mot_path_train=data/spine \
mot_path_val=data/spine \
train_split=train \
val_split=val \
epochs=20 \
The option -v $PWD/cfgs:/app/cfgs maps a directory from Windows into the container. PWD is the absolute path of your project (C:/Users//root/.cache/torch/hub/checkpoints inside the container stores the downloaded models from Torch Hub. If we wouldn't map this directory to the checkpoints directory of our project the conainer woud download the model each time we restart the container because its filesystem is not persisted on the disk.
Train a model on a Linux machine
Training the model on a linux machine can be done by the following command:
python src/train.py with \
mot17 \
deformable \
multi_frame \
tracking \
device=cuda:0 \
output_dir=checkpoints/custom_dataset_deformable \
mot_path_train=data/spine \
mot_path_val=data/spine \
train_split=train \
val_split=val \
epochs=20 \
We also created a script named train_custom.sh in the root directory of the trackformer repository which contains this command.
Inference
Inference for all stacks of a dataset for all splits can be done with the following bash script:
export DATASET=spine # dataset name
export SUBDIR=run_1 # subdir in checkpoints dir
for MODEL_NAME in MOTA IDF1 BBOX_AP_IoU_0_50
do
for SPLIT in train val test
do
for file in ./data/$DATASET/$SPLIT/*
do
if [ -d "$file" ]; then
STACK_NAME="$(basename -- $file)"
echo "Processing" $SPLIT $STACK_NAME "..."
python src/track.py with \
dataset_name=$STACK_NAME \
obj_detect_checkpoint_file=checkpoints/$SUBDIR/checkpoint_best_$MODEL_NAME.pth \
write_images=True \
generate_attention_maps=False \
output_dir=detections/$SUBDIR/$MODEL_NAME/$SPLIT
fi
done
done
done
This will run inference on all images found in data/spine/$SPLIT and save renderen images with bounding boxes and trackformer detection files in detections/$SUBDIR/$MODEL_NAME/$SPLIT.
The repository also contains this bash code in the file track_custom.sh in the root directory.