diff --git a/README.md b/README.md index 1c7bffc8..434a1255 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,10 @@ See [INSTALLATION](docs/en/installation.md) for details. See [GETTING STARTED](GETTING_STARTED.md) for details. +## Custom dataset examples + +See [examples](examples) + ## Notes ⚠️ The current version is based on the [static shape of GRAPH](https://mindspore.cn/docs/en/r2.0/note/static_graph_syntax_support.html). diff --git a/docs/zh/how_to_guides/data_preparation.md b/docs/zh/how_to_guides/data_preparation.md index c5c0d076..975ecd10 100644 --- a/docs/zh/how_to_guides/data_preparation.md +++ b/docs/zh/how_to_guides/data_preparation.md @@ -6,13 +6,13 @@ ``` └─ coco2017_yolo ├─ annotations - └─ instances_val2017.json + │ └─ instances_val2017.json ├─ images - ├─ train2017 # coco2017 原始图片 - └─ val2017 # coco2017 原始图片 + │ ├─ train2017 # coco2017 原始图片 + │ └─ val2017 # coco2017 原始图片 ├─ labels - ├─ train2017 - └─ val2017 + │ ├─ train2017 + │ └─ val2017 ├─ train2017.txt ├─ val2017.txt └─ test-dev2017.txt diff --git a/examples/finetune_car_detection/crejson.py b/examples/finetune_car_detection/crejson.py index 6eda17a4..1bb24f65 100644 --- a/examples/finetune_car_detection/crejson.py +++ b/examples/finetune_car_detection/crejson.py @@ -82,4 +82,3 @@ def init_coco_format(): # 为每个分区保存JSON文件 with open(f"./annotations/instances_val2017.json", "w") as json_file: json.dump(coco_format, json_file, indent=4) - \ No newline at end of file diff --git a/examples/finetune_car_detection/rename.py b/examples/finetune_car_detection/rename.py index 11a2f7c3..6ef420a2 100644 --- a/examples/finetune_car_detection/rename.py +++ b/examples/finetune_car_detection/rename.py @@ -5,7 +5,7 @@ start_num = 1 # 获取当前目录下所有的.txt文件 -files = [f for f in os.listdir('images/train') if f.endswith(extension)] +files = [f for f in os.listdir('images/val') if f.endswith(extension)] for i, file in enumerate(files, start=start_num): # 构造新的文件名,使用zfill填充前导零 @@ -13,10 +13,9 @@ # 使用os.rename重命名文件 # 需根据自己的路径修改 - os.chdir('D:/Desktop/mindspore/yolo_car_detection/bddua/bdd100k/images/train') + os.chdir('images/val') os.rename(file, new_filename) #print(f"Renamed '{file}' to '{new_filename}'") print("All files have been renamed.") - diff --git a/examples/finetune_car_detection/voc2yolo.py b/examples/finetune_car_detection/voc2yolo.py index 0b514eec..9903645f 100644 --- a/examples/finetune_car_detection/voc2yolo.py +++ b/examples/finetune_car_detection/voc2yolo.py @@ -1,7 +1,6 @@ import xml.etree.ElementTree as ET import sys import os.path -import cv2 class XmlParse: @@ -43,7 +42,7 @@ def xml2txt(xml, labels, name_list, img_path): fil_name = root.find('filename').text[:-4] if not os.path.exists(labels): # 如果路径不存在则创建 os.mkdir(labels) - out = open(labels + './' + fil_name + '.txt', 'w+') + out = open(labels + '/' + fil_name + '.txt', 'w+') for obj in root.iter('object'): x_min = float(obj.find('bndbox').find('xmin').text) @@ -74,8 +73,7 @@ def xml2txt(xml, labels, name_list, img_path): # print(w) # print(h) - #class_dict = dict(zip(name_list, range(0, len(name_list)))) - class_dict={'rider':0, 'pedestrian':1, 'trailer':2, 'train':3,'bus':4,'car':5,'truck':6,'traffic sign':7,'traffic light':8,'other person':9,'motorcycle':10,'bicycle':11} + class_dict = {name: i for i, name in enumerate(name_list)} class_name = obj.find('name').text if class_name not in name_list: pass @@ -100,8 +98,7 @@ def folder_Path(): img_path = './images/val' xml_path = './labels_xml/val' # xml路径 labels = './val' # 转txt路径 - #name_list = ['rider', 'pedestrian', 'trailer', 'train','bus','car','truck','traffic sign','traffic light','other person','motorcycle','bicycle'] # 类别名 - name_list = ['rider', 'pedestrian', 'trailer', 'train','bus','car','truck','traffic sign','traffic light','other person','motorcycle','bicycle',"van"] # 类别名 + name_list = ['rider', 'pedestrian', 'trailer', 'train', 'bus', 'car', 'truck', 'traffic sign', 'traffic light', 'other person', 'motorcycle', 'bicycle', "van"] # 类别名 xml2txt(xml_path, labels, name_list, img_path) diff --git a/examples/finetune_single_class_dataset/README.md b/examples/finetune_single_class_dataset/README.md new file mode 100644 index 00000000..bb4d18fe --- /dev/null +++ b/examples/finetune_single_class_dataset/README.md @@ -0,0 +1,63 @@ +### 单类别数据集训练流程 + +本文以自制巧克力花生豆数据集为例,介绍单类别数据集使用MindYOLO进行训练的主要流程。 + +#### 数据集格式转换 + +巧克力花生豆数据集采用voc格式的数据标注,其文件目录如下所示: +``` + ROOT_DIR + ├── Annotations + │ ├── 000000.xml + │ └── 000002.xml + ├── Images + │ ├── 000000.jpg + │ └── 000002.jpg + └── Test_Images + ├── 000004.jpg + └── 000006.jpg +``` +数据集格式转换分为以下步骤: + +1. 训练集与验证集转换为yolo格式。可参考[voc2yolo.py](../finetune_car_detection/voc2yolo.py),使用时需修改图片文件夹路径、标签文件夹路径与生成的txt标签文件夹路径,且对训练集和验证集依次完成该过程。 +2. 验证集转换为coco格式。首先完成图片重命名,可参考[rename.py +](../finetune_car_detection/rename.py),使用时需确保当前目录为数据集的根目录。然后生成json文件,可参考[crejson.py](../finetune_car_detection/crejson.py),使用时需修改验证集图片文件夹路径,验证集txt标注文件路径以及生成的json文件路径。 + +#### 编写yaml配置文件 +配置文件继承[yolov8n.yaml](../../configs/yolov8/yolov8n.yaml),并且列出需要修改的参数,通常包括数据集相关参数以及学习率等超参,如下所示: +``` +__BASE__: [ + '../../configs/yolov8/yolov8n.yaml', +] + +data: + dataset_name: seed + train_set: ./seed/train.txt + val_set: ./seed/val.txt + nc: 1 + # class names + names: [ 'seed' ] + +optimizer: + lr_init: 0.001 # initial learning rate + warmup_bias_lr: 0.01 # warmup initial bias lr + min_warmup_step: 10 # minmum warmup step +``` +#### 模型训练 +选用yolov8n模型进行训练。 +* 在多卡NPU/GPU上进行分布式模型训练,以8卡为例: + + ```shell + mpirun --allow-run-as-root -n 8 python train.py --config ./examples/finetune_single_class_dataset/yolov8n_single_class_dataset.yaml --is_parallel True + ``` + +#### 可视化推理 +使用/demo/predict.py即可用训练好的模型进行可视化推理,运行方式如下: + +```shell +python demo/predict.py --config ./examples/finetune_single_class_dataset/yolov8n_single_class_dataset.yaml --weight=/path_to_ckpt/WEIGHT.ckpt --image_path /path_to_image/IMAGE.jpg +``` +推理效果如下: +
+ +
\ No newline at end of file diff --git a/examples/finetune_single_class_dataset/yolov8n_single_class_dataset.yaml b/examples/finetune_single_class_dataset/yolov8n_single_class_dataset.yaml new file mode 100644 index 00000000..80bd0768 --- /dev/null +++ b/examples/finetune_single_class_dataset/yolov8n_single_class_dataset.yaml @@ -0,0 +1,16 @@ +__BASE__: [ + '../../configs/yolov8/yolov8n.yaml', +] + +data: + dataset_name: seed + train_set: ./seed/train.txt + val_set: ./seed/val.txt + nc: 1 + # class names + names: [ 'seed' ] + +optimizer: + lr_init: 0.001 # initial learning rate + warmup_bias_lr: 0.01 # warmup initial bias lr + min_warmup_step: 10 # minmum warmup step diff --git a/requirements/cpu_requirements.txt b/requirements/cpu_requirements.txt index 2fc8b85a..aeacfbd1 100644 --- a/requirements/cpu_requirements.txt +++ b/requirements/cpu_requirements.txt @@ -2,7 +2,7 @@ numpy < 2 pyyaml >= 5.3 tqdm pillow == 9.5.0 -mindspore +mindspore <= 2.3.0 pylint pytest opencv-python