huanghoujing / AlignedReID-Re-Production-Pytorch

Reproduce AlignedReID: Surpassing Human-Level Performance in Person Re-Identification, using Pytorch.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

移植loss问题

chapmancpp opened this issue · comments

大佬好!
我把代码移植到python3.6+pytorch0.4下面。在训练的时候,loss.py里面报错。
当一个batch块里面出现相同的ID的图片的时候这边is_pos 计算的就不是对角矩阵了。
is_pos = labels.expand(N, N).eq(labels.expand(N, N).t())
is_neg = labels.expand(N, N).ne(labels.expand(N, N).t())
然后导致后面代码:
dist_ap, relative_p_inds = torch.max(
dist_mat[is_pos_test].contiguous().view(N, -1), 1, keepdim=True)#报错
错误提示:
RuntimeError: invalid argument 2: size '[16 x -1]' is invalid for input with 18 elements at ..\src\TH\THStorage.c:37

请问这里我是否可以直接定义一个batch大小的对角阵给is_pos 。还是is_pos 代码里面就可以出现非对角矩阵。
当我将is_pos 改成一直是对角矩阵的时候。只有全局loss,loss的值开始就非常的低,请问可能是什么问题啊。

多谢你的关注!
这个is_pos的第i行表示所有样本和第i个样本之间是否是同一个id,对角线上肯定是True,如果第j, k, l个样本和第i个样本同一个id,那么第i行的第j, k, l应该是Trueis_pos一般情况下不是对角阵。这个错误我没能一眼看出来是哪里的不兼容。

N = dist_mat.size(0) #这是您N的定义
您之前定义了N的大小,为矩阵大小,
然而当队列中出现相同的ID的时候,即为非对角矩阵时,那么
is_pos = labels.expand(N, N).eq(labels.expand(N, N).t()) ,
dist_mat[is_pos]的维数就会不等于N。
那么,下面很多用N定义的就会报错了,比如下面这行:
dist_ap, relative_p_inds = torch.max(
dist_mat[is_pos_test].contiguous().view(N, -1), 1, keepdim=True)#报错

dist_mat[is_pos_test].contiguous()的维数不等于N,就不能用view(N,1).您看我理解的对吗,是不是我哪边理解错了。

举个例子,labels[1, 2, 3, 4, 2, 1, 3, 4, 4, 2, 1, 3],也即4个id,每个id有3张图片,那么is_pos应该是(为了简化,下面的1表示True, 0表示False):

1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0
0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0
0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1
0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0
0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0
0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1
0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0
0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0
0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0
0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1

对角线都是1,每一行总共有3个1,所以dist_mat[is_pos].contiguous().view(N, -1)里边的-1就相当于3dist_mat[is_pos].contiguous().view(N, -1)的结果是一个12*3的数组。

我发现上面你的代码中好像有点问题,dist_ap, relative_p_inds = torch.max( dist_mat[is_pos_test].contiguous().view(N, -1), 1, keepdim=True)这里边is_pos_test不对吧,应该是is_pos

后来发现是我对triplet loss的理解问题。哈哈,谢谢大佬。大佬在国外的吗?羡慕。

大佬这个还是不敢当。。没在国外啊。。。

后来发现是我对triplet loss的理解问题。哈哈,谢谢大佬。大佬在国外的吗?羡慕。

N = dist_mat.size(0) #这是您N的定义
您之前定义了N的大小,为矩阵大小,
然而当队列中出现相同的ID的时候,即为非对角矩阵时,那么
is_pos = labels.expand(N, N).eq(labels.expand(N, N).t()) ,
dist_mat[is_pos]的维数就会不等于N。
那么,下面很多用N定义的就会报错了,比如下面这行:
dist_ap, relative_p_inds = torch.max(
dist_mat[is_pos_test].contiguous().view(N, -1), 1, keepdim=True)#报错

dist_mat[is_pos_test].contiguous()的维数不等于N,就不能用view(N,1).您看我理解的对吗,是不是我哪边理解错了。

我也遇到了这个问题,你解决了吗?

举个例子,labels[1, 2, 3, 4, 2, 1, 3, 4, 4, 2, 1, 3],也即4个id,每个id有3张图片,那么is_pos应该是(为了简化,下面的1表示True, 0表示False):

1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0
0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0
0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1
0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0
0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0
0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1
0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0
0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0
0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0
0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1

对角线都是1,每一行总共有3个1,所以dist_mat[is_pos].contiguous().view(N, -1)里边的-1就相当于3dist_mat[is_pos].contiguous().view(N, -1)的结果是一个12*3的数组。

我发现上面你的代码中好像有点问题,dist_ap, relative_p_inds = torch.max( dist_mat[is_pos_test].contiguous().view(N, -1), 1, keepdim=True)这里边is_pos_test不对吧,应该是is_pos

要是labels = [1, 2, 3, 4, 2, 1, 3, 4, 4, 2, 1, 1]这样的话,不就没法搞了吗