使用脚本切分训练集
pip install matplotlib
python3 make_voc.py --dataset datasets/测试数据集
import argparse
import random
import re
from pathlib import Path
from matplotlib import pyplot as plt
annotations_name = 'Annotations'
jpegimages_name = 'JPEGImages'
trainval_name = 'trainval.txt'
text_file_name = 'test.txt'
val_file_name = 'val.txt'
def write_file(datas, file):
results = []
for data in datas:
annotation = Path(annotations_name, f'{data}.xml')
image = Path(jpegimages_name, f'{data}.jpg')
result = f'{image} {annotation}'
results.append(result)
with file.open('w')as f:
f.write("\n".join(results))
print(file, "success")
def make_paddle_voc(dataset):
dataset = Path(dataset)
assert dataset.is_dir(), "Error dataset path"
annotations_path = dataset / annotations_name
images_path = dataset / jpegimages_name
if not (annotations_path.is_dir() and images_path.is_dir()):
print("Please use the following structure:")
print(f"{dataset.name}")
print(f'\t{annotations_name}\n\t\t|--00001.xml\n\t\t|--00002.xml')
print(f'\t{jpegimages_name}\n\t\t|--00001.jpg\n\t\t|--00002.jpg')
raise RuntimeError(f'Error {jpegimages_name} or {annotations_name} dir')
paddle_path = dataset / 'paddle'
paddle_path.mkdir(exist_ok=True, parents=True)
trainval_path = paddle_path / trainval_name
test_path = paddle_path / text_file_name
val_path = paddle_path / val_file_name
annotations = annotations_path.glob('*.xml')
images = images_path.glob('*.jpg')
images_list = [image.name for image in images]
annotations_list = []
for annotation in annotations:
image = annotation.with_suffix('.jpg').name
assert image in images_list, f"{annotation.name} has no image file"
annotations_list.append(annotation.stem)
random.shuffle(annotations_list)
per = round(len(annotations_list)/10)
trainval = annotations_list[:per*7] # 此处切分比例为8:1:1 可行修改比例
test = annotations_list[per*7:per*9]
val = annotations_list[per*9:]
write_file(trainval, trainval_path)
write_file(test, test_path)
write_file(val, val_path)
def check_labels(dataset):
dataset = Path(dataset)
annotations_path = dataset / annotations_name
class_list = {}
for annotation_path in annotations_path.glob('*.xml'):
with annotation_path.open('r')as f:
names = re.findall(r'(.+?) ', f.read())
for name in names:
if name not in class_list.keys():
class_list[name] = 0
class_list[name] += 1
class_list = dict(sorted(class_list.items()))
label_list = dataset / 'label_list.txt'
with label_list.open('w')as f:
f.write('\n'.join(class_list.keys()))
fig, ax = plt.subplots()
[ax.text(a, b + 1, b, ha='center', va='bottom') for a, b in class_list.items()]
plt.bar(*zip(*class_list.items()))
plt.xticks(rotation=270)
plt.title('Detection category distribution')
plt.xlabel('Class')
plt.ylabel('Number')
plt.tight_layout()
plt.savefig(f"{dataset / '类别分布.jpg'}", format="jpg")
print(f"Save as {dataset / '类别分布.jpg'}")
print(f"共{len(class_list)}类")
if __name__=='__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--dataset', required=True, help='input dataset path, necessary parameter')
opt = parser.parse_args()
check_dataset(opt.dataset)
make_paddle_voc(opt.dataset)
check_labels(opt.dataset)
创建数据集配置文件
python3 tools/train.py -c configs/ppyoloe/ppyoloe_crn_s_300e_voc.yml
python3 -u tools/eval.py -c configs/ppyoloe/ppyoloe_crn_s_300e_voc.yml
python3 -u tools/infer.py -c configs/ppyoloe/ppyoloe_crn_s_300e_voc.yml --infer_img=test.jpg --draw_threshold=0.5
python3 tools/export_model.py -c configs/ppyoloe/ppyoloe_crn_s_300e_voc.yml --output_dir=output/ppyoloe_crn_s_300e_voc/ -o weights=output/ppyoloe_crn_s_300e_voc/best_model