# 12月5日科研工作进展 ## 目前进度 ### 1.对之前的代码与数据进行了梳理、错误检查与修正 #### 问题解决: ##### (1)在低聚类的情况下,存在模型不能很好引导训练的情况: 如图,在聚类数较小的情况下,acc_proto应该较高,因为原型数本就较少,但之前的训练存在acc_proto在热身结束后接近0的情况,这存在问题。 ![log5](/pic/log4.png) ###### 原因: 1️⃣在较小的聚类条件下,单个簇中样本数目大,分布较为分散,此时查询样本q可能存在于簇边缘和聚类中心的相似度较低,而训练初期模型其实并不确定该样本的归属,强行拉近可能存在错误。 2️⃣在较小的聚类条件下,由于总簇数cluster_result(如10个聚类)小于batchsize样本数(如64),在采样过程中会导致多个样本被分到一个聚类中,导致每个样本分配的原型pos_proto_id出现重复(如[2,2, 2, 1, 0])。但样本的标签依旧保持顺序分布(如[0, 1, 2, 3, 4]),这使得在计算loss时将相同id的聚类推开,导致训练异常,同时导致计算loss与精度的问题。 ```python all_proto_id = [i for i in range(im2cluster.max()+1)] pos_proto_id = im2cluster[index] pos_prototypes = prototypes[pos_proto_id] neg_proto_id = set(all_proto_id)-set(pos_proto_id.tolist()) neg_proto_id = sample(neg_proto_id,self.r) neg_prototypes = prototypes[neg_proto_id] proto_selected = torch.cat([pos_prototypes,neg_prototypes],dim=0) logits_proto = torch.mm(q,proto_selected.t()) labels_proto = torch.linspace(0, q.size(0)-1, steps=q.size(0)).long().cuda() loss = loss_criterion(logits_proto, labels_proto) ``` ###### 解决办法: (1)目前使用了调整标签的方法进行了修正,即根据选择原型的id修正查询样本的标签,如原型id为[2, 2, 2, 1, 0],样本的为[0, 1, 2, 3, 4],调整后为[0, 0, 0, 3, 4],代码如下: ```python def adjust_labels(proto_selected, labels_proto): for value in torch.unique(proto_selected): # 获取B中该元素的所有位置 indices = torch.nonzero(proto_selected == value).squeeze() # 确保 indices 是一维张量,避免0维张量的问题 indices = indices.reshape(-1) # 确保indices有元素,防止空张量错误 if indices.numel() > 0: # 获取最小的位置(即第一个出现的位置) min_index = indices[0].item() # 使用.item()获取标量值 # 检查 min_index 是否越界 if min_index < len(labels_proto): # 将labels_proto中这些位置的元素替换为labels_proto中min_index位置的值 labels_proto[indices] = labels_proto[min_index].clone() else: continue return labels_proto ``` 调整效果: 可见loss与acc正常工作了,在热身结束后acc_proto相较之前提升巨大,且随着训练与聚类数的提升而不断增加,在epoch25左右达到顶峰(聚类数3,6,15)。loss__proto则在epoch37左右达到最低(聚类数60,120,240),怀疑为训练数据集的100分类引起。 ![log6](/pic/log6.png) (2)针对原因1️⃣的问题,决定使用新的loss方式对聚类数较低时进行调整: 直接最小化样本与其**最相似原型**之间的距离可能在某些情况下过于强硬,特别是当数据本身存在一定的噪声或存在多个相似的原型时,这种方法可能导致不理想的聚类结果。为了避免这种情况,可以采用以下两种思路:**最小化样本与最相似的 K 个原型之间的距离**,或**最大化样本与不相似原型之间的距离**。 ##### 实现方法: - **K 最近原型**:对于每个样本,计算它与所有原型之间的距离,然后选择距离最小的 K 个原型。 - **加权距离**:为了更好地处理样本与多个原型之间的关系,可以给每个原型分配一个权重(通常根据距离反比或其他策略来决定权重),然后计算加权距离作为损失的一部分。 ###### 损失函数设计: 1️⃣**最小化样本与最相似的 K 个原型之间的距离,最大化与不相似的原型之间的距离** 假设有一个样本$x_i$ ,它与$$K$$个原型的相似度分别为$s_{i1},s_{i2},...,s_{iK}$。可以设计如下损失函数: $$ Loss_i=∑_{k=1}^Kw_k⋅∥x_i−μ_k∥2 $$ 其中,$w_k$是与原型 $μ_k$相关的权重(例如与距离成反比),$∥⋅∥$是距离度量。 总的损失为最小化样本与最相似的 K 个原型之间的距离,又最大化样本与不相似的原型之间的距离: $$ \mbox{Total Loss}=∑_{k=1}^Kw_k⋅∥x_i−μ_k∥^2+λ⋅∑_{k=K+1}^Mmax(0,\alpha-∥x_i−μ_k∥^2) $$ 第二项为最大化样本与不相似原型(第 K+1 到第 M 个原型)之间的距离,$λ$ 是调节两部分之间平衡的超参数,$\alpha$是推远距离的阈值。 通过最小化这个损失函数,我们可以确保每个样本与多个原型保持一定的关系,而不是仅仅依赖于最相似的一个原型。 ### 2.下游任务代码构建部分完成 目前下游任务暂定为**少样本/半监督图像分类**、**目标检测**等,目前完成**少样本/半监督图像分类**代码,微调数据和测试集暂定为PASCAL VOC2007和mini_imagenet ### 3.阅读论文Adaptive Multi-head Contrastive Learning,对投影头设计有了新的方向 ## 下周任务 #### 1.实现新的损失函数代码设计与测试 #### 2.对现有模型的超参数进行调整