Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

the show result is error #4

Open
Evoluange opened this issue Apr 25, 2022 · 11 comments
Open

the show result is error #4

Evoluange opened this issue Apr 25, 2022 · 11 comments

Comments

@Evoluange
Copy link

Hi,Thansk your work.
I am using mmdet-2.23.0 to train solov2 and succuss to get pth model
However,some problem occur when i test model result using demo.py
when i run " python demo.py ./imgs/30208.jpg ./res.jpg ./configs/solo/solo_r101_fpn_3x_coco.py ./SOLO_R101_3x.pth"
the result image show is strange, and other models show same result,why it happen?
30208
image

@Evoluange
Copy link
Author

Evoluange commented Apr 25, 2022

image
image
The test code as follows:

from mmdet.apis import init_detector, inference_detector
from mmdet.apis import show_result_pyplot
import os
 
imagepath = r'./imgs/' #需要加载的测试图片的文件路径
savepath = r'./imgs-test' #保存测试图片的路径
# config_file = r'./configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py' 
# checkpoint_file = r'./faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth'  

config_file = r'./mmdetection-master/configs/solov2/solov2_mobileNetV2_80.py' 
checkpoint_file = r'./mmdetection-master/work_dirs/solov2_mobileNetV2_80/epoch_35.pth'  
device = 'cuda:0'
# init a detector
model = init_detector(config_file, checkpoint_file, device=device)
# inference the demo image
 
for filename in os.listdir(imagepath):
    print(filename)
    img = os.path.join(imagepath, filename)
    result = inference_detector(model, img)
    out_file = os.path.join(savepath, filename)
    show_result_pyplot(model, img, result, out_file, score_thr=0.6)

@lifuguan
Copy link
Owner

It seems the model aims to detect the background rather than the object. How's your mAP result? Is it also strange?

FYI

I've tested the model in COCO dataset, the result is good. #1 (comment)

Tips

Maybe you can load the official pth model to check the results.

@lifuguan
Copy link
Owner

Something must happen in your code. I've tested in your demo image, the result is shown below:
image

My vscode config code:

        {
            "env": {"PYTHONPATH" : "${workspaceRoot}"},
            "name": "solov2-coco:demo",
            "type": "python",
            "request": "launch",
            "program": "${workspaceRoot}/tools_det/demo.py",
            "console": "integratedTerminal",
            "justMyCode": false,
            "args": ["work_dirs/result.jpg", "work_dirs/tmp/class_1_ins_2/demo_solov2.png", "configs/det/solo/solov2_r50_fpn_coco.py", "/disk1/lihao/model_zoo/solo/SOLOv2_fpn_R50_1x.pth"]
        },

@Evoluange
Copy link
Author

configs\det_base_\datasets\coco-instance.py
image
How does it work ? coco is 80 classes
can I delete this line?

@lifuguan
Copy link
Owner

Yes, just delete it. I was testing low-data dataset in that moment.

@Evoluange
Copy link
Author

Hi,I meet some problem when train solov2.
today, I copy your code in mmdetection(2.19.0) to train solov2 model , the only line modified is base\coco-instance.py is (bear,).
I run python tools-det/train.py configs/det/solo/solov2_r50_fpn_coco.py and get trained model to test the result.
when I run python tools-det/demo.py 30208.jpg 30208-res-e12.jpg configs/det/solo/solov2_r50_fpn_coco.py work_dirs/solov2_r50_fpn_coco/epoch_12.pth
the result as follow, it is so strange.
image

To make sure it's not the problem of coco data or too few train iterations ,after all it is 12 epochs not 36 epochs.
I train solov2 model in offical project (WXinlong/SOLO) again.
I run python tools/train.py configs/solov2/solov2_r50_fpn_8gpu_1x.py and get trained model to test the result.
when I run python solo_inference_demo.py --img=30208.jpg --config=configs/solov2/solov2_r50_fpn_8gpu_1x.py --weight=work_dirs/solov2_release_r50_fpn_8gpu_1x/epoch_12.pth
the result as follow,it seems like normal.
image
So, I don not know what's wrong? I can not get right result.

@lifuguan
Copy link
Owner

Again, it would be useful if you can provide your training logs. Because the demo you train on official project(WXlong/SOLO) is also strange, it contains overlap parts. Yet the Matrix NMS should have avoided this situation.

@Evoluange
Copy link
Author

I think the trained model is no problem . The problem is no matrix nms in test phase when run tool-det/demo.py, so all the boxes without nms are drawn in image. why the result your shown above is only one box? can you show your test code ?

@lifuguan
Copy link
Owner

lifuguan commented Apr 27, 2022

A personal question, do you speak Chinese? We can talk in chinese.

DEMO code

The demo.py directly comes from the official mmdetection project.

'''
Author: your name
Date: 2021-12-20 16:47:41
LastEditTime: 2022-04-21 15:48:09
LastEditors: Please set LastEditors
Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
FilePath: /research_workspace/tools_det/demo.py
'''

from argparse import ArgumentParser
import cv2

from mmdet.apis import (async_inference_detector, inference_detector,
                        init_detector, show_result_pyplot)


def parse_args():
    parser = ArgumentParser()
    parser.add_argument('img', help='Image file')
    parser.add_argument('out', help='Image file')
    parser.add_argument('config', help='Config file')
    parser.add_argument('checkpoint', help='Checkpoint file')
    parser.add_argument(
        '--device', default='cuda:0', help='Device used for inference')
    parser.add_argument(
        '--score-thr', type=float, default=0.3, help='bbox score threshold')
    args = parser.parse_args()
    return args

def show_result_pyplot(model,
                       img,
                       result,
                       out_file, #加入out_file,运行时把改行注释删除
                       score_thr=0.5):
    if hasattr(model, 'module'):
        model = model.module
    res_img = model.show_result(
        img,
        result,
        score_thr=score_thr,
        show=False
        )
    cv2.imwrite(out_file, res_img)
    

def main(args):
    # build the model from a config file and a checkpoint file
    model = init_detector(args.config, args.checkpoint, device=args.device)
    # test a single image
    result = inference_detector(model, args.img)
    # show the results
    show_result_pyplot(model, args.img, result, args.out, score_thr=args.score_thr)


if __name__ == '__main__':
    args = parse_args()
    main(args)

Pretrain Model convert code

This code can helps you to convert official solov2 pth to our mmdet format.

# disclaimer: inspired by MoCo official repo and PyContrast repo
import argparse
import pickle as pkl
import sys

import torch

if __name__ == "__main__":

    parser = argparse.ArgumentParser(description='Convert Models')
    parser.add_argument('input', metavar='I', default="/disk1/lihao/model_zoo/InstanceLoc/insloc_c4_400ep.pkl", help='input model path')
    parser.add_argument('output', metavar='O', default="/disk1/lihao/model_zoo/InstanceLoc/insloc_c4_400ep.pth", help='output path')
    parser.add_argument('--c4', action='store_true', help='using ema model')
    args = parser.parse_args()

    print('=========================')
    print(f'converting {args.input}')
    print('=========================')
    torch_weight = torch.load(args.input, encoding='ascii')
    # torch_weight = torch.load(args.input)['state_dict']
    new_state_dict = {}

    for k, v in torch_weight.items():
        # C4 backbone treats C5 layers as the shared head
        if 'roi_head.shared_head' in k:
            old_k = k
            k = k.replace('roi_head.shared_head', 'backbone')
            print(old_k, '---->', k)

        if not args.c4 and 'roi_head.bbox_head.shared_fcs' in k:
            old_k = k
            k = k.replace(f'roi_head.bbox_head.shared_fcs.0.weight',
                          f'roi_heads.box_head.fc1.weight')
            k = k.replace(f'roi_head.bbox_head.shared_fcs.0.bias',
                          f'roi_heads.box_head.fc1.bias')
            print(old_k, '---->', k)
            new_state_dict[k] = v.numpy()
            continue

        if 'backbone' in k and 'layer' not in k and 'backbone_k' not in k:
            old_k = k
            if args.c4:
                # C4 stem
                k = k.replace('backbone',
                              'backbone.stem').replace('bn1', 'conv1.norm')
            else:
                # FPN stem
                k = k.replace('backbone', 'backbone.bottom_up.stem').replace(
                    'bn1', 'conv1.norm')
            print(old_k, '---->', k)
        elif 'backbone' in k and 'backbone_k' not in k and 'layer' in k:
            if args.c4:
                # C4 Backbone
                old_k = k
                if 'layer4' not in k:
                    k = k.replace("layer1", "res2")
                    k = k.replace("layer2", "res3")
                    k = k.replace("layer3", "res4")
                else:
                    k = k.replace("backbone", "roi_heads")
                    k = k.replace("layer4", "res5")
                k = k.replace("bn1", "conv1.norm")
                k = k.replace("bn2", "conv2.norm")
                k = k.replace("bn3", "conv3.norm")
                k = k.replace("downsample.0", "shortcut")
                k = k.replace("downsample.1", "shortcut.norm")
            else:
                # FPN backbone
                old_k = k
                k = k.replace('backbone', 'backbone.bottom_up')
                k = k.replace("layer1", "res2")
                k = k.replace("layer2", "res3")
                k = k.replace("layer3", "res4")
                k = k.replace("layer4", "res5")
                k = k.replace("bn1", "conv1.norm")
                k = k.replace("bn2", "conv2.norm")
                k = k.replace("bn3", "conv3.norm")
                k = k.replace("downsample.0", "shortcut")
                k = k.replace("downsample.1", "shortcut.norm")
            print(old_k, '--->', k)
        elif 'neck' in k and 'neck_k' not in k:
            # FPN neck
            old_k = k
            # replace lateral conv
            k = k.replace('neck.lateral_convs.0.bn',
                          'backbone.fpn_lateral2.norm')
            k = k.replace('neck.lateral_convs.1.bn',
                          'backbone.fpn_lateral3.norm')
            k = k.replace('neck.lateral_convs.2.bn',
                          'backbone.fpn_lateral4.norm')
            k = k.replace('neck.lateral_convs.3.bn',
                          'backbone.fpn_lateral5.norm')

            k = k.replace('neck.lateral_convs.0.conv', 'backbone.fpn_lateral2')
            k = k.replace('neck.lateral_convs.1.conv', 'backbone.fpn_lateral3')
            k = k.replace('neck.lateral_convs.2.conv', 'backbone.fpn_lateral4')
            k = k.replace('neck.lateral_convs.3.conv', 'backbone.fpn_lateral5')

            # replace fpn conv
            k = k.replace('neck.fpn_convs.0.bn', 'backbone.fpn_output2.norm')
            k = k.replace('neck.fpn_convs.1.bn', 'backbone.fpn_output3.norm')
            k = k.replace('neck.fpn_convs.2.bn', 'backbone.fpn_output4.norm')
            k = k.replace('neck.fpn_convs.3.bn', 'backbone.fpn_output5.norm')

            k = k.replace('neck.fpn_convs.0.conv', 'backbone.fpn_output2')
            k = k.replace('neck.fpn_convs.1.conv', 'backbone.fpn_output3')
            k = k.replace('neck.fpn_convs.2.conv', 'backbone.fpn_output4')
            k = k.replace('neck.fpn_convs.3.conv', 'backbone.fpn_output5')
            print(old_k, '--->', k)
        elif 'roi_head.bbox_head.shared_convs' in k:
            # 4conv in det head
            old_k = k
            conv_idx = int(k.split('.')[3])
            k = k.replace(
                f'roi_head.bbox_head.shared_convs.{conv_idx}.conv.weight',
                f'roi_heads.box_head.conv{conv_idx+1}.weight')
            k = k.replace(
                f'roi_head.bbox_head.shared_convs.{conv_idx}.bn.weight',
                f'roi_heads.box_head.conv{conv_idx+1}.norm.weight')
            k = k.replace(
                f'roi_head.bbox_head.shared_convs.{conv_idx}.bn.bias',
                f'roi_heads.box_head.conv{conv_idx+1}.norm.bias')
            k = k.replace(
                f'roi_head.bbox_head.shared_convs.{conv_idx}.bn.running_mean',
                f'roi_heads.box_head.conv{conv_idx+1}.norm.running_mean')
            k = k.replace(
                f'roi_head.bbox_head.shared_convs.{conv_idx}.bn.running_var',
                f'roi_heads.box_head.conv{conv_idx+1}.norm.running_var')
            k = k.replace(
                f'roi_head.bbox_head.shared_convs.{conv_idx}.bn.num_batches_tracked',
                f'roi_heads.box_head.conv{conv_idx+1}.norm.num_batches_tracked'
            )
            print(old_k, '--->', k)
        else:
            continue
        new_state_dict[k] = v.numpy()

    res = {
        "model": new_state_dict,
        "__author__": "Ceyuan",
        "matching_heuristics": True
    }

    with open(args.output, "wb") as f:
        pkl.dump(res, f)

