BAM icon indicating copy to clipboard operation
BAM copied to clipboard

关于coco的fss_list文件中train下data_list_0文件

Open Strike1999 opened this issue 3 years ago • 11 comments

你好!

很感谢你们启发性的工作!

我在复现的过程中发现coco的fss_list文件中train下data_list_0文件中图片和标注都要比其他其他list少一半,最后得到的coco上split0 1shot的mean iou结果只有37.8(比原论文中结果少了5.51),而其他的split的结果都比较正常。请问这是什么原因呢?

谢谢!

Strike1999 avatar Jun 25 '22 05:06 Strike1999

您好, 感谢对我们工作的关注!

  1. 首先,请确认coco_split0的data_list含有21917(train)和26052(test)项,这部分list在原始的repo中上传有误。
  2. 不同split下样本数目不同与coco数据集原始样本分布有关,在某一个split下,更多的train样本对应更少的test样本。您可以查看日志输出的训练时间进行对比,split0训练成本更低。
  3. 利用我们提供的模型进行推理以检查样本的完备性,如无误,建议重新训练并尽可能避免resume。

欢迎随时讨论~

祝好,

chunbolang avatar Jun 25 '22 06:06 chunbolang

您好, 非常感谢您的回复!

我们去除了val文件中的一部分(每个split去除了150张左右),因为我们发现在evaluation的过程中,如果使用原始的coco_split文件下val的txt文件,程序会报错,报错信息如下:

File "/home/shengmengmeng/BAM/util/dataset.py", line 234, in __getitem__
    assert len(label_class) > 0
AssertionError

我们试着去dataset.py文件里找问题,在dataset.py文件220行-234行中:

        label_class = np.unique(label).tolist()
        if 0 in label_class:
            label_class.remove(0)
        if 255 in label_class:
            label_class.remove(255) 
        new_label_class = []
        for c in label_class:
            if c in self.sub_val_list:
                if self.mode == 'val' or self.mode == 'demo' or self.mode == 'finetune':
                    new_label_class.append(c)
            if c in self.sub_list:
                if self.mode == 'train':
                    new_label_class.append(c)
        label_class = new_label_class    
        assert len(label_class) > 0

我们认为是在某个split下,有些标注图片的class都不在这个split的sub_val_list中,导致label_class等于0。所以我们对每个split分别去除了这些图片,每个split去除了150张左右。

我们不清楚是不是这个操作导致了miou下降,我们用您提供的split0权重在我们修改过后的val txt下进行测试,结果只有37.7。

再次感谢!

Strike1999 avatar Jun 26 '22 02:06 Strike1999

您好,无论训练/测试都不会存在某一幅图像不包含属于sub_list/sub_val_list中任一类别的情况,因此出现assert报错需要检查所构建的coco数据集是否完备,特别是生成的png标注的正确性。可参考下面的代码:

from pycocotools.coco import COCO
import numpy as np
import cv2
import os
import time
from tqdm import tqdm

write_mode = 'val' # train val
generate_list = False
data_root_path = '/disk2/lcb/datasets/MSCOCO2014'

annFile = data_root_path + '/annotations/instances_{}2014.json'.format(write_mode)
img_dir = data_root_path + '/{}2014'.format(write_mode)
save_dir = data_root_path + '/annotations/{}2014'.format(write_mode)

if not os.path.exists(save_dir):
    print('{} has been created!'.format(save_dir))
    os.mkdir(save_dir)


coco=COCO(annFile)
# display COCO categories and supercategories
cats = coco.loadCats(coco.getCatIds())

nms=[cat['name'] for cat in cats]
num_cats = len(nms)
print('All {} categories.'.format(num_cats))
print(nms)


# get all images ids
imgIds = coco.getImgIds()
num_img = len(imgIds)
print('All {} images.'.format(num_img))


sum_time = 0
for idx, im_id in enumerate(imgIds):  
    start_time = time.time()
    # load annotations
    annIds = coco.getAnnIds(imgIds=im_id, iscrowd=False)
    if len(annIds) == 0:
        continue

    image = coco.loadImgs([im_id])[0]
    # image.keys: ['coco_url', 'flickr_url', 'date_captured', 'license', 'width', 'height', 'file_name', 'id']
    h, w = image['height'], image['width']
    gt_name = image['file_name'].split('.')[0] + '.png'
    gt = np.zeros((h, w), dtype=np.uint8)

    # ann.keys: ['area', 'category_id', 'bbox', 'iscrowd', 'id', 'segmentation', 'image_id']
    anns = coco.loadAnns(annIds)
    for ann_idx, ann in enumerate(anns):

        cat = coco.loadCats([ann['category_id']])
        cat = cat[0]['name']
        cat = nms.index(cat) + 1    # cat_id ranges from 1 to 80

        ## below is the original script 
        segs = ann['segmentation']
        for seg in segs:
            seg = np.array(seg).reshape(-1, 2)    # [n_points, 2]      
            cv2.fillPoly(gt, seg.astype(np.int32)[np.newaxis, :, :], int(cat))

    save_gt_path = os.path.join(save_dir, gt_name)
    cv2.imwrite(save_gt_path, gt)

    cost_time = time.time() - start_time
    sum_time += cost_time
    avg_time = sum_time*1.0/(idx + 1)
    left_time = avg_time * (len(imgIds) - idx)/60

    if idx % 100 == 0:
        print('Processed {}/{} images. Time: {:.4f} min'.format(idx, num_img, left_time))



