利用maskFormer/mask2Former配置环境并训练自己的数据集

1. 配置环境:

使用detectron2配置的环境,所以也是复制之前电脑上用过detectron2的环境

conda create -n mask2former --clone PatchDCT
conda activate mask2former

然后在requirement里面下载需要的包

另外在mask2former中还需要make一下:

利用maskFormer/mask2Former配置环境并训练自己的数据集_第1张图片

2. 数据集配置

利用之前配置好的coco数据集,但由于maskFormer/mask2Former使用的数据集是包含实例分割和语义分割,还需要在datasets/prepare_ade20k_sem_seg.py输出符合代码运行的数据集格式。

利用maskFormer/mask2Former配置环境并训练自己的数据集_第2张图片

环境里面还需要导入包:

pip install git+https://github.com/cocodataset/panopticapi.git

 在trin_net.py加入:(这个在之前创建自己的coco数据集也有提到)

# 自己的数据集
from detectron2.data import DatasetCatalog
from detectron2.data.datasets.coco import load_coco_json
os.environ['CUDA_LAUNCH_BLOCKING'] = '1'
# 声明类别,尽量保持  #需修改成为自己的类别名称
# CLASS_NAMES = ["_background_", "person", "bicycle", "car", "UAV"] # 没有背景就不标注背景
CLASS_NAMES = ["person", "bicycle", "car", "UAV"]
# 数据集类别元数据
DATASET_CATEGORIES = [
    {"name": "person", "id": 0, "isthing": 1, "color": [219, 142, 185]},
    {"name": "bicycle", "id": 1, "isthing": 1, "color": [119, 11, 32]},
    {"name": "car", "id": 2, "isthing": 1, "color": [0, 0, 142]},
    {"name": "UAV", "id": 3, "isthing": 1, "color": [119, 11, 32]},
]

# 数据集路径 此路径需修改为自己的路径
DATASET_ROOT = r'G:/coco_4classes'
ANN_ROOT = os.path.join(DATASET_ROOT, 'annotations')

TRAIN_PATH = os.path.join(DATASET_ROOT, 'train2017')
VAL_PATH = os.path.join(DATASET_ROOT, 'val2017')

TRAIN_JSON = os.path.join(ANN_ROOT, 'instances_train2017.json')
# VAL_JSON = os.path.join(ANN_ROOT, 'val.json')
VAL_JSON = os.path.join(ANN_ROOT, 'instances_val2017.json')
# print(TRAIN_PATH)
# 声明数据集的子集 coco_my_train  修改为自己的数据集名字
PREDEFINED_SPLITS_DATASET = {
    "coco_my_train": (TRAIN_PATH, TRAIN_JSON),
    "coco_my_val": (VAL_PATH, VAL_JSON),
}


# 注册数据集
def register_dataset():
    """
    purpose: register all splits of dataset with PREDEFINED_SPLITS_DATASET
    """
    for key, (image_root, json_file) in PREDEFINED_SPLITS_DATASET.items():
        register_dataset_instances(name=key,
                                   metadate=get_dataset_instances_meta(),
                                   json_file=json_file,
                                   image_root=image_root)


def get_dataset_instances_meta():
    """
    purpose: get metadata of dataset from DATASET_CATEGORIES
    return: dict[metadata]
    """
    thing_ids = [k["id"] for k in DATASET_CATEGORIES if k["isthing"] == 1]
    thing_colors = [k["color"] for k in DATASET_CATEGORIES if k["isthing"] == 1]
    # assert len(thing_ids) == 2, len(thing_ids)
    thing_dataset_id_to_contiguous_id = {k: i for i, k in enumerate(thing_ids)}
    thing_classes = [k["name"] for k in DATASET_CATEGORIES if k["isthing"] == 1]
    ret = {
        "thing_dataset_id_to_contiguous_id": thing_dataset_id_to_contiguous_id,
        "thing_classes": thing_classes,
        "thing_colors": thing_colors,
    }
    return ret


# # 注册数据集实例,加载数据集中的对象实例
def register_dataset_instances(name, metadate, json_file, image_root):
    """
    purpose: register dataset to DatasetCatalog,
             register metadata to MetadataCatalog and set attribute
    """
    DatasetCatalog.register(name, lambda: load_coco_json(json_file, image_root, name))
    MetadataCatalog.get(name).set(json_file=json_file,
                                  image_root=image_root,
                                  evaluator_type="coco",
                                  **metadate)