@Evoluange
Copy link
Author

Hello~,按照你提供的方法在mmdet2.19.0上训练solov2模型,结果一直异常满屏蓝色轮廓。之前以为是训练的模型本身是正常的,只是测试时没有做matrix-nms,因为人像轮廓感觉已经出来了(如上面图所示)。现在我把pth模型转成onnx用c++前传,测试结果仍然是异常,现象和之前一模一样,这应该是模型本身的问题了。
代码唯一改动的地方就是把bear注释掉了,然后改用coco-val集来训练:
改动部分:
360截图20220427170243897
然后训练:
python tools-det/train.py configs/det/solo/solov2_r50_fpn_coco.py
训练日志截图:
360截图20220427170437414
测试代码:
python demo.py 30208.jpg 30208-result.jpg configs/det/solo/solov2_r50_fpn_coco.py work_dirs/solov2_r50_fpn_coco/epoch_12.pth
出现异常结果,不确定问题出在哪儿了?

@Evoluange
Copy link
Author

您好,我在mmdet2.19版本上面加入您的代码,用coco-train数据集上面重新训练模型。作为对照,我先用mmdet上开源的mask-rcnn训练模型和测试模型,确定整体代码测试脚本和训练数据都没有异常。然后我再加入你的det和custom目录到mmdet2.19中训练solov2模型,用相同的脚本在coco-val上测试,结果还是异常。
异常点1:总共80类里面,几乎只有person一个类别识别出来了,拿大量图片测试偶尔发现零星其他类别但真很少见
异常点2:单个人的图片人没有分割出来,但背景被识别成人
异常点3:阈值设置为0.8时人像框特别多,感觉没有做NMS
异常点4:多个人存在时分割遗漏,只分割了一个,其他漏掉了
2345截图20220505111650
2345截图20220505111708

另外,我在使用您网站上下载的模型进行测试时,会报错unexpected key in source state_dict: mask_feat_head,missing keys in source state_dict: mask_head,对模型转换之后测试不报错,但是测试结果图片仍然有上面异常点1和异常点4的问题
2345截图20220505111337
2345截图20220505111353

感觉还是有不对劲的地方,无法复现你展示的结果。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants