Closed nightwork23 closed 3 years ago
I have the same question, the performance decreases to 77.8% (mAP) and 89.9% (top-1) when choosing the "use-hard" option.
Could you tell me why CM_hard does not show any advantages compared to CM?
Sorry that we didn't not provides the CM_hard command in readme.md. I will update it. For this command: CUDA_VISIBLE_DEVICES=0,1,2,3 python examples/cluster_contrast_train_usl.py -b 256 -a resnet_ibn50a -d market1501 --iters 400 --momentum 0.1 --eps 0.4 --num-instances 16 --pooling-type gem --use-hard --logs-dir /data0/developer/cluster-contrast/examples/logs/gem-hard You will get result: Mean AP: 87.0% CMC Scores: top-1 94.6% top-5 98.2% top-10 98.8% which is much higher than paper result since we use gem pooling.
If use average pooling like: CUDA_VISIBLE_DEVICES=0,1,2,3 python examples/cluster_contrast_train_usl.py -b 256 -a resnet_ibn50a -d market1501 --iters 400 --momentum 0.1 --eps 0.4 --num-instances 16 --pooling-type avg --use-hard You will get result similar or a litter higher than our paper: Mean AP: 84.5% CMC Scores: top-1 93.6% top-5 97.5% top-10 98.4%
Thank!
Using CM_hard will get better result, but it requires carefully selected hyper-parameters. Generally, we recommend using CM first, and then try CM_hard for different hyper-parameters.
from my test,I choose batchsize 128 model resnet dataset market1501 --iters 400 --momentum 0.1 --eps 0.4 --num-instances 16 --pooling-type gem . when I choose use-hard ,mAP is 78.0. but when I use common CM ,mAP is 80.8
I follow your codes without the hard instance updating and get the score 82.7% mAP like your paper. However, when choose the use-hard option, the performance decreases to 79.4%. Codes about CM_Hard in cm.py is as follows: class CM_Hard(autograd.Function): @staticmethod def forward(ctx, inputs, targets, features, momentum): ctx.features = features ctx.momentum = momentum ctx.save_for_backward(inputs, targets) outputs = inputs.mm(ctx.features.t())
return outputs @staticmethod def backward(ctx, grad_outputs): inputs, targets = ctx.saved_tensors grad_inputs = None if ctx.needs_input_grad[0]: grad_inputs = grad_outputs.mm(ctx.features) #[32,2048] batch_centers = collections.defaultdict(list) for instance_feature, index in zip(inputs, targets.tolist()): batch_centers[index].append(instance_feature) for index, features in batch_centers.items(): distances = [] for feature in features: distance = feature.unsqueeze(0).mm(ctx.features[index].unsqueeze(0).t())[0][0] distances.append(distance.cpu().numpy()) median = np.argmin(np.array(distances)) ctx.features[index] = ctx.features[index] ctx.momentum + (1 - ctx.momentum) features[median] ctx.features[index] /= ctx.features[index].norm() return grad_inputs, None, None, None def cm_hard(inputs, indexes, features, momentum=0.5): return CM_Hard.apply(inputs, indexes, features, torch.Tensor([momentum]).to(inputs.device))
Could you tell me how to show the advantages about CM_hard compared with the baseline CM in Spcl?