lithium770 / Unsupervised-Person-re-ID-with-Stochastic-Training-Strategy

10 stars 2 forks source link

Initialize cluster memory #2

Closed vegetablebird5 closed 2 years ago

vegetablebird5 commented 2 years ago

作者您好,我在阅读代码的过程中有一些疑惑。请问您这里的 tar_fea_dict、和 target_centers 分别表示的是什么呢? 期待您的答复,感谢!

image

lithium770 commented 2 years ago

您好,tar_fea_dict用来对所有的pseudo label建立一个字典,经过上面那段语句的处理后tar_fea_dict[pid]里会是一个包含伪标签pid对应所有样本的feature表示的列表。

下面那段语句从tar_fea_dict每个伪标签对应的列表中随机选取一个feature作为这个伪标签的cluster center,然后添加到target_centers里。这样target_centers就可以用于初始化这个epoch的cluster_memory。

vegetablebird5 commented 2 years ago

首先非常感谢作者您的答复,对于cluster center,也就是说从每个伪标签对应的列表中随机选取一个feature,作为当前这个伪标签的聚类质心,而不是把当前这个伪标签中所包含的所有实例特征取平均,来作为当前这个伪标签的聚类质心,是这样理解吧?

另外,关于您的文章我还有以下疑惑。 1.您文章中说的Cluster centroid和Current training sample不一致是什么意思,这部分我没有看太明白。 image 2.关于损失计算问题。我的理解是不使用当前cluster_memory中的聚类质心和query实例去计算对比损失,而是用当前伪标签的cluster_center中的一个随机instance 样本去和query实例计算对比损失(我阅读您的文章之后是这样理解的,若有出入的地方还请您指正)。 3.您的代码整体框架是构建了两个内存字典(instance feature memory和cluster memory )还是单独的一个聚类内存字典(cluster memory)? 期待您的答复。感谢!

lithium770 commented 2 years ago

您好,是这样理解的。

1.不一致性指的是:因为instance-memory里储存的feature是随着训练进程更新的,而encoder本身在随着训练不断变化。因此储存的feature之间存在不一致性,计算得到的centroid和当前encoder对输入数据编码的current training sample之间也存在不一致性。

  1. 您描述的方式是对比实验中的stochastic设置,我们使用的stochastic(online)是使用cluster_memory中的质心计算对比损失,只是每个epoch的开始阶段初始化cluster_memory时需要选随机instance(因为聚类结果每次会变化所以需要每个epoch重新初始化)。因为cluster_memory中储存的质心会随着训练更新,在具有随机性的同时能让最近infer到的feature在质心表示中拥有更大的权值。

  2. 构建了两个内存字典。

vegetablebird5 commented 2 years ago

感谢作者您的答复。我大致明白了。 1.在计算对比损失的时候,在baseline中使用的是聚类实例特征的均值向量最为分类器进行对比损失; 在stochastic中,使用的是cluster_memory中每个聚类随机选取的一个图像特征作为分类器计算对比损失; 在stochastic(online)中,使用的是cluster_memory中每个聚类随机选取的一个新提取的(也就是更新之后的)图像特征作为分类器计算对比损失。是这样吗? 2.也就是说,stochastic和stochastic(online)都没有使用每个聚类实例特征的均值向量(也就是对每个聚类中的实例特征进行平均操作)来作为聚类质心,而都是使用聚类中的一个随机实例作为聚类质心,是这个意思吧? 3.另外,stochastic和stochastic(online)之间的区别是不是就是它们更新cluster_memory的方式不同,其他都是一样的?还有就是它们的区别在代码中是怎样体现的呢? 再次感谢作者抽出时间给予答复。

lithium770 commented 2 years ago

您好,stochastic和stochastic(online)的区别确实只有更新cluster_memory的方式不同,这两种设置的质心都直接从cluster_memory中取。

假如当前batch里有属于聚类c的一个输入数据x,那么在backward更新cluster_memory里聚类c所对应的质心时,stochastic设置会使用这个聚类里的随机feature进行更新(在每个epoch初根据聚类结果对每个聚类random一个序列,需要更新时按照序列的顺序取instance,在做这个设置的实验时会额外维护一个memory用来放每个instance的最新feature,可以看作一个momentum为0的instance_memory)。而stochastic(online)使用当前encoder产生的f_x更新质心,实现和代码里一样。前者的额外memory类似传统的instance_memory,因为每个instance只有被访问时才会更新所以会取到outdated的feature,而后者始终用最新的instance feature更新质心,因此质心表示中总是更一致的feature具有更大的权值。

vegetablebird5 commented 2 years ago

感谢作者您的答复。 还有个问题就是,为什么从tar_fea_dict每个伪标签对应的列表中随机选取一个feature作为这个伪标签的cluster center,会比把当前伪标签列表中的特征取平均作为聚类质心的效果好呢? 是有什么理论依据吗,还是根据实验得出的结论呢? 期待您的答复,感谢!

lithium770 commented 2 years ago

是指初始化cluster_memory的时候为什么选随机一个feature吗,是实验得到的

vegetablebird5 commented 2 years ago

是指初始化cluster_memory的时候为什么选随机一个feature吗,是实验得到的

就是 初始化cluster_memory时、以及在聚类内存字典正、负样本进行损失计算时,都不使用聚类的平均特征作为聚类质心吗?

lithium770 commented 2 years ago

对,因为cluster_memory里存的质心会被新的feature直接更新。如果我没解释清楚的话,结合一下cluster_memory里质心更新的公式应该更好理解...

vegetablebird5 commented 2 years ago

对,因为cluster_memory里存的质心会被新的feature直接更新。如果我没解释清楚的话,结合一下cluster_memory里质心更新的公式应该更好理解...

好的,我明白了,感谢作者您的答复。 另外,您文章中的使用的Temporal ensembling based feature embeding方法中, image 注释中的 update features for outliers 是什么含义呢,我没有看明白。 期待您的答复,感谢!

lithium770 commented 2 years ago

dbscan聚类会产生一些孤立的样本(即没有和其他样本被分配到一个聚类),这些outlier不会被分配伪标签也不会用于这个epoch的训练。所以instance_memory(temporal memory)里这些样本的feature不会被更新,在下个epoch的聚类开始前要更新一下这些样本的feature。

vegetablebird5 commented 2 years ago

image 作者您好,还想请问您文章中的这个聚类准确率(Clustering ACC)是根据什么计算的呢?