论文:Learning Multi-Domain Convolutional Neural Networks for Visual Tracking
代码:https://github.com/hyeonseobnam/py-MDNet
网络整体结构:
论文中的重点:
- 首先进行多领域学习。学习完成后,当给定一个测试序列时,将删除训练阶段使用的所有现有二元分类层分支,并构造一个新的分支来计算测试序列中的目标分数。在跟踪过程中,新的分类层和共享层中的全连接层会在线进行微调,以适应新的域。在线更新是为了分别对目标的长期和短期外观变化进行建模,以实现鲁棒性和自适应性,并且在学习过程中引入了一种有效和高效的难例挖掘技术。
- 我们考虑两个互补方面的视觉跟踪,鲁棒性和适应性,通过长期和短期更新。使用长时间收集的正样本定期执行长期更新,而当在短期内使用正样本将估计目标分类为背景时,只要检测到潜在的跟踪失败,就会执行短期更新。在这两种情况下,我们都使用短期内观察到的负面样本,因为旧的负面样本通常是多余的或与当前框架无关。请注意,我们在跟踪期间维护一个网络,根据目标外观的变化速度执行这两种更新。
其他:(参考:https://blog.csdn.net/laizi_laizi/article/details/107475865)
- 网络分为shared layers和domain-specific layers两部分,前者采用VGG-M的模型和预训练参数,后者有K个分支,对应K个训练序列,也称为K个domain(这里只加载conv部分的预训练模型,然后离线学习阶段conv和fc全都训练)
- 训练过程中,每次迭代从一个序列中提取32个positive samples和96个negative samples来构成一个mini-batch,训练对应的 fc6^{k} 分支(也就是说每个epoch下,每个fc6分支都依次被训一次)
- fc6每个分支输出二维特征,分别表示target和background的pos_score和neg_score,对于正样本的标签就是[0, 1],负样本的标签就是[1, 0],损失采用二分类交叉熵:binary softmax cross-entropy loss
- 训练非常类似R-CNN,因为原图上crop下来一起送入shared layers,计算冗余,效率低下
- 这样一个分类的方式,用一个序列训练一个domain,如果没有在线更新部分,个人感觉只是对见过的物体跟踪比较准确,当然有了在线更新的部分会好很多,无疑速度也变慢了
MDNet(model.py)
- 包括优化器、网络结构、损失函数、准确度、精确度
优化器
- 学习率倍乘
网络结构
3x107x107
| conv1
96x51x51
| conv2
256x11x11
| conv3
512x3x3
| fc4
512
| fc5
512
| fc6 ...(一个视频序列就有一个分支)
2
损失函数
- 二值交叉熵损失
准确度
- 预测正确的比例
精确度
- 预测的精度
pretrain
data_prov.py
- 输入:
- img_list: list(303),如[’’,’’,’’,…],图片路径
- gt: ndarray:(303, 4),真实标签
- opts,各种参数
- __ next __:一个序列中选8帧,每帧生成4个pos_regions和12个neg_regions
train_mdnet.py
- 一个序列生成32个pos_regions和96个neg_regions
- pos_regions 送入网络得到 pos_score,neg_regions 送入网络得到 neg_score
- 根据 pos_score,neg_score 计算损失
pretrain 总结
- 每个序列生成正负样本 --> 用正负样本训练网络 --> 计算分类损失
- 本质是训练一个分类器,区分输入的是正样本还是负样本(前景还是背景)
tracking
gen_config.py
输出:
- img_list
- init_bbox
- gt
- savefig_dir
- args.display
- result_path
run_tracker.py
- gen_config–>训练的数据和基本信息
------------- 初始化 ------------- - 初始化变量 result、result_bb、overlap
- 初始化模型 MDNet,并导入共享层的预训练权重
- 初始化损失函数BCELoss
- 初始化优化器:
①第一帧训练时的优化器(fc4-5:0.0005,fc6:*10)
②在线训练阶段的优化器(fc4-5:0.001,fc6:*10)
------------- 第一帧 -------------
// 训练 fc4-6 - 读入第一帧图像
- 生成 500 个正样本和 5000 个负样本(两者生成的方式有差异)
- 对于正负样本,分别提取样本区域然后分别送入 MDNet 获得 conv3 的输出特征
- 难例挖掘:设置 eval 模式,将 1024 个负样本的 conv3 特征送入网络(fc4-6),选择 fc6 输出得分最高的 256 个负样本,设置回 train 模式
- 每次迭代输入 32 个正样本 conv3 特征和 96 个负样本 conv3 特征,得到正负样本得分
- 计算损失函数,更新 fc4-6 的参数(梯度截断)
// 训练 BBox regression - 重新生成 1000 个样本用于回归
- 送入 MDNet 获得 conv3 的输出特征
- 拟合 conv3 特征与回归偏差
------------- 在线更新 ------------- - 重新生成 200 个负样本,获得 conv3 的特征,沿用8中的正样本特征,获得 pos_feats_all、neg_feats_all,然后进入循环
- 在上一帧预测的target location构造 256 个候选样本,获得 fc6 输出结果,然后挑选pos_score最高的5个candidates,平均他们的位置作为预测出来的target bbox,对应的分数平均值为 target_score,如果 target_score > 0,则 success = 1
- 如果 success = 0,扩大搜索区域
- 如果 success = 1,BBox regression
- 保存原始预测结果(result)和回归后的结果(result_bb)
- 如果 success = 1,生成 50 个正样本和 200 个负样本,append 到 pos_feats_all 和 neg_feats_all,超出长度则删除旧的
- 如果 success = 0,short-term update,使用pos_feats_all 的部分和 neg_feats_all 来训练网络
- 每 10 帧用 pos_feats_all 和 neg_feats_all 训练网络,long-term update
总结
预训练阶段:训练整个网络。
跟踪阶段:固定前三层卷积层,利用第一帧的信息训练fc4-5以及随机初始化的fc6,以及bbox回归网络。对于后续帧,固定bbox回归网络,在上一帧预测的位置周围生成候选样本,将得分最高的5个样本均值作为预测结果,如果得分大于零,送入回归网络,并将此时预测出来的target bbox周围固定数量的正样本特征和负样本特征并入短期和长期的特征集合中,如果得分小于等于零,则扩大候选样本的搜索区域(用于下一个epoch),并用短期特征集合中的特征来更新模型,另外,每过10帧就用长期特征集合中的特征来更新模型。