一.虚拟环境
1.使用Anaconda创建虚拟环境
打开Anaconda prompt,输入
conda create -n your_env_name python=3.9 #your_env_name为你想创建的环境名。
#python=3.9为你想要的python版本,例如可以python=3.8等
2.进入虚拟环境中
使用命令
activate your_env_name
注:base为你的基础环境,我预先创建了一个叫做pytorch的虚拟环境,使用activate pytroch即可进入
二.环境配置
YOLOv8的公司已经将yolov8的源码集成到了包中,我们只需ultralytics安装包便可
pip install ultralytics
建议安装环境时python版本>=3.8比较合适,同时需要安装pytorch版本>=1.7
三.数据集
1.数据集来源
我的数据集来自于极客https://www.cvmart.net/dataSets/detail/449?utm_campaign=zywang
该数据集包含 12,500 张带有细胞类型标签 (CSV) 的增强血细胞图像 (JPEG)。4 种不同细胞类型中的每一种都有大约 3,000 张图像,这些图像被分组到 4 个不同的文件夹中(根据细胞类型)。细胞类型是嗜酸性粒细胞、淋巴细胞、单核细胞和中性粒细胞。该数据集附带一个额外的数据集,其中包含原始 410 幅图像(预增强)以及两个额外的子类型标签(WBC 与 WBC),以及这 410 幅图像中每个单元格的边界框(JPEG + XML 元数据)。更具体地说,“dadataset-master”文件夹包含 410 张带有子类型标签和边界框(JPEG + XML)的血细胞图像,而“dataset2-master”文件夹包含 2,500 个增强图像以及 4 个额外的子类型标签(JPEG + CSV)。
其中dadataset-master文件夹是我们需要的yolov8任务的数据集
2.数据集处理
我的原数据集为两个文件,其中Annotations为xml文件为label文件,JEPGImages为图片文件
由于训练yolov8模型时xml格式文件并不支持训练,所以要先将xml数据集改为yolo格式的数据集,用一个xml转yolo脚本即可
import os
import xml.etree.ElementTree as ET
def convert_voc_to_yolo(xml_path, classes, output_folder):
tree = ET.parse(xml_path)
root = tree.getroot()
image_filename = root.find('filename').text
image_width = float(root.find('size/width').text)
image_height = float(root.find('size/height').text)
yolo_lines = []
for obj in root.findall('object'):
class_name = obj.find('name').text
class_index = classes.index(class_name)
bbox = obj.find('bndbox')
xmin = float(bbox.find('xmin').text)
ymin = float(bbox.find('ymin').text)
xmax = float(bbox.find('xmax').text)
ymax = float(bbox.find('ymax').text)
# 计算中心坐标和宽度/高度的相对值
x_center = (xmin + xmax) / (2.0 * image_width)
y_center = (ymin + ymax) / (2.0 * image_height)
width = (xmax - xmin) / image_width
height = (ymax - ymin) / image_height
# 将信息格式化为 YOLO 格式的一行文本
yolo_line = f"{class_index} {x_center} {y_center} {width} {height}"
yolo_lines.append(yolo_line)
# 将 YOLO 格式的信息写入文本文件
yolo_file_path = os.path.join(output_folder, os.path.splitext(image_filename)[0] + '.txt')
with open(yolo_file_path, 'w') as yolo_file:
for line in yolo_lines:
yolo_file.write(line + '\n')
def convert_folder_to_yolo(xml_folder, classes, output_folder):
os.makedirs(output_folder, exist_ok=True)
for xml_file in os.listdir(xml_folder):
if xml_file.endswith('.xml'):
xml_path = os.path.join(xml_folder, xml_file)
convert_voc_to_yolo(xml_path, classes, output_folder)
# Example usage:
xml_folder_path = 'D:/Allpythonproject/cv-haut/Blood/archive (1)/dataset-master/dataset-master/Annotations'
output_folder_path = 'D:/Allpythonproject/cv-haut/Blood/archive (1)/dataset-master/dataset-master/output'
class_names = ["RBC"]
convert_folder_to_yolo(xml_folder_path, class_names, output_folder_path)
其中xml_folder_path为你xml格式数据集的地址,out_folder_path为你输出yolo格式存入的地址,class_names为你的类别数,在我的数据集中只标注了一个叫RBC的标注。你可以根据你的类别数进行修改
在进行划分后我们要对训练集进行划分,其中图片和标签要一一对应
import os
import random
import shutil
def split_and_clean_dataset(images_folder, labels_folder, output_folder, split_ratio=0.8):
os.makedirs(output_folder, exist_ok=True)
# 创建主文件夹
output_images_folder = os.path.join(output_folder, 'images')
output_labels_folder = os.path.join(output_folder, 'labels')
os.makedirs(output_images_folder, exist_ok=True)
os.makedirs(output_labels_folder, exist_ok=True)
# 获取所有图像文件名
image_files = [f for f in os.listdir(images_folder) if f.endswith('.jpg')]
random.shuffle(image_files)
# 划分训练集和验证集
split_index = int(split_ratio * len(image_files))
train_files = image_files[:split_index]
val_files = image_files[split_index:]
# 创建训练集和验证集的子文件夹
train_images_folder = os.path.join(output_images_folder, 'train')
val_images_folder = os.path.join(output_images_folder, 'val')
train_labels_folder = os.path.join(output_labels_folder, 'train')
val_labels_folder = os.path.join(output_labels_folder, 'val')
os.makedirs(train_images_folder, exist_ok=True)
os.makedirs(val_images_folder, exist_ok=True)
os.makedirs(train_labels_folder, exist_ok=True)
os.makedirs(val_labels_folder, exist_ok=True)
# 复制图像和标签到相应的文件夹,并检查匹配性
for file_name in train_files:
image_path = os.path.join(images_folder, file_name)
label_name = file_name.replace('.jpg', '.txt')
label_path = os.path.join(labels_folder, label_name)
if os.path.exists(label_path):
shutil.copy(image_path, train_images_folder)
shutil.copy(label_path, train_labels_folder)
else:
print(f"Warning: Label not found for {file_name}. Skipping.")
for file_name in val_files:
image_path = os.path.join(images_folder, file_name)
label_name = file_name.replace('.jpg', '.txt')
label_path = os.path.join(labels_folder, label_name)
if os.path.exists(label_path):
shutil.copy(image_path, val_images_folder)
shutil.copy(label_path, val_labels_folder)
else:
print(f"Warning: Label not found for {file_name}. Skipping.")
# 用法示例:
images_folder_path = 'JPEGImages/'
labels_folder_path = 'output/'
output_folder_path = 'Formost'
split_and_clean_dataset(images_folder_path, labels_folder_path, output_folder_path)
其中images_folder_path为你存放图像的路径,labels_folder_path为你上一步保存yolo格式的路径,output_folder_path为你最终要存放最终数据集的文件夹,在运行之前我已经创建好了一个名叫Formost的文件夹。
最终训练集结构如下
——————-Formost
————images
——train
——val
————labels
——train
——val
其中Formost为主文件夹,主文件夹下有两个次文件夹images和labels,这两个文件夹下又有两个文件夹train和val分别存放训练集和验证集
四.训练模型
1.创建yaml文件
yolov8命令行中“data”参数可以指定yaml文件,故需创建一个包含类别数和数据集路径的yaml文件
train: "D:/Allpythonproject/cv-haut/Blood/archive (1)/dataset-master/dataset-master/Formost/images/train"
val: "D:/Allpythonproject/cv-haut/Blood/archive (1)/dataset-master/dataset-master/Formost/images/val"
nc: 1
names:
0: EOSINOPHIL
其中train和val要换成你第二步数据集处理后图片的训练集和验证集的绝对路径。nc为你的类别数跟你原本xml文件中的类别数保持一致,像我的类别数就只有一类即可填1。names你可以为你要检测的类别物命名,在此我的类别数为EOSINOPHIL,则在预测时预测的名字就叫做EOSINOPHIL
我的yaml文件存放在了与数据集同等的目录下,v8.yaml为我创建的yaml文件
2.使用命令行训练模型
打开pycharm中的terminal或者cmd都可以,使用cd命令切换到你存放yaml文件的地方输入
yolo task=detect mode=train model=yolov8n.pt data=v8.yaml batch=16 epochs=20 imgsz=640 workers=16 device=0
其中data参数为你创建的yaml文件,model为你的预训练模型,有5种预训练模型可供你选择,若想深入了解可以看这篇博客https://blog.csdn.net/qq_37553692/article/details/130898732
五.训练完毕
训练完之后,yolov8会在你主目录下创建一个叫做runs的文件夹,runs文件夹会有以下文件
weights文件夹里为你训练的模型参数,至此,训练完毕