在正常的行人重识别深度学习的模型中,都是先将行人图片经过backbonne网络,提取特征,然后再将特征和Linear层进行了链接,然后根据输出的分类概率,来反馈,对网络进行优化。我就在想,可不可以不经过最后的分类层,而是直接在特征的层面进行优化。所以我写了一个损失函数:
import torch
import torch.nn as nn
class Features_Loss(nn.Module):
def __init__(self):
super(Features_Loss,self).__init__()
def forward(self, features, batch_size, person_num):
loss_all = 0
loss_temp = 0
for id_index in range( batch_size // person_num ):
features_temp_list = features[id_index*person_num:(id_index+1)*person_num+1]
loss_temp = 0
distance = torch.mm(features_temp_list,features_temp_list.t())
distance = 1 -distance
for i in range(person_num):
for j in range( i + 1, person_num ):
loss_temp = loss_temp + distance[i][j]
loss_temp = loss_temp / ( person_num * (person_num-1)/2 )
loss_all = loss_all + loss_temp
loss_all = loss_all / ( batch_size // person_num )
return loss_all
送入这个损失函数的都是经过了标准化的特征向量,这个函数让相同label的行人图片的特征在余弦距离这个层面上拉近。
在数据的准备阶段,我让每个batch中包含K个ID的行人,每个ID下面存在N张图片,就像是triplet loss那样对数据的mini batch进行采样。
训练的时候,我首相将epoch设置为1,产生了epoch1.pth为训练的结果,然后又设置为60进行训练,这次的训练结果为epoch60.pth 。
我们的这个训练过程的代码,以及训练好的模型,都上传到了github上,地址为:https://github.com/t20134297/reid_with_features_loss_only
首先运行 python3 train.py来训练模型,然后运行python3 test.py就可以测试了,这个简单的模型获得rank1在60%左右。