Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ony have anchor and pos_sample #26

Open
Meimeiainaonao opened this issue Aug 29, 2021 · 5 comments
Open

Ony have anchor and pos_sample #26

Meimeiainaonao opened this issue Aug 29, 2021 · 5 comments

Comments

@Meimeiainaonao
Copy link

Meimeiainaonao commented Aug 29, 2021

Thanks for your contribution!

In this code, I only found utilize the anchor and pos_sample as follows:

def __getitem__(self, index):
        path, target = self.samples[index]
        cam = self.cams[index]
        # pos_path, neg_path
        pos_path = self._get_pos_sample(target, index)

        sample = self.loader(path)
        pos0 = self.loader(pos_path[0])
        pos1 = self.loader(pos_path[1])
        pos2 = self.loader(pos_path[2])
        pos3 = self.loader(pos_path[3])

and in the forward as follows:

            outputs, f = model(inputs)
            _, pf = model(pos)
            #pf = Variable( pf, requires_grad=True)
            neg_labels = pos_labels
            # hard-neg
            # ----------------------------------
            nf_data = pf # 128*512
            # 128 is too much, we use pool size = 64
            rand = np.random.permutation(4*opt.batchsize)[0:opt.poolsize]
            nf_data = nf_data[rand,:]
            neg_labels = neg_labels[rand]
            nf_t = nf_data.transpose(0,1) # 512*128
            score = torch.mm(f.data, nf_t) # cosine 32*128 
            score, rank = score.sort(dim=1, descending = True) # score high == hard
            labels_cpu = labels.cpu()
            nf_hard = torch.zeros(f.shape).cuda()
            for k in range(now_batch_size):
                hard = rank[k,:]
                for kk in hard:
                    now_label = neg_labels[kk] 
                    anchor_label = labels_cpu[k]
                    if now_label != anchor_label:
                        nf_hard[k,:] = nf_data[kk,:]
                        break

I cannot understand neg_labels = pos_labels, In the paper, neg_lable should decribe as neg_lable !=pos_label.

Please help, Thx

@CynicalHeart
Copy link

我记得当初也被pos_labels名称迷惑到了,因为它的定义在上面:

inputs, labels, pos, pos_labels = data  # anchor、batch中类别索引列表、正例、正例类别索引列表
...
pos = pos.view(4 * opt.batchsize, c, h, w)  # 正例样本[5维->4维]
# copy pos 4times 复制四次,并使四个索引连续排布.eg:[213,213,213,213,132,132,132,132...]
pos_labels = pos_labels.repeat(4).reshape(4, opt.batchsize)  # [4, b]
pos_labels = pos_labels.transpose(0, 1).reshape(4 * opt.batchsize)  # [4*b]

它的含义是一个批次所有图片的类别标签×4

@Meimeiainaonao
Copy link
Author

非常感谢同学帮我解答,但是我还是不明白,code中对tripletfolder.py中anchor、pos、neg进行了定义:

def _get_pos_sample(self, target, index):
    pos_index = np.argwhere(self.targets == target) # 正样本 与anchor同身份但是不相似的行人
    pos_index = pos_index.flatten()
    pos_index = np.setdiff1d(pos_index, index)
    rand = np.random.permutation(len(pos_index))
    result_path = []
    for i in range(4):
       t = i%len(rand)
       tmp_index = pos_index[rand[t]]
       result_path.append(self.samples[tmp_index][0])
    return result_path

def _get_neg_sample(self, target):
    neg_index = np.argwhere(self.targets != target)  # 负样本,与anchor不同身份但是相似的行人
    neg_index = neg_index.flatten()
    rand = random.randint(0,len(neg_index)-1)
    return self.samples[neg_index[rand]]

但在__getitem__中仅使用了pos_sample,没有neg_sample呐

        def __getitem__(self, index):
             path, target = self.samples[index]
             cam = self.cams[index]
             # pos_path, neg_path
             pos_path = self._get_pos_sample(target, index) # 仅使用了pos_sample,没有neg_sample呐     
             ...
             c,h,w = pos0.shape
             pos = torch.cat((pos0.view(1,c,h,w), pos1.view(1,c,h,w), pos2.view(1,c,h,w), pos3.view(1,c,h,w)), 0)
             pos_target = target
             return sample, target, pos, pos_targe

此外,在forward内,就仅有
outputs, f = model(inputs) _, pf = model(pos)# 仅计算了pos_f,也没有计算neg_f

想请教同学这是为啥呐,code中到底哪个位置使用了neg_sample, 或者给出了neg_sample的索引呐?
不胜感激~~

@CynicalHeart
Copy link

我记得没有任何位置用上neg_sample,正负例都是用的第一个函数。

@Meimeiainaonao
Copy link
Author

正负样本不应该分别对应anchor同身份和不同身份的行人嘛?计算loss时,这个code内正负样本选择的都是同身份中的行人呐?

        neg_labels = pos_labels

        # hard-neg
        # ----------------------------------
        nf_data = pf # 负样本的特征直接取自于正样本的特征呐?后面计算的就都是正样本中,与anchor距离最远的正样本了?
        # 128 is too much, we use pool size = 64
        rand = np.random.permutation(4*opt.batchsize)[0:opt.poolsize]
        nf_data = nf_data[rand,:]
        neg_labels = neg_labels[rand]
        nf_t = nf_data.transpose(0,1) # 512*128
        score = torch.mm(f.data, nf_t) # cosine 32*128 
        score, rank = score.sort(dim=1, descending = True) # score high == hard
        labels_cpu = labels.cpu()

@layumi
Copy link
Owner

layumi commented Aug 31, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants