1.准备数据集

(1)下载数据集

这里以CUB-200-2011数据集为例。CUB-200-2011(Caltech-UCSD Birds 200-2011)是一个包含200种鸟类的数据集,每种鸟类大约有60张图片,总共有11788张图片。数据集中包含了图片和标注信息(包括边界框)。下载链接:CUB-200-2011

(2)解压 

(3)转换成yolov8所需格式

        生成标签文件(labels):打开你克隆下来的ultralytics项目,在项目中新建一个python文件convert_to_yolov8_format.py,粘贴下面的python代码。并打开终端输入以下bash命令运行它。

python convert_to_yolov8_format.py
#1.处理标签文件
import os
import pandas as pd
from PIL import Image

# 数据集路径
dataset_dir = '/path/to/CUB_200_201'  #这里切换为自己的路径,解压后的数据集位置
images_dir = os.path.join(dataset_dir, 'images')
annotations_dir = dataset_dir

# 加载数据
bounding_boxes = pd.read_csv(os.path.join(annotations_dir, 'bounding_boxes.txt'), sep='\s+', header=None, names=['image_id', 'x', 'y', 'width', 'height'])
class_labels = pd.read_csv(os.path.join(annotations_dir, 'image_class_labels.txt'), sep='\s+', header=None, names=['image_id', 'class_id'])
image_paths = pd.read_csv(os.path.join(annotations_dir, 'images.txt'), sep='\s+', header=None, names=['image_id', 'image_path'])

# 合并数据帧
data = pd.merge(bounding_boxes, class_labels, on='image_id')
data = pd.merge(data, image_paths, on='image_id')

# 创建YOLO格式的标注文件
for _, row in data.iterrows():
    image_path = os.path.join(images_dir, row['image_path'])
    image = Image.open(image_path)
    dw = 1. / image.width
    dh = 1. / image.height

    # 计算归一化坐标
    x = (row['x'] + row['width'] / 2.0) * dw
    y = (row['y'] + row['height'] / 2.0) * dh
    w = row['width'] * dw
    h = row['height'] * dh

    # 类别ID调整为从0开始(如果需要)
    class_id = row['class_id'] - 1

    # 生成标注文件
    txt_path = image_path.replace('.jpg', '.txt').replace('images', 'labels')
    os.makedirs(os.path.dirname(txt_path), exist_ok=True)
    with open(txt_path, 'w') as f:
        f.write(f"{class_id} {x} {y} {w} {h}\n")

print("YOLO标注文件生成完成!")

(4)分割训练和验证数据集

        首先在CUB_200_201种的images和labels两个文件夹中都分别新建上train和val两个文件夹。        

        注释掉convert_to_yolov8_format.py文件中的1.处理标签文件和2.创建和填写 YAML 文件代码。然后复制粘贴以下代码。

        请确保更新脚本中的路径以反映你的实际文件结构。运行这个脚本前,建议备份你的数据。这个脚本会根据你提供的比例自动将图片和标签文件分配到训练集和验证集的对应文件夹中。

#3.分割训练和验证数据集
import os
import numpy as np
import shutil

def split_data(images_base, labels_base, train_img_folder, val_img_folder, train_lbl_folder, val_lbl_folder, split_size=0.2):
    """递归分割数据为训练集和验证集,适用于嵌套文件夹结构,同时处理图片和标签"""
    # 确保目标文件夹存在
    os.makedirs(train_img_folder, exist_ok=True)
    os.makedirs(val_img_folder, exist_ok=True)
    os.makedirs(train_lbl_folder, exist_ok=True)
    os.makedirs(val_lbl_folder, exist_ok=True)

    # 遍历基础文件夹中的每个子文件夹(每种鸟类)
    species_folders = [f for f in os.listdir(images_base) if os.path.isdir(os.path.join(images_base, f))]

    for species in species_folders:
        species_img_path = os.path.join(images_base, species)
        species_lbl_path = os.path.join(labels_base, species)
        img_files = [f for f in os.listdir(species_img_path) if os.path.isfile(os.path.join(species_img_path, f))]
        lbl_files = [f for f in os.listdir(species_lbl_path) if os.path.isfile(os.path.join(species_lbl_path, f))]

        # 确保图片和标签数量相匹配
        assert len(img_files) == len(lbl_files), f"Mismatch in number of images and labels for {species}"

        np.random.shuffle(img_files)  # 随机打乱顺序

        # 分割训练集和验证集
        split_point = int(len(img_files) * (1 - split_size))
        train_files = img_files[:split_point]
        val_files = img_files[split_point:]

        # 创建每个种类的目标文件夹
        os.makedirs(os.path.join(train_img_folder, species), exist_ok=True)
        os.makedirs(os.path.join(val_img_folder, species), exist_ok=True)
        os.makedirs(os.path.join(train_lbl_folder, species), exist_ok=True)
        os.makedirs(os.path.join(val_lbl_folder, species), exist_ok=True)

        # 移动图片和标签文件
        for file in train_files:
            shutil.move(os.path.join(species_img_path, file), os.path.join(train_img_folder, species, file))
            lbl_file = file.replace('.jpg', '.txt')
            shutil.move(os.path.join(species_lbl_path, lbl_file), os.path.join(train_lbl_folder, species, lbl_file))

        for file in val_files:
            shutil.move(os.path.join(species_img_path, file), os.path.join(val_img_folder, species, file))
            lbl_file = file.replace('.jpg', '.txt')
            shutil.move(os.path.join(species_lbl_path, lbl_file), os.path.join(val_lbl_folder, species, lbl_file))