# 注册数据集和元数据
def plain_register_dataset():
    # 训练集
    DatasetCatalog.register("coco_my_train", lambda: load_coco_json(TRAIN_JSON, TRAIN_PATH))
    MetadataCatalog.get("coco_my_train").set(thing_classes=CLASS_NAMES,  # 可以选择开启,但是不能显示中文,这里需要注意,中文的话最好关闭
                                             evaluator_type='coco',  # 指定评估方式
                                             json_file=TRAIN_JSON,
                                             image_root=TRAIN_PATH)

    # DatasetCatalog.register("coco_my_val", lambda: load_coco_json(VAL_JSON, VAL_PATH, "coco_2017_val"))
    # 验证/测试集
    DatasetCatalog.register("coco_my_val", lambda: load_coco_json(VAL_JSON, VAL_PATH))
    MetadataCatalog.get("coco_my_val").set(thing_classes=CLASS_NAMES,  # 可以选择开启,但是不能显示中文,这里需要注意,中文的话最好关闭
                                           evaluator_type='coco',  # 指定评估方式
                                           json_file=VAL_JSON,
                                           image_root=VAL_PATH)

再在def setup 里面修改配置参数即可

利用maskFormer/mask2Former配置环境并训练自己的数据集_第3张图片

注意别忘记在main函数加入:

plain_register_dataset()  # 新加的数据集代码

利用maskFormer/mask2Former配置环境并训练自己的数据集_第4张图片

3. 出现问题:

1. Attribute 'ignore_label' does not exist in the metadata of dataset 'coco_my_train'

网上的原因是说detectron2版本低于0.4.0,但是我的版本是0.6.0,所以就直接在注册自己的数据集里面加入了这个参数:

# 注册数据集和元数据
def plain_register_dataset():
    # 训练集
    DatasetCatalog.register("coco_my_train", lambda: load_coco_json(TRAIN_JSON, TRAIN_PATH))
    MetadataCatalog.get("coco_my_train").set(thing_classes=CLASS_NAMES,  # 可以选择开启,但是不能显示中文,这里需要注意,中文的话最好关闭
                                             evaluator_type='coco',  # 指定评估方式
                                             ignore_label=255,   # 缺少这个标签,加上
                                             json_file=TRAIN_JSON,
                                             image_root=TRAIN_PATH)

    # DatasetCatalog.register("coco_my_val", lambda: load_coco_json(VAL_JSON, VAL_PATH, "coco_2017_val"))
    # 验证/测试集
    DatasetCatalog.register("coco_my_val", lambda: load_coco_json(VAL_JSON, VAL_PATH))
    MetadataCatalog.get("coco_my_val").set(thing_classes=CLASS_NAMES,  # 可以选择开启,但是不能显示中文,这里需要注意,中文的话最好关闭
                                           evaluator_type='coco',  # 指定评估方式
                                           ignore_label=255,  # 缺少这个标签,加上
                                           json_file=VAL_JSON,
                                           image_root=VAL_PATH)

2. ValueError: matrix contains invalid numeric entries

经查阅有两种解决方式

(1).降低学习率lr

(2).在_lsap.py文件中加上   

    if np.any(np.isneginf(cost_matrix) | np.isnan(cost_matrix)):
        raise ValueError("matrix contains invalid numeric entries")

我先尝试了第一个办法,把学习率降低到了0.0001。

3.  Attribute 'thing_dataset_id_to_contiguous_id' does not exist in the metadata of dataset 'coco_my_train'.

但是我在get_dataset_instances_meta()定义了这个关于metadata的函数,是定义了thing_dataset_id_to_contiguous_id'

def get_dataset_instances_meta():
    """
    purpose: get metadata of dataset from DATASET_CATEGORIES
    return: dict[metadata]
    """
    thing_ids = [k["id"] for k in DATASET_CATEGORIES if k["isthing"] == 1]
    thing_colors = [k["color"] for k in DATASET_CATEGORIES if k["isthing"] == 1]
    # assert len(thing_ids) == 2, len(thing_ids)
    thing_dataset_id_to_contiguous_id = {k: i for i, k in enumerate(thing_ids)}
    thing_classes = [k["name"] for k in DATASET_CATEGORIES if k["isthing"] == 1]
    ret = {
        "thing_dataset_id_to_contiguous_id": thing_dataset_id_to_contiguous_id,
        "thing_classes": thing_classes,
        "thing_colors": thing_colors,
    }
    return ret

利用新的代码注册数据集,直接在train_net里面加入class Register 注册自己的数据集:

