目录
说明
- 本篇博客是RGBT目标跟踪专题中的其中一篇:
Attribute-based Progressive Fusion Network for RGBT Tracking论文研读笔记
项目
- 源码在:yangmengmeng1997/APFNet (github.com)
- 下载数据集:GitHub - mmic-lcl/Datasets-and-benchmark-code
- 下载跟踪结果测评工具箱:GitHub - mmic-lcl/Datasets-and-benchmark-code
使用GTOT数据集和RGBT234数据集相互训练测试,即一个做训练集,另一个做测试集。但是需要注意查看数据集中是否含有tag属性标签文件,最好从原作者给出的链接中下载。这里介绍使用GTOT数据集作为训练集,RGBT234数据集作为测试集,反之同样。源码结构分析如下:
文件夹/文件 | 用途 |
log | 存放训练或测试过程的打印信息 |
models | 存放预训练权重和训练中间阶段的模型 |
modules | 存放网络结构搭建的脚本 |
pretrain | 预训练数据集以及预训练模型 |
results | 存放测试跟踪结果 |
tracking | 用来在测试集上面测试模型 |
train_stage1.py | 训练阶段一 |
train_stage2.py | 训练阶段二 |
train_stage3.py | 训练阶段二 |
预处理数据集
首先预处理数据集。打开 APFNet/pretrain/data/prepro_data.py。修改以下参数,其set_type 为数据集名称,设置为 GTOT 或者 RGBT234,seq_home 根据自己数据集所在路径相应修改,challenge_type 为挑战/属性名称,有六个选择,在注释中有标注。6、7、9、10 共四行也需要修改,seqlist_path 为 gtot.txt 和 rgbt234.txt 的路径,两个 txt 文件为两个数据集所含序列名称的文件。output_path 为 pkl 输出文件所要保存的路径。在这一步骤当中,需要不断修改 set_type 和 challenge_type 共 12 种组合,执行 prepro_data.py12 次,最终得到12 个 pkl 文件。
set_type = 'GTOT' # set datasets GTOT or RGBT234.modify it to yourself
#set_type = 'RGBT234'
seq_home = 'xxx/dataset/'+set_type +'/' #modify it to yourself
challenge_type = 'ALL' # set challenge type. FM~Fast Motion; OCC~Occlusion; SC~Scale; Variation; ILL~Illumination Variation; TC~Thermal Crossover; ALL~Whole dataset
if set_type=='GTOT': #modify it to yourself
seqlist_path = 'xxx/dataset/gtot.txt' #modify it to yourself
output_path = 'xxx/APFNet/pretrain/data/GTOT_'+challenge_type+'.pkl' #modify it to yourself
elif set_type == 'RGBT234':
seqlist_path = 'xxx/dataset/rgbt234.txt'
output_path = 'xxx/APFNet/pretrain/data/RGBT234_'+challenge_type+'.pkl'
其中,gtot.txt 文件内容示例如下:
BlackCar
BlackSwan1
BlueCar
BusScale
......
生成 gtot.txt 文件以及 rgbt234.txt 可使用如下简易的脚本:
import os
#my_path = './RGBT234'
#txt_name = './RGBT234.txt'
my_path = './GTOT'
txt_name = './gtot.txt'
with open(txt_name,"w") as f:
for name in os.listdir(my_path):
f.write(str(name) + '\n')
共生成12个pkl文件,用来存储数据集中不同属性子集的路径。
预训练模型
首先修改 APFNet/pretrain/data_prov.py 中的 modules 文件夹路径。
import torch
import torch.utils.data as data
import sys
sys.path.insert(0,'xxx/APFNet/modules/')
from sample_generator import SampleGenerator
from utils import crop_image2
之后修改 APFNet/pretrain/train_mdnet.py 中的三个参数。其中 dataset 为数据集名称,需要设置为 gtot 或者 rgbt234,model_path 为输出的模型的保存路径及名称,init_model_path为预训练权重的路径,这里我们使用./models/mdnet_imagenet_vid.pth 作为预训练权重。在这一步骤当中,需要设置dataset变量的值两次,运行脚本两次,得到两个输出模型:GTOT.pth和 RGBT234.pth,这两个模型之后将会作为第一阶段训练的预训练权重。
parser.add_argument('-d', '--dataset', default='gtot', help='training dataset {gtot, rgbt234}')
parser.add_argument("-model_path", default ="./models/GTOT", help = "model path")
parser.add_argument("-init_model_path", default="./models/mdnet_imagenet_vid.pth")
根据 train_mdnet.py 脚本中关于路径的代码编写方式,可知,运行该脚本应在其上一层
文件夹内,即:
cd APFNet/
python3 ./pretrain/train_mdnet.py
执行两次之后,将会在 APFNet/models/下得到 GTOT.pth 和 RGBT234.pth 两个模型。
训练阶段一
三个训练阶段均以训练 GTOT 数据集为例,RGBT234 数据集训练过程同理。
修改APFNet/pretrain/pretrain_option.py 中的模式,设置为阶段一:
#stage1 common
opts['ft_layers'] = ['parallel','fc']
opts['lr_mult'] = {'parallel':10,'fc':5}
opts['n_cycles'] = 500
##stage2 ensemble sknet
#opts['ft_layers'] = ['ensemble','fc6']
#opts['lr_mult'] = {'ensemble':10,'fc6':5}
#opts['n_cycles'] = 500
#stage3 ensemble Transformer fine-tune all
#opts['ft_layers'] = ['transformer','fc','layer','parallel','ensemble']
#opts['lr_mult'] = {'transformer':10,'fc':1,'fc6':5,'layer':1,'parallel':1,'ensemble':1}
#opts['n_cycles'] = 500
修改 APFNet/train_stage1.py 中以下参数,其中 set_type 表示要训练的属性的分支,model_path 表示生成的模型的输出位置及名称,init_model_path 为预训练权重位置,这里使用之前生成的 GTOT.pth。batch_frames、lr、batch_pos、batch_neg、n_cycles 是一些超参数,可以自己改动,也可以使用原设置。
#Change it by yourslef to train different attribute branches
parser.add_argument("-set_type", default = 'GTOT_FM') # OCC SC TC FM ILL
#your path for saving attribute branch
parser.add_argument("-model_path", default =xxx/APFNet/models/GTOT_FM.pth", help = "model path") # # OCC SC TC FM ILL 要同时改!!!
#load the backbone model GTOT.pth use the GTOT datasets pretain, and the RGBT234.pth usze the RGBT234 dataset pretrain the backbone.
parser.add_argument("-init_model_path", default="xxx/APFNet/models/GTOT.pth")
parser.add_argument("-batch_frames", default = 8, type = int)
parser.add_argument("-lr", default=0.0001, type = float) #you can set it by yourself
parser.add_argument("-batch_pos",default = 32, type = int)
parser.add_argument("-batch_neg", default = 96, type = int)
parser.add_argument("-n_cycles", default = 200, type = int ) #you can set it by yourself
根据其代码编写的路径配置,可知运行路径为当前脚本所在路径。需要修改 set_type和 model_path,并重复运行脚本共五次,得到五个模型:GTOT_OCC.pth、GTOT_SC.pth、GTOT_TC.pth、GTOT_FM.pth、GTOT_ILL.pth。其中不同的分支,也可能会得到多个模型,因为除了存储最终模型之外,平均精确度大于一定阈值如 0.95 的模型也会被保存下来。第一阶段到此完成。
cd APFNet/
python3 ./train_stage1.py
训练阶段二
修改 APFNet/pretrain/pretrain_option.py 中的模式,设置为阶段二,同上。
修改 APFNet/train_stage2.py 中以下参数,其中 logger 表示日志文件存储的位置及其名称,set_type 表示要训练的属性的分支,model_path 表示生成的模型的输出位置及名称,init_model_path 为预训练权重位置,这里使用之前生成的 GTOT.pth。batch_frames、lr、batch_pos、batch_neg、n_cycles 是一些超参数,可以自己改动,也可以使用原设置。
logger = get_logger('./log/trainGTOTSKALL.log')
parser = argparse.ArgumentParser()
#set yourdataset
parser.add_argument("-set_type", default = 'GTOT_ALL')
#Saving model path
parser.add_argument("-model_path", default ="xxx/APFNet/models/GTOT_ALL", help = "model path")
#your backbone model
parser.add_argument("-init_model_path", default="xxx/APFNet/models/GTOT.pth")
parser.add_argument("-batch_frames", default = 8, type = int)
parser.add_argument("-lr", default=0.0001, type = float) #set it bysourself
parser.add_argument("-batch_pos",default = 32, type = int)
parser.add_argument("-batch_neg", default = 96, type = int)
parser.add_argument("-n_cycles", default = 500, type = int ) #set it bysourself
根据其代码编写的路径配置,可知运行路径为当前脚本所在路径。运行脚本共一次,得到一个模型:GTOT_ALL.pth。第二阶段到此完成。
训练阶段三
修改 APFNet/pretrain/pretrain_option.py 中的模式,设置为阶段三,同上。
修改 APFNet/train_stage3.py 中以下参数,其中 logger 表示日志文件存储的位置及其名称,set_type 表示要训练的属性的分支,model_path 表示生成的模型的输出位置及名称,init_model_path 为预训练权重位置,这里使用之前生成的 GTOT.pth。batch_frames、lr、batch_pos、batch_neg、n_cycles 是一些超参数,可以自己改动,也可以使用原设置。
logger = get_logger('./log/Train_GTOT_ALL_Transformer.log')
parser = argparse.ArgumentParser()
parser.add_argument("-set_type", default = 'GTOT_ALL')
parser.add_argument("-model_path", default ="xxx/APFNet/models/GTOT_ALL_Transformer", help = "model path")
parser.add_argument("-init_model_path", default="xxx/APFNet/models/GTOT_ALL.pth")
parser.add_argument("-batch_frames", default = 8, type = int)
parser.add_argument("-lr", default=0.0001, type = float)
parser.add_argument("-batch_pos",default = 32, type = int)
parser.add_argument("-batch_neg", default = 96, type = int)
parser.add_argument("-n_cycles", default = 1000, type = int )
根据其代码编写的路径配置,可知运行路径为当前脚本所在路径。运行脚本共一次,得到最终模型:GTOT_ALL_Transformer.pth。第三阶段到此完成。
模型测试
介绍使用 GTOT 数据集训练得到的模型测试 RGBT234 数据集,反之亦然。
首先需要修改 APFNet/tracking/Run.py 中显卡指定一行:
os.environ["CUDA_VISIBLE_DEVICES"] = '0'
再修改 APFNet/tracking/Run.py 中其他参数,其中,logger 表示日志文件保存的位置及其名称,dataset 表示待被测试的数据集,我们这里选择 RGBT234,model_path 表示使用加载哪一个模型,作为输入,result_path 表示测试结果保存的位置,dataset_path 表示待测试数据集存储在的位置,mylist 表示数据集序列名称文件的路径。
logger = get_logger('./log/GTOT_ALL_Transformer.log') #Record your log files
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--seq', default='', help='input seq')
parser.add_argument('-j', '--json', default='', help='input json')
parser.add_argument('-f', '--savefig', action='store_true')
parser.add_argument('-d', '--display', action='store_true')
parser.add_argument("-dataset", default = 'RGBT234' ) #testing dataset
parser.add_argument("-model_path", default ='./models/GTOT_ALL_Transformer.pth') # your model
parser.add_argument("-result_path", default ='xxx/APFNet/results/') #your result path
args = parser.parse_args()
##your result path
args.result_path = 'xxx/APFNet/results/'+args.dataset+'/'+args.model_path.split('/')[-1].split('.')[0]+'/'
#assert args.seq != '' or args.json != ''
print(opts)
dataset_path = os.path.join('xxx/dataset/', args.dataset) #dataset path
mylist='xxx/dataset/rgbt234.txt'
运行之后,将在APFNet/results/RGBT234/GTOT_ALL_Transformer/下得到跟踪结果,每个txt里面都是八列,前四列表示RGB图像上的跟踪框,后四列则是相对应的热红外图像的跟踪框。