Report/12月20日本周科研工作进展.md

203 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 12月5日科研工作进展
## 目前进度
### 1.继续进行超参数调整
![log7-l2s](/pic/log7-l2s.png)
![log8](/pic/log8.png)
#### 超参数:
```python
# 批次大小
parser.add_argument('--batch-size', default=64, type=int)
parser.add_argument('--batch-size', default=96, type=int)
# 学习率
parser.add_argument('--lr', default=0.03, type=float)
parser.add_argument('--lr', default=0.08, type=float)
# 聚类数量
parser.add_argument('--num-cluster', default='2,5,10,20,33,50,100,200,400,800,1600,2400,3200', type=str)
parser.add_argument('--num-cluster', default='3200,2400,1600,800,400,200,100,50,25,20,10,5,2', type=str)
# 负样本队列大小
parser.add_argument('--pcl-r', default=1024, type=int)
parser.add_argument('--pcl-r', default=640, type=int)
# MoCo动量
parser.add_argument('--moco-m', default=0.999, type=float, )
# softmax温度
parser.add_argument('--temperature', default=0.2, type=float)
# 数据增强
parser.add_argument('--aug-plus', default=True, type=bool)
parser.add_argument('--aug-plus', default=False, type=bool)
```
#### 目前问题:
1存在过拟合的情况
2存在原型聚类损失不能很好引导两个精度的提升的问题
#### 目前最佳训练:
![log9-l2s](/pic/log9-l2s.png)
### 2.使用了软化标签的方式解决低聚类问题中的不确定影响
调用了nn.CrossEntropyLoss中的label_smoothing功能缓解硬标签对初期模型的破坏目前设定上限为0.2
```python
def cac_smoothing_factor(cluster_result, args):
# 获取当前聚类数
cluster = int(cluster_result['centroids'][-1].shape[0])
# 计算平滑因子使得聚类数越少平滑因子越大最大为0.2
smoothing_factor = min(0.2, ((args.max_cluster - cluster) / args.max_cluster) ** 0.5 * 0.2)
return smoothing_factor
```
### 3.改用了自行设计聚类数组而非直接翻倍的方式决定聚类数目
根据之前的实验聚类数在100左右时对训练提升最大这是因为使用的mini-imagenet数据集拥有100个类别的原因。使用直接翻倍的情况可能会导致跳过n倍数类别或1/n类别的聚类数导致计算损失时存在误差。
```python
parser.add_argument('--num-cluster', default='2,5,10,20,33,50,100,200,400,800,1600,2400,3200', type=str)
# 改变聚类数逻辑
if should_change:
# 取 num_clusters 的最后一个数字,与 all_clusters 比较
last_cluster = num_clusters[-1]
if last_cluster in all_clusters:
index = all_clusters.index(last_cluster)
if index + 1 < len(all_clusters): # 确保不会超出范围
next_cluster = all_clusters[index + 1]
# 更新 num_clusters移除第一个添加新数字到末尾
num_clusters.pop(0)
num_clusters.append(next_cluster)
print(f"Epoch {epoch}: 聚类数改变.")
print(f"num_clusters 更新为: {num_clusters}")
else:
print("all_clusters 已用完,无法改变.")
else:
print("当前 num_clusters 的最后一个数字未在 all_clusters 中找到")
sliding_window.reset(epoch) # 重置窗口并更新init_threshold
elif should_change_threshold:
print(f"Epoch {epoch}: 增加inst阈值")
else:
print("滑动窗口未达到条件,不改变聚类数.")
```
### 4.增加了cos学习率衰减以控制更新以及防止过拟合
```python
def adjust_learning_rate(optimizer, epoch, args):
"""Decay the learning rate based on schedule"""
lr = args.lr
if args.cos: # cosine lr schedule
lr *= 0.5 * (1. + math.cos(math.pi * epoch / args.epochs))
else: # stepwise lr schedule
for milestone in args.schedule:
lr *= 0.1 if epoch >= milestone else 1.
for param_group in optimizer.param_groups:
param_group['lr'] = lr
```
### 5.采用凝聚型层次聚类作为一次聚类任务的方式
避免出现样本a在细聚类时属于小原型1.1小原型1.1属于大原型1中但样本a却在粗聚类时被分配到大原型2中的问题提升聚类的可靠性。
![图片1](/pic/图片1.png)
```python
# 取得聚类中心0
centroids_0, im2cluster_0, D0 = clus(x, num_clusters[0], args)
# 取得聚类中心1
centroids_1, im2cluster_1, D1 = clus(centroids_0, num_clusters[1], args)
# 取得聚类中心2
centroids_2, im2cluster_2, D2 = clus(centroids_1, num_clusters[2], args)
density_0 = cau_density(im2cluster_0, num_clusters[0], D0, args)
density_1 = cau_density(im2cluster_1, num_clusters[1], D1, args)
density_2 = cau_density(im2cluster_2, num_clusters[2], D2, args)
...
def clus(x, num_cluster, args):
k= int(num_cluster)
clus = faiss.Clustering(x.shape[1], k)
clus.verbose = False
clus.niter = 20 # 最大迭代次数
clus.nredo = 5 # 聚类重新初始化次
clus.seed = args.seed
clus.max_points_per_centroid = int(x.shape[0] * 5 / 3 / int(num_cluster))
clus.min_points_per_centroid = int(x.shape[0] / 3 / int(num_cluster))
clus.is_relative_centroids = True
clus.spherical = True
print(
f"num_cluster:{num_cluster}, min_points:{clus.min_points_per_centroid}, max_points:{clus.max_points_per_centroid}")
res = faiss.StandardGpuResources()
cfg = faiss.GpuIndexFlatConfig()
cfg.useFloat16 = True
cfg.device = args.gpu
index = faiss.GpuIndexFlatL2(res, x.shape[1], cfg)
clus.train(x, index)
D, I = index.search(x, 1) # for each sample, find cluster distance and assignments
im2cluster = [int(n[0]) for n in I]
# 取得聚类中心
centroids = faiss.vector_to_array(clus.centroids).reshape(k, x.shape[1])
return centroids, im2cluster, D
def cau_density(im2cluster, k, D, args):
# 计算每个样本到其聚类中心的距离
Dcluster = [[] for c in range(k)]
for im, i in enumerate(im2cluster):
Dcluster[i].append(D[im][0])
# 聚类中心浓度估算
density = np.zeros(k)
for i, dist in enumerate(Dcluster):
if len(dist) > 1:
d = (np.asarray(dist) ** 0.5).mean() / np.log(len(dist) + 10)
density[i] = d
# 如果聚类只有一个点,最大化估计其浓度
dmax = density.max()
for i, dist in enumerate(Dcluster):
if len(dist) <= 1:
density[i] = dmax
density = density.clip(np.percentile(density, 10),
np.percentile(density, 90)) # 去掉极端浓度值
density = args.temperature * density / density.mean() # 缩放浓度值
```
目前没有使用,原因是每层聚类数的差异不够,如聚类数为[2400,2000,1600]每层差距不到1.2,凝聚型聚类会导致从小样本中聚类大样本数,问题较大。
可能考虑在以后从小到大的聚类训练中使用,以获得高可信度的粗聚类中心。
### 6.改用聚类数从高到低的方式引导训练流程
在模型刚开始训练时,较粗的聚类可能导致边缘样本的错误分配,导致错误的累计。故引导聚类的方法从细到粗更可靠,最近邻和过度聚类通常更能被接受的;同时,凝聚聚类是一个循环过程,可以自然地在循环框架中进行解释;随着学习到更好的表示,这些聚类可以被合并。
目前正在实验,
从小到大loss_inst: 3.50, loss_proto: 2.84 **Acc_Inst: 75.01, Acc_Proto: 60.28**
从大到小loss_inst: 2.67e, loss_proto: 3.46, **Acc_Inst: 91.45, Acc_Proto: 89.15**
两种聚类方式会已进行比较图1和图3后续将补充一些说明作为论文的工作量。
## 下周任务
1.进行一些下游任务实验的进一步设计如few-shot、聚类效果等