iKun分析
根据你提供的代码和论文信息,我确实认为 iKUN(insertable Knowledge Unification Network)的一个核心优势就是其解耦能力。让我详细分析一下:
iKUN 的设计特点恰恰是为了实现与现有跟踪器的解耦,能够直接利用现有跟踪器的推理结果进行操作,而无需重新训练整个跟踪系统。从代码和论文中可以看出以下几点支持这一观点:
-
插入式设计:从名称 "insertable Knowledge Unification Network" 就可以看出,该模型被设计为可插入式的。README 中明确指出它能够 "enable communication with off-the-shelf trackers in a plug-and-play manner",这表明它可以直接与现有的跟踪器集成。
-
无需重新训练:论文摘要中提到了传统方法 "需要重新训练整个框架"("need to retrain the entire framework"),而 iKUN 的设计目标就是解决这个问题。
-
利用现有跟踪结果:从
test.py代码中可以看到,系统会加载现有跟踪器生成的跟踪结构(tracks):
# load tracks
try:
tracks = np.loadtxt(join(track_dir, video, 'all', 'gt.txt'), delimiter=',')
except:
tracks_1 = np.loadtxt(join(track_dir, video, 'car', 'predict.txt'), delimiter=',')
# ...
-
知识统一模块(KUM):这个模块设计用于根据文本指导自适应地提取视觉特征,但它并不改变或重新训练底层跟踪器。它提供了三种模式(cascade attention、cross correlation、text-first modulation),可以根据需要选择不同的文本引导方式。
-
测试时相似度校准:
similarity_calibration方法在测试时应用,用于根据伪频率优化置信度分数,这也是在不改变底层跟踪器的情况下进行的后处理操作。 -
明确的测试流程:README 中的测试命令显示,你可以直接使用预训练的 iKUN 模型与现有跟踪结果一起生成最终输出,而不需要重新训练跟踪器:
python test.py --kum_mode 'cascade attention' --test_ckpt iKUN_cascade_attention.pth --similarity_calibration
综上所述,iKUN 确实设计为能够解耦使用,它可以直接利用现有跟踪器的推理结果,通过添加文本引导能力来增强跟踪性能,而无需重新训练整个跟踪系统。这种设计使其成为一个灵活且实用的解决方案,特别是对于那些已经有现成跟踪器但希望添加文本引导能力的应用场景。
通过仔细分析提供的代码,我可以详细介绍 iKUN 是如何使用现有跟踪器的结果的。让我系统地解释这个流程:
iKUN 使用跟踪器的方式
1. 跟踪器结果的加载与使用
在 test.py 中的 generate_final_results 函数是关键部分,该函数展示了 iKUN 如何使用现有跟踪器的结果:
def generate_final_results(cls_dict, data_dir, track_dir, save_dir, thr_score=0.):
# ...
# load tracks
try:
tracks = np.loadtxt(join(track_dir, video, 'all', 'gt.txt'), delimiter=',')
except:
tracks_1 = np.loadtxt(join(track_dir, video, 'car', 'predict.txt'), delimiter=',')
if len(tracks_1.shape) == 2:
tracks = tracks_1
max_obj_id = max(tracks_1[:, 1])
else:
tracks = np.empty((0, 10))
max_obj_id = 0
tracks_2 = np.loadtxt(join(track_dir, video, 'pedestrian', 'predict.txt'), delimiter=',')
if len(tracks_2.shape) == 2:
tracks_2[:, 1] += max_obj_id
tracks = np.concatenate((tracks, tracks_2), axis=0)
# ...
这段代码说明:
- iKUN 从
track_dir中加载现有跟踪器的跟踪结果(bbox 坐标等信息) - 它尝试先加载 "all" 目录中的综合跟踪结果
- 如果失败,则分别加载 "car" 和 "pedestrian" 目录下的跟踪结果并合并
2. 跟踪结果的整合过程
在加载跟踪结果后,iKUN 将其与自己的文本相似度分数结合:
# generate `predict.txt`
video_dict = cls_dict[video]
for obj_id, obj_dict in video_dict.items():
for frame_id, frame_dict in obj_dict.items():
for exp in EXPRESSIONS[video]:
if exp in EXPRESSIONS['dropped']:
continue
if exp not in frame_dict:
continue
exp_dir_out = join(video_dir_out, exp)
score = np.mean(frame_dict[exp])
with open(join(exp_dir_out, 'predict.txt'), 'a') as f:
if score > thr_score:
bbox = tracks[
(tracks[:, 0] == int(frame_id)) *
(tracks[:, 1] == int(obj_id))
][0]
assert bbox.shape in ((9, ), (10, ))
if MIN_FRAME < bbox[0] < MAX_FRAME:
f.write(','.join(list(map(str, bbox))) + '\n')
这段代码展示了整合过程:
- 对于每个视频的每个对象的每一帧,iKUN 检索与特定文本表达式相关的相似度分数
- 如果分数超过阈值
thr_score,则从已加载的跟踪结果中查找对应的边界框 - 最后将这些边界框写入结果文件
3. 测试流程
在 test.py 的主函数中,可以看到完整的测试流程:
if __name__ == '__main__':
# ...
if not exists(output_path):
model = get_model(opt, 'Model')
try:
model, _ = load_from_ckpt(model, join(opt.save_root, f'{opt.test_ckpt}'))
except:
print('The model is not loaded.')
dataloader = get_dataloader('test', opt, 'Track_Dataset')
output = test_tracking(model, dataloader)
# ...
SAVE_DIR = join(opt.save_root, opt.exp_name, f'results{opt.save_postfix}')
CLS_DICT = json.load(open(output_path))
if opt.similarity_calibration:
TEXT_FEAT_DICT = json.load(open(join(opt.save_root, 'textual_features.json')))
CLS_DICT = similarity_calibration(
TEXT_FEAT_DICT,
CLS_DICT,
a=8,
b=-0.1,
tau=100
)
generate_final_results(
cls_dict=CLS_DICT,
data_dir=opt.data_root,
track_dir=opt.track_root,
save_dir=SAVE_DIR,
)
这个流程是:
- 加载 iKUN 模型并运行
test_tracking函数生成文本-视觉相似度分数 - 可选地应用相似度校准(similarity calibration)
- 调用
generate_final_results将相似度分数与跟踪器的跟踪结果合并
4. 视觉-文本匹配过程
在 test_tracking 函数中,iKUN 评估每个跟踪对象与文本描述的匹配程度:
def test_tracking(model, dataloader):
print('========== Testing Tracking ==========')
model.eval()
OUTPUTS = multi_dim_dict(4, list)
with torch.no_grad():
for batch_idx, data in enumerate(tqdm(dataloader)):
# forward
inputs = dict(
local_img=data['cropped_images'].cuda(),
global_img=data['global_images'].cuda(),
exp=tokenize(data['expression_new']).cuda(),
)
similarity = model(inputs)['logits'].cpu()
for idx in range(len(data['video'])):
for frame_id in range(data['start_frame'][idx], data['stop_frame'][idx] + 1):
frame_dict = OUTPUTS[data['video'][idx]][int(data['obj_id'][idx])][int(frame_id)]
frame_dict[data['expression_raw'][idx]].append(similarity[idx].cpu().numpy().tolist())
return OUTPUTS
这个函数计算每个跟踪对象与文本表达式之间的相似度分数,并将结果存储在一个多维字典中。
核心解耦机制
通过上述分析,iKUN 的解耦机制主要体现在:
-
后处理方式:iKUN 不干预或修改原始跟踪器的跟踪过程,而是作为一个后处理组件使用跟踪器已生成的结果
-
选择性筛选:它使用文本-视觉相似度分数来筛选原始跟踪结果中与特定文本描述匹配的对象
-
基于阈值的过滤:使用相似度阈值(
thr_score)决定哪些跟踪结果应该保留 -
数据集成:它不要求改变原始跟踪器的训练或推理方式,只需要跟踪器能够输出标准格式的跟踪结果
-
文件级接口:通过文件系统接口(读取
.txt文件)与跟踪器交互,这是一种非常松散的耦合方式
总结来说,iKUN 采用了一种非侵入式的方法使用现有跟踪器的结果,它本质上是在原始跟踪器的输出上添加了一个基于文本引导的过滤层,而不需要修改或重新训练原始跟踪器。这种设计使 iKUN 能够与各种现有跟踪器兼容,只要它们能够输出标准格式的跟踪结果。