# --------------- Generate data list ---------------
if generate_list:
    img_files_list = os.listdir(save_dir)
    with open('./lists/coco/{}.txt'.format(write_mode), 'a') as f:
        for img_id in tqdm(range(len(img_files_list))):
            mask_str = img_files_list[img_id]
            img_str = mask_str.split('.')[0] + '.jpg'
            f.write('{}2014/'.format(write_mode) + img_str + ' ')
            f.write('annotations/{}2014/'.format(write_mode) + mask_str + '\n')


# get voc id in coco
voc_cls_name = ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 
                'bus', 'train', 'boat',  'bird', 'cat', 
                'dog', 'horse', 'sheep', 'cow', 'bottle', 
                'chair', 'couch', 'potted plant', 'dining table', 'tv']
voc_id = []
for name in voc_cls_name:
    voc_id.append(nms.index(name) + 1)
# voc_id = [1, 2, 3, 4, 5, 6, 7, 9, 15, 16, 17, 18, 19, 20, 40, 57, 58, 59, 61, 63]

chunbolang avatar Jun 26 '22 04:06 chunbolang

您好!

我们重新下载了COCO2014验证集图片与标注的json文件,并使用您上面提供的代码将json文件转化为PNG的格式,并尝试用您提供的BAM模型进行在验证集上进行测试。结果split0的结果只有39.1,其他三个split的结果都和论文结果非常接近(但不是完全相同),这非常令我们困惑。

是不是在将标注json文件转化为PNG,和加载标注PNG图片时出现了不对应的情况?

很感谢您的耐心解答!!

Strike1999 avatar Jun 27 '22 07:06 Strike1999

按您的说明,出现不对应的情况可能性不大。

对于目前的现象我也十分困惑,最近有其他相关工作基于这个repo取得新的sota,参考这里,coco-split0结果看起来也是正常的。

就我而言,如果较难复现论文中的结果,完全可以按照您的复现数据在后续工作中呈现,并不会对工作的质量产生负面影响,参照ASGNet(CVPR21)对PFENet的复现。

chunbolang avatar Jun 27 '22 08:06 chunbolang

您好!

我们注意到在test.py文件中,代码设置了随机种子、采样的次数以及每次采样的数量,每次采样都会从对应的list文件下面选取相应数量的图片进行测试:

val_manual_seed = 123
val_num = 5

    elif args.data_set == 'coco':
        test_num = 1000
        split_gap = 20

想请问一下为什么要进行这样的测试,可不可以对所有对应验证集图片进行测试?

Strike1999 avatar Jun 30 '22 06:06 Strike1999

  • 大多数文章会给出5次独立运行的平均mIoU。
  • 遍历所有的support-query组合成本很高,当然理论上是可以的。

chunbolang avatar Jun 30 '22 06:06 chunbolang

您好!

我们使用HSNet提供的[val2014.zip]PNG格式的文件,得到了和论文一致的结果。但使用该数据得到的BAM split0结果和之前一样,我觉得是annotation中标注不对应造成的。

我们也测试了最新的MSANet的模型,该模型也使用了BAM中的Base learner框架,结果出现了和BAM相同的问题:split0异常,其他split正常。

不知道您是否可以提供一下val2014的annotation文件吗?麻烦您了,万分感谢!

Strike1999 avatar Jul 01 '22 07:07 Strike1999

FSS的png标注由这部分代码生成 ---> https://github.com/chunbolang/BAM/issues/30#issuecomment-1166416040 Base learner训练需要的相关标注可访问此链接获得。

chunbolang avatar Jul 01 '22 12:07 chunbolang

您好!

我们使用HSNet提供的[val2014.zip]PNG格式的文件,得到了和论文一致的结果。但使用该数据得到的BAM split0结果和之前一样,我觉得是annotation中标注不对应造成的。

我们也测试了最新的MSANet的模型,该模型也使用了BAM中的Base learner框架,结果出现了和BAM相同的问题:split0异常,其他split正常。

不知道您是否可以提供一下val2014的annotation文件吗?麻烦您了,万分感谢!

我也遇到了相同的问题,在split0上的结果有问题,是39点几,请问您最后解决了吗?

jingyi1997 avatar Jul 09 '22 03:07 jingyi1997

您好! 我们使用HSNet提供的[val2014.zip]PNG格式的文件,得到了和论文一致的结果。但使用该数据得到的BAM split0结果和之前一样,我觉得是annotation中标注不对应造成的。 我们也测试了最新的MSANet的模型,该模型也使用了BAM中的Base learner框架,结果出现了和BAM相同的问题:split0异常,其他split正常。 不知道您是否可以提供一下val2014的annotation文件吗?麻烦您了,万分感谢!

我也遇到了相同的问题,在split0上的结果有问题,是39点几,请问您最后解决了吗?

还没有

Strike1999 avatar Jul 09 '22 03:07 Strike1999