# 注册自己的数据集
import cv2
from detectron2.data import DatasetCatalog
from detectron2.data.datasets.coco import load_coco_json
from detectron2.utils.visualizer import Visualizer
class Register:
    """用于注册自己的数据集"""
    # 声明类别,尽量保持  #需修改成为自己的类别名称
    # CLASS_NAMES = ["_background_", "person", "bicycle", "car", "UAV"] # 没有背景就不标注背景
    CLASS_NAMES = ["person", "bicycle", "car", "UAV"]
    # ROOT = r'G:/coco_4classes'  # 图片所在目录

    def __init__(self):
        self.CLASS_NAMES = Register.CLASS_NAMES
        # 数据集路径,此路径需修改为自己的路径
        DATASET_ROOT = r'G:/coco_4classes'
        self.ANN_ROOT = os.path.join(DATASET_ROOT, 'annotations')
        # self.ANN_ROOT = "/home/user/yourdir/detectron2/datasets/coco/annotations"

        self.TRAIN_PATH = os.path.join(DATASET_ROOT, 'train2017')
        self.VAL_PATH = os.path.join(DATASET_ROOT, 'val2017')

        self.TRAIN_JSON = os.path.join(self.ANN_ROOT, 'instances_train2017.json')
        self.VAL_JSON = os.path.join(self.ANN_ROOT, 'instances_val2017.json')

        # 声明数据集的子集,coco_my_train  修改为自己的数据集名字
        self.PREDEFINED_SPLITS_DATASET = {
            "coco_my_train": (self.TRAIN_PATH, self.TRAIN_JSON),
            "coco_my_val": (self.VAL_PATH, self.VAL_JSON),
        }

    # 注册数据集
    def register_dataset(self):
        """
        purpose: register all splits of datasets with PREDEFINED_SPLITS_DATASET
        注册数据集(这一步就是将自定义数据集注册进Detectron2)
        """
        for key, (image_root, json_file) in self.PREDEFINED_SPLITS_DATASET.items():
            self.register_dataset_instances(name=key,
                                            json_file=json_file,
                                            image_root=image_root)

    @staticmethod
    def register_dataset_instances(name, json_file, image_root):
        """
        purpose: register datasets to DatasetCatalog,
                 register metadata to MetadataCatalog and set attribute
        注册数据集实例,加载数据集中的对象实例
        """
        DatasetCatalog.register(name, lambda: load_coco_json(json_file, image_root, name))
        MetadataCatalog.get(name).set(json_file=json_file,
                                      image_root=image_root,
                                      evaluator_type="coco")

    def plain_register_dataset(self):
        """注册数据集和元数据"""
        # 训练集
        DatasetCatalog.register("coco_my_train", lambda: load_coco_json(self.TRAIN_JSON, self.TRAIN_PATH))
        MetadataCatalog.get("coco_my_train").set(thing_classes=self.CLASS_NAMES,  # 可以选择开启,但是不能显示中文,这里需要注意,中文的话最好关闭
                                                 evaluator_type='coco',  # 指定评估方式
                                                 json_file=self.TRAIN_JSON,
                                                 image_root=self.TRAIN_PATH)

        # DatasetCatalog.register("coco_my_val", lambda: load_coco_json(VAL_JSON, VAL_PATH, "coco_2017_val"))
        # 验证/测试集
        DatasetCatalog.register("coco_my_val", lambda: load_coco_json(self.VAL_JSON, self.VAL_PATH))
        MetadataCatalog.get("coco_my_val").set(thing_classes=self.CLASS_NAMES,  # 可以选择开启,但是不能显示中文,这里需要注意,中文的话最好关闭
                                               evaluator_type='coco',  # 指定评估方式
                                               json_file=self.VAL_JSON,
                                               image_root=self.VAL_PATH)

    def checkout_dataset_annotation(self, name="coco_my_val"):
        """
        查看数据集标注,可视化检查数据集标注是否正确,
        这个也可以自己写脚本判断,其实就是判断标注框是否超越图像边界
        可选择使用此方法
        """
        # dataset_dicts = load_coco_json(TRAIN_JSON, TRAIN_PATH, name)
        dataset_dicts = load_coco_json(self.TRAIN_JSON, self.TRAIN_PATH)
        print(len(dataset_dicts))
        for i, d in enumerate(dataset_dicts, 0):
            # print(d)
            img = cv2.imread(d["file_name"])
            visualizer = Visualizer(img[:, :, ::-1], metadata=MetadataCatalog.get(name), scale=1.5)
            vis = visualizer.draw_dataset_dict(d)
            # cv2.imshow('show', vis.get_image()[:, :, ::-1])
            cv2.imwrite('out/' + str(i) + '.jpg', vis.get_image()[:, :, ::-1])
            # cv2.waitKey(0)
            if i == 200:
                break

注意在def main(args)加入这个:

def main(args):
    cfg = setup(args)
    # 记得加入这个
    Register().register_dataset()  # register my dataset

运行即可。

你可能感兴趣的:(深度学习,人工智能,python,pytorch)