# 指定源文件夹和目标文件夹路径
images_base = 'path/to/CUB_200_2011/images'  # 图片的基础文件夹
labels_base = 'path/to/CUB_200_2011/labels'  # 标签的基础文件夹
train_img_folder = 'path/to/CUB_200_2011/images/train'  # 训练集图片目标文件夹
val_img_folder = 'path/to/CUB_200_2011/images/val'  # 验证集图片目标文件夹
train_lbl_folder = 'path/to/CUB_200_2011/labels/train'  # 训练集标签目标文件夹
val_lbl_folder = 'path/to/CUB_200_2011/labels/val'  # 验证集标签目标文件夹

# 调用函数进行分割
split_data(images_base, labels_base, train_img_folder, val_img_folder, train_lbl_folder, val_lbl_folder)

print("已分割")

分割好后删去images和labels两个文件夹中的空文件夹,都只保留train和val两个文件夹。然后将数据集放到项目的ultralytics\ultralytics\cfg\datasets路径下。

        创建 YAML 配置文件,在ultralytics\ultralytics\cfg\datasets此目录下新建一个文件cub200.yaml。然后粘贴以下代码。

# 文件名: cub200.yaml

train: /path/to/CUB_200_2011/images/train  # 更改为实际的训练集图片路径
val: /path/to/CUB_200_2011/images/val    # 更改为实际的验证集图片路径

nc: 200  # CUB-200-2011 数据集包含 200 个鸟类
names: [ '类别1', '类别2', ... '类别200']  # 这里需要填写所有200个鸟类的名称

        然后在你的python文件convert_to_yolov8_format.py文件中注释掉刚刚的处理标签文件的代码,粘贴以下代码。

#2.创建和填写 YAML 文件
import os

# 设置数据集的目录路径
dataset_dir = 'ultralytics/ultralytics/cfg/datasets/CUB_200_2011'  #改为自己的数据集路径

# 设置类别文件的路径
classes_path = os.path.join(dataset_dir, 'classes.txt')

# 读取类别名称
names = []
with open(classes_path, 'r') as file:
    names = [line.strip().split()[-1] for line in file.readlines()]

# 生成用于YAML文件的类别名称部分
names_section = "[" + ", ".join(f"'{name}'" for name in names) + "]"
print(names_section)

运行后会生成200个鸟类的名称,复制下来粘贴到cub200.yaml文件中的names: [ '类别1', '类别2', ... '类别200'] 。

 2.修改yolov8.yaml文件

打开ultralytics/ultralytics/cfg/models/v8/yolov8.yaml文件,修改nc为200,因为有200种鸟类。

3.在项目根目录下新建训练和验证python文件

#train.py

from ultralytics import YOLO

# Load a model
model = YOLO("ultralytics/ultralytics/cfg/models/v8/yolov8.yaml")  # build a new model from scratch
#model = YOLO("yolov8n.pt")  # load a pretrained model 不使用预训练权重,就注释这一行即可
# train
model.train(data='ultralytics/ultralytics/cfg/datasets/cub200.yaml',
                cache=False,
                imgsz=640,
                epochs=10, #训练的轮次,先设小一些试一下。回头再根据需求更改
                batch=16,
                close_mosaic=0,
                workers=4,
                #device='0',
                optimizer='SGD', # using SGD
                amp=False, # close amp
                project='runs/train',
                name='exp',
                )
#val.py

from ultralytics import YOLO

if __name__ == '__main__':
    model = YOLO('ultralytics/runs/train/exp/weights/best.pt') # 自己训练结束后的模型权重
    model.val(data='ultralytics/ultralytics/cfg/datasets/cub200.yaml',
              split='val',
              imgsz=640,
              batch=16,
              save_json=False, # if you need to cal coco metrice
              project='runs/val',
              name='exp',
              )

4.AutoDL云服务器租用

租用新实例

选上你想要的环境。

选上想租的主机。 

 创建开机后连接pycharm,可参考AutoDL帮助文档。

连接上后,点击浏览远程主机即可看到远程主机的情况。

 找到在远程主机中自己项目的位置。

接着点开终端选择远程主机的终端。 

在训练和验证之前,记得先修改train.py和val.py中涉及到的路径,改为远程主机的绝对路径。 

接下来开始训练

 训练完成后,结果将会被保存在runs文件夹里。

然后开始验证:

 验证完成后,结果将会被保存在runs文件夹里。

 

更多推荐