随便搞个python环境,直接装或者anaconda都行,python版本最低3.8以上

一、安装yolov8  (cpu版本)

pip install ultralytics  

yolov8安装版本比较省事,不过这里默认装的是CPU版本

import torch
print(torch.__version__)

2.3.1是torch版本  cpu是PyTorch 是专为 CPU 运行而设计的,无法使用GPU加速

我这里是云主机没显卡所以直接用就行,但cpu的效率比较低,如果你用的是台式机参考下面的方法切换成GPU版本

二、GPU模式切换(无显卡忽略)

#卸载cpu版本的库
pip uninstall torch
pip uninstall torchvision

cuda参考文档

https://zhuanlan.zhihu.com/p/672526561

1、查看显卡驱动版本 

nvidia-smi

 2、对比CUDA和驱动的对应版本

https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html

 可以看到显卡驱动版本符合CUDA 12.3之前的所有版本

 3、对比pytorch和CUDA的对应版本

https://pytorch.org/get-started/previous-versions/

 

*START LOCALLY*可以看到目前最新的pytorch稳定版本是2.1.2,并且可以选择计算平台:CUDA表示使用GPU,CPU则是使用CPU计算

对应的CUDA有11.8和12.1两个选择,结合之前对比的

和CUDA版本关系,这里选择CUDA12.1,表中给出了安装torch相关框架的命令

 

 最近遇到一个坑,onnxruntime-gpu最多支持到11.x的CUDA,12.x还没有官方support,所以感觉最好还是先用11.x

4、安装错了卸载

pip3 uninstall torch torchvision torchaudio

5、安装CUDA

https://developer.nvidia.com/cuda-downloads

CUDA Toolkit 11.8 Downloads | NVIDIA Developer

 

下完就是exe程序直接安装就行

6、安装GPU的库

pip install torch torchvision torchaudio -i https://download.pytorch.org/whl/cu118

7、检查nvcc版本

nvcc -V

8、检查库GPU版本

print('torch 版本为:', torch.__version__)
print('GPU 可用:', torch.cuda.is_available())
print('GPU 数量:', torch.cuda.device_count())
print('对应 cuDNN 版本:', torch.backends.cudnn.version())
print('对应 CUDA 版本号:', torch.version.cuda)

# 在查看torchvision和torch版本是否匹配
import torchvision
print('torchvision 版本为:', torchvision.__version__)

 

三、基本使用

新建项目

1、下载官方模型

模型就是官方拿了好多张图片,每个图片给物体画了个框框,然后打上标记说这个东西就是叫“车”,然后我们拿着做好的模型是怼着新的图片去匹配,把比较相似的框选出来

https://github.com/ultralytics/assets/releases/download/v8.2.0/yolov8n.pt

2、模型预测

我们随便在网上找一些常见的人物、汽车等图片

 

#进入项目目录
cd C:\Users\Administrator\PycharmProjects\yolo8test

#识别
yolo predict model=./yolov8n.pt source=./111.jpg

 返回

(.venv) PS C:\Users\Administrator\PycharmProjects\yolo8test> yolo predict model=./yolov8n.pt source=./111.jpg
Ultralytics YOLOv8.2.86 🚀 Python-3.9.13 torch-2.3.1+cpu CPU (Intel Xeon Gold 6133 2.50GHz)
YOLOv8n summary (fused): 168 layers, 3,151,904 parameters, 0 gradients, 8.7 GFLOPs

image 1/1 C:\Users\Administrator\PycharmProjects\yolo8test\111.jpg: 384x640 1 person, 15 cars, 1 suitcase, 147.3ms
Speed: 0.0ms preprocess, 147.3ms inference, 0.0ms postprocess per image at shape (1, 3, 384, 640)
Results saved to runs\detect\predict
💡 Learn more at https://docs.ultralytics.com/modes/predict
(.venv) PS C:\Users\Administrator\PycharmProjects\yolo8test> 

我们就能在 当前目录生成一个经过识别的图片目录runs,如下

3、分割模型

 yolo task = segment mode = predict model = ./yolov8x-seg.pt source = '1.jpg'

4、分类模型

yolo task = classify mode = predict model = ./yolov8x-cls.pt source = '1.jpg'

5、post检测模型

yolo task = pose mode = predict model = ./yolov8n-pose.pt source = '1.jpg'

6、python调用yolo

我们可以通过python直接去调用yolo去识别我们想要找的图片元素位置,可以返回坐标或相似度

from ultralytics import YOLO

# 加载预训练的YOLOv8n模型
model = YOLO('./yolov8n.pt')

# 在图片列表上运行批处理推理
results = model(['./111.jpg'], stream=True)  # 返回 Results 对象生成器

# 初始化一个空列表来存储推理结果
tuili_jieguo = []

# 遍历推理结果生成器
for result in results:
    if len(result.boxes.cls) > 0:  # 如果检测到了物体
        # 遍历每个检测到的物体
        for i in range(len(result.boxes.cls)):
            # 获取类别ID
            leibie_id = int(result.boxes.cls[i].item())
            # 获取类别的名称
            leibie = result.names[leibie_id]

            # 获取物体的相似度(置信度)
            xiangsidu = result.boxes.conf[i].item()

            # 获取物体的边界框坐标值,返回的是左上角和右下角坐标
            zuobiao = result.boxes.xyxy[i].tolist()

            # 存入列表中
            tuili_jieguo.append({
                '类别': leibie,
                '相似度': xiangsidu,
                '坐标': zuobiao
            })

# 打印结果
if len(tuili_jieguo) > 0:
    for info in tuili_jieguo:
        print(info)
else:
    print('没有找到任何元素')

 返回

{'类别': 'car', '相似度': 0.7799433469772339, '坐标': [0.22769272327423096, 317.2225341796875, 128.27581787109375, 434.3835754394531]}
{'类别': 'car', '相似度': 0.7526790499687195, '坐标': [697.0774536132812, 74.91606903076172, 744.7645263671875, 125.85704803466797]}
{'类别': 'car', '相似度': 0.7515988349914551, '坐标': [644.66357421875, 67.18761444091797, 727.217529296875, 110.74929809570312]}
{'类别': 'car', '相似度': 0.7397133708000183, '坐标': [0.0, 188.8974609375, 236.7770233154297, 361.6441650390625]}
{'类别': 'car', '相似度': 0.6943690180778503, '坐标': [131.71730041503906, 121.01139831542969, 283.1908874511719, 197.81919860839844]}
{'类别': 'car', '相似度': 0.6556140780448914, '坐标': [364.0426940917969, 206.4368896484375, 689.3762817382812, 381.542724609375]}
{'类别': 'car', '相似度': 0.6262668967247009, '坐标': [602.9423828125, 57.743648529052734, 681.0354614257812, 95.95284271240234]}
{'类别': 'car', '相似度': 0.6166586875915527, '坐标': [579.7506103515625, 48.26351547241211, 646.1148681640625, 85.86759185791016]}
{'类别': 'car', '相似度': 0.505893349647522, '坐标': [196.24853515625, 105.84526062011719, 317.51824951171875, 169.0955352783203]}
{'类别': 'car', '相似度': 0.47477126121520996, '坐标': [58.76011657714844, 149.4607696533203, 272.3125305175781, 258.5394287109375]}
{'类别': 'suitcase', '相似度': 0.3830447793006897, '坐标': [362.7950134277344, 205.08999633789062, 688.3359985351562, 381.7972106933594]}
{'类别': 'car', '相似度': 0.34968864917755127, '坐标': [205.19512939453125, 101.66968536376953, 317.385009765625, 154.1511688232422]}
{'类别': 'person', '相似度': 0.3185082674026489, '坐标': [444.6435852050781, 44.4957275390625, 457.28009033203125, 76.48484802246094]}
{'类别': 'car', '相似度': 0.29900309443473816, '坐标': [684.0139770507812, 38.089942932128906, 745.5180053710938, 70.73363494873047]}
{'类别': 'car', '相似度': 0.27480557560920715, '坐标': [210.26715087890625, 76.54121398925781, 324.5977783203125, 115.85347747802734]}
{'类别': 'car', '相似度': 0.264335036277771, '坐标': [702.9208374023438, 38.8995475769043, 749.3323364257812, 74.61824798583984]}
{'类别': 'car', '相似度': 0.2511461675167084, '坐标': [348.7983093261719, 159.1416778564453, 592.0986938476562, 250.2734832763672]}

这里返回的坐标是框框的左上角和右下角

7、视频流实时识别

mss库不断截屏来获取视频流,然后交给yolo,通过opencv标记

import mss  # 截屏
import cv2  # 图片识别
import numpy as np  # 将mss的截屏转换为opencv能识别的图片
from ultralytics import YOLO  # 识别画面

# 加载预训练的YOLOv8n模型
model = YOLO('C:\\image\\yolov8n.pt')

# 定义截图区域
#使用微信的截图功能能获取到pos的值 前面的值写top  后面的值写left
quyu = {"left": 326, "top": 613, "width": 697, "height": 340}

# 实例化截图mss库工具,重命名sct
with mss.mss() as sct:
    while True:  # 死循环
        # 死循环截图--识别--标记--显示

        # 1、获取指定区域的截图
        quyujieping = sct.grab(quyu)  # 截图
        quyujieping = np.array(quyujieping)  # 转换opencv识别的图片
        quyujieping2 = cv2.cvtColor(quyujieping, cv2.COLOR_BGR2RGB)  # 截图转换为RGB排序,才能给YOLO识别
        # 给yolo的要转换RGB
        # 给opencv的不用转换

        # 2、在图片列表上运行批量推理 (识别)类、相似度、坐标
        results = model(quyujieping2, stream=True)  # 返回 Results 对象生成器

        tuili_jieguo = []  # 推理结果

        # 处理结果生成器
        for result in results:
            if len(result.boxes.cls) > 0:
                for i in range(len(result.boxes.cls)):
                    # 获取类别ID
                    leibie_id = int(result.boxes.cls[i].item())
                    # 获取类别名称
                    leibie = result.names[leibie_id]

                    # 获取相似度
                    xiangsidu = str(round(result.boxes.conf[i].item(), 2))

                    # 获取坐标值,两个,左上角和右下角
                    zuobiao = result.boxes.xyxy[i].tolist()

                    # 存入列表中
                    tuili_jieguo.append({
                        '类别': leibie,
                        '相似度': xiangsidu,
                        '坐标': zuobiao
                    })

        # 3  绘制边界框  标记
        for info in tuili_jieguo:
            # 使用opencv将结果中的坐标画出来
            cv2.rectangle(
                quyujieping,
                (int(info['坐标'][0]), int(info['坐标'][1])),
                (int(info['坐标'][2]), int(info['坐标'][3])),
                (0, 255, 0),  # 绿色边界框
                2
            )
            # 标记类别
            cv2.putText(
                quyujieping,
                f"{info['类别']}",
                (int(info['坐标'][0]), int(info['坐标'][1]) + 15),
                cv2.FONT_HERSHEY_SIMPLEX,
                0.6,
                (255, 255, 255),  # 白色文字
                1,
                cv2.LINE_AA
            )

            # 标记相似度 *文本写入
            cv2.putText(
                quyujieping,
                f"{info['相似度']}",
                (int(info['坐标'][2]) + 8, int(info['坐标'][1]) + 15),
                cv2.FONT_HERSHEY_SIMPLEX,
                0.6,
                (255, 255, 255),  # 白色文字
                1,
                cv2.LINE_AA
            )

        # 4、显示窗口部分
        cv2.namedWindow("video", cv2.WINDOW_NORMAL)  # 创建窗口
        cv2.resizeWindow("video", quyu['width'] // 2, quyu['height'] // 2)  # 设置窗口大小
        cv2.imshow("video", quyujieping)  # 显示窗口

        # 退出部分
        if cv2.waitKey(5) & 0xFF == ord("q"):  # 按q键退出
            cv2.destroyAllWindows()
            break

 

有点自动驾驶识别那意思了~

8、实时识别加函数触发

import mss  # 截屏
import cv2  # 图片识别
import numpy as np  # 将mss的截屏转换为opencv能识别的图片
from ultralytics import YOLO  # 目标检测

# 加载预训练的YOLOv8n模型
model = YOLO('./yolov8n.pt')

# 定义截图区域
quyu = {"left": 326, "top": 613, "width": 697, "height": 340}

# 实例化截图mss库工具,重命名sct
with mss.mss() as sct:
    while True:  # 死循环
        # 1、获取指定区域的截图
        quyujieping = sct.grab(quyu)  # 截图
        quyujieping = np.array(quyujieping)  # 转换opencv识别的图片
        quyujieping2 = cv2.cvtColor(quyujieping, cv2.COLOR_BGR2RGB)  # 截图转换为RGB排序,才能给YOLO识别

        # 2、在图片列表上运行批量推理 (识别)类、相似度、坐标
        results = model(quyujieping2, stream=True)  # 返回 Results 对象生成器

        tuili_jieguo = []  # 推理结果

        # 处理结果生成器
        for result in results:
            if len(result.boxes.cls) > 0:
                for i in range(len(result.boxes.cls)):
                    # 获取类别ID
                    leibie_id = int(result.boxes.cls[i].item())
                    # 获取类别名称
                    leibie = result.names[leibie_id]

                    # 检测到"person"时触发动作
                    if leibie == "person":
                        print("Person detected! Triggering action...")

                    # 获取相似度
                    xiangsidu = str(round(result.boxes.conf[i].item(), 2))

                    # 获取坐标值,两个,左上角和右下角
                    zuobiao = result.boxes.xyxy[i].tolist()

                    # 存入列表中
                    tuili_jieguo.append({
                        '类别': leibie,
                        '相似度': xiangsidu,
                        '坐标': zuobiao
                    })

        # 3  绘制边界框  标记
        for info in tuili_jieguo:
            # 使用opencv将结果中的坐标画出来
            cv2.rectangle(
                quyujieping,
                (int(info['坐标'][0]), int(info['坐标'][1])),
                (int(info['坐标'][2]), int(info['坐标'][3])),
                (0, 255, 0),  # 绿色边界框
                2
            )
            # 标记类别
            cv2.putText(
                quyujieping,
                f"{info['类别']}",
                (int(info['坐标'][0]), int(info['坐标'][1]) + 15),
                cv2.FONT_HERSHEY_SIMPLEX,
                0.6,
                (255, 255, 255),  # 白色文字
                1,
                cv2.LINE_AA
            )
            # 标记相似度 *文本写入
            cv2.putText(
                quyujieping,
                f"{info['相似度']}",
                (int(info['坐标'][2]) + 8, int(info['坐标'][1]) + 15),
                cv2.FONT_HERSHEY_SIMPLEX,
                0.6,
                (255, 255, 255),  # 白色文字
                1,
                cv2.LINE_AA
            )

        # 4、显示窗口部分
        cv2.namedWindow("video", cv2.WINDOW_NORMAL)  # 创建窗口
        cv2.resizeWindow("video", quyu['width'] // 2, quyu['height'] // 2)  # 设置窗口大小
        cv2.imshow("video", quyujieping)  # 显示窗口

        # 退出部分
        if cv2.waitKey(5) & 0xFF == ord("q"):  # 按q键退出
            cv2.destroyAllWindows()
            break

打印中心点坐标(忽略 临时放一下)

import time
from ultralytics import YOLO

# 加载预训练的YOLO模型
model = YOLO('E:\\yolo\\ultralytics-main\\best.pt')

# 记录开始时间
start_time = time.time()

# 对指定目录下的图像进行对象检测
# conf=0.05 设置置信度阈值为 0.05
# save=False 表示不保存输出图像
# show_conf=False 表示在输出中不显示置信度信息
results = model("E:\\yolo\\ultralytics-main\\ultralytics\\assets", conf=0.05, save=False, show_conf=False)

# 计算并打印处理时间
processing_time = time.time() - start_time
print(f"Processing time: {processing_time:.2f} seconds")

# 遍历所有的检测结果
for result in results:
    # 获取类别名称
    class_names = result.names
    
    # 获取检测到的边界框信息
    boxes = result.boxes
    
    # 遍历每个边界框
    for box in boxes:
        # 获取边界框的坐标 (左上角和右下角坐标)
        coordinates = box.xyxy.numpy().tolist()[0]
        
        # 将坐标转换为整数类型
        int_coordinates = [int(coord) for coord in coordinates]
        
        # 计算边界框中心点的 X 和 Y 坐标
        center_x = (int_coordinates[0] + int_coordinates[2]) / 2
        center_y = (int_coordinates[1] + int_coordinates[3]) / 2
        
        # 获取该边界框所属的类别 ID
        class_id = int(box.cls.numpy().tolist()[0])
        
        # 打印类别名称及其对应的中心点坐标
        print(f"{class_names[class_id]}: {center_x:.2f}, {center_y:.2f}")

四、模型训练

1、数据集下载(coco128)

https://www.ultralytics.com/assets/coco128.zip  

在项目目录创建一个 datasets目录,把文件解压进去

2、编辑数据集标签文件

vi coco128.yaml

# COCO128 dataset.yaml file
# Example usage: yolo train model=yolov8n.yaml data=coco128.yaml epochs=30

# Train, Val, Test sets sizes below
train: ./coco128/images/train2017  # 应该指向训练集图像目录
val: ./coco128/images/train2017      # 应该指向验证集图像目录
#test: ./coco128/images/train2017   # 可选,应该指向测试集图像目录

# Classes
nc: 80  # number of classes
names: ['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
        'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
        'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee',
        'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
        'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
        'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'couch',
        'potted plant', 'bed', 'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
        'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear',
        'hair drier', 'toothbrush']
# Download script/URL (optional)
download: https://ultralytics.com/assets/coco128.zip

配置说明

主要说一下names,相当于是指定了一些元素,指定的是我们需要用模型去匹配那些类型的元素,比如人、轿车、狗狗之类的,这些标签是在训练模型时定义的,换句话说我们上面引用的模型在训练之初,就通过标记图片中元素,然后个给元素明明特定的标签名,在我们用模型去匹配图片的时候,他会先检测你要匹配那些类型的元素,如果我们不写他也不知道就什么都匹配不到

3、验证模型

yolo val model = ./yolov8n.pt data = ./coco128.yaml

说明

yolo val  #这部分指示程序进入“验证”模式,即对模型的性能进行评估。
model = ./yolov8n.pt  #指定了要使用的YOLO模型路径,这里是yolov8n.pt,这通常是一个预训练好的模型文件。
data = coco128.yaml   #指定了数据集配置文件的路径,coco128.yaml应该包含了关于数据集的信息,如类别的数量、训练和验证集的位置等

返回

(.venv) PS C:\Users\Administrator\PycharmProjects\yolo8test> yolo val model = ./yolov8n.pt data = ./coco128.yaml
Ultralytics YOLOv8.2.86 🚀 Python-3.9.13 torch-2.3.1+cpu CPU (Intel Xeon Gold 6133 2.50GHz)
YOLOv8n summary (fused): 168 layers, 3,151,904 parameters, 0 gradients, 8.7 GFLOPs
val: Scanning C:\Users\Administrator\PycharmProjects\yolo8test\datasets\coco128\labels\train2017... 126 images, 2 backgrounds, 0 corrupt: 100%|██████████| 128/128 [00:00<00:00, 99
val: New cache created: C:\Users\Administrator\PycharmProjects\yolo8test\datasets\coco128\labels\train2017.cache
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 8/8 [00:18<00:00,  2.34s/it]
                   all        128        929       0.64      0.537      0.605      0.446
                person         61        254      0.797      0.677      0.764      0.538
               bicycle          3          6      0.514      0.333      0.315      0.264
                   car         12         46      0.813      0.217      0.273      0.168
            motorcycle          4          5      0.687      0.887      0.898      0.685
              airplane          5          6       0.82      0.833      0.927      0.675
                   bus          5          7      0.491      0.714      0.728      0.671
                 train          3          3      0.534      0.667      0.706      0.604
                 truck          5         12          1      0.332      0.473      0.297
                  boat          2          6      0.226      0.167      0.316      0.134
         traffic light          4         14      0.734        0.2      0.202      0.139
             stop sign          2          2          1      0.992      0.995      0.701
                 bench          5          9      0.839      0.582       0.62      0.365
                  bird          2         16      0.921      0.728      0.864       0.51
                   cat          4          4      0.875          1      0.995      0.791
                   dog          9          9      0.603      0.889      0.785      0.585
                 horse          1          2      0.597          1      0.995      0.518
              elephant          4         17      0.849      0.765        0.9      0.679
                  bear          1          1      0.593          1      0.995      0.995
                 zebra          2          4      0.848          1      0.995      0.965
               giraffe          4          9       0.72          1      0.951      0.722
              backpack          4          6      0.589      0.333      0.376      0.232
              umbrella          4         18      0.804        0.5      0.643      0.414
               handbag          9         19      0.424     0.0526      0.165     0.0889
                   tie          6          7      0.804      0.714      0.674      0.476
              suitcase          2          4      0.635      0.883      0.745      0.534
               frisbee          5          5      0.675        0.8      0.759      0.688
                  skis          1          1      0.567          1      0.995      0.497
             snowboard          2          7      0.742      0.714      0.747        0.5
           sports ball          6          6      0.716      0.433      0.485      0.278
                  kite          2         10      0.817       0.45      0.569      0.184
          baseball bat          4          4      0.551       0.25      0.353      0.175
        baseball glove          4          7      0.624      0.429      0.429      0.293
            skateboard          3          5      0.846        0.6        0.6       0.41
         tennis racket          5          7      0.726      0.387      0.487       0.33
                bottle          6         18      0.448      0.389      0.376      0.208
            wine glass          5         16      0.743      0.362      0.584      0.333
                   cup         10         36       0.58      0.278      0.404       0.29
                  fork          6          6      0.527      0.167      0.246      0.184
                 knife          7         16      0.564        0.5       0.59       0.36
                 spoon          5         22      0.597      0.182      0.328       0.19
                  bowl          9         28      0.648      0.643      0.618      0.491
                banana          1          1          0          0      0.124     0.0379
              sandwich          2          2      0.249        0.5      0.308      0.308
                orange          1          4          1       0.31      0.995      0.623
              broccoli          4         11      0.374      0.182      0.249      0.203
                carrot          3         24      0.648      0.458      0.572      0.362
               hot dog          1          2      0.351      0.553      0.745      0.721
                 pizza          5          5      0.644          1      0.995      0.843
                 donut          2         14      0.657          1       0.94      0.864
                  cake          4          4      0.618          1      0.945      0.845
                 chair          9         35      0.506      0.514      0.442      0.239
                 couch          5          6      0.463        0.5      0.706      0.555
          potted plant          9         14       0.65      0.643      0.711      0.472
                   bed          3          3      0.698      0.667      0.789      0.625
          dining table         10         13      0.432      0.615      0.485      0.366
                toilet          2          2      0.615        0.5      0.695      0.676
                    tv          2          2      0.373       0.62      0.745      0.696
                laptop          2          3          1          0      0.451      0.361
                 mouse          2          2          1          0     0.0625    0.00625
                remote          5          8      0.843        0.5      0.605      0.529
            cell phone          5          8          0          0     0.0549     0.0393
             microwave          3          3      0.435      0.667      0.806      0.718
                  oven          5          5      0.412        0.4      0.339       0.27
                  sink          4          6       0.35      0.167      0.182      0.129
          refrigerator          5          5      0.589        0.4      0.604      0.452
                  book          6         29      0.629      0.103      0.346      0.178
                 clock          8          9      0.788       0.83      0.875       0.74
                  vase          2          2      0.376          1      0.828      0.795
              scissors          1          1          1          0      0.249     0.0746
            teddy bear          6         21      0.877      0.333      0.591      0.394
            toothbrush          2          5      0.743        0.6      0.638      0.374
Speed: 1.1ms preprocess, 128.4ms inference, 0.0ms loss, 4.1ms postprocess per image
Results saved to runs\detect\val4
💡 Learn more at https://docs.ultralytics.com/modes/val

可以看到,数据集中的图片基本匹配的没有问题,验证就是拿一堆图片去让模型去识别看看有什么问题没,这里主要是模型和val: ./coco128/images/train2017 中图片去匹配

4 、训练模型

yolo train model = ./yolov8n.pt data = coco128.yaml epochs = 10 imgsz = 640

YOLO的训练脚本会默认寻找与图像文件夹同级的labels文件夹来获取标注信息,所以我们在训练的时候只要通过coco128.yaml 指定好train和val的路径即可

./coco128/
├── images/
│   ├── train2017/
└── labels/
    ├── train2017/   #标注文件在这里


---
train: ./coco128/images/train2017
val: ./coco128/images/train2017

训练模型说明
    best.pt  #这个文件保存的是在训练过程中验证集上表现最好的模型权重。通常是在每个epoch结束时,根据验证集上的性能指标(如mAP - mean Average Precision)来判断哪个模型最好,并将这个模型的状态保存下来。因此,best.pt代表了你的模型在训练过程中的最佳状态。

    last.pt  #这个文件保存的是训练结束时模型的最后状态,也就是最后一个epoch完成后的权重。无论这个模型是否是表现最好的,它都会被保存下来,以便你可以查看训练结束时模型的状态,或者从这里继续训练。



如果你想要部署模型用于实际应用中,通常会选择best.pt,因为它代表了模型在验证数据上的最优表现。而last.pt则可用于分析模型收敛的情况,或者在训练被意外中断后恢复训练。

此外,如果你需要进一步调整模型或进行微调(fine-tuning),你可以加载last.pt或best.pt作为预训练模型来继续训练。

新模板训练
yolo train model = ./best.pt data = coco128.yaml epochs = 10 imgsz = 640
新模板验证
yolo val model = ./models/yolov8n.pt data = coco128.yaml
训练模型流程
也就是说,如果我想要让训练更贴合我想要的结果,那么我就需要尽可能多的将每次训练得到的新的best.pt作为模板模型做下一次训练

#是的,如果你想让训练更贴合你所期望的结果,可以采用迭代的方式逐步改进模型。具体来说,你可以按照以下步骤操作:

1. **初次训练**:
   # 使用预训练模型(如`yolov8n.pt`)作为起点,基于你的数据集(如`coco128.yaml`)进行初步训练。
   #评估训练结果,记录下`best.pt`模型的表现。

2. **评估与选择**:
   #对`best.pt`模型在验证集上的性能进行评估。如果模型的表现已经达到你的预期,可以停止训练。
   -#如果模型表现未达预期,则可以考虑使用这个模型作为新的起点,进行下一步的训练。

3. **继续训练**:
   #将上次训练得到的`best.pt`作为新的模型起点,进行新一轮的训练。你可以适当调整训练参数,如增加`epochs`数量、调整学习率等。
   #新一轮训练结束后,再次评估性能,并决定是否继续训练或停止。

4. **迭代改进**:
   #重复上述过程,每次使用最新的`best.pt`模型作为起点,持续改进模型性能,直到达到满意的水平。

这种方法的优点是可以逐步提升模型性能,并针对特定问题进行优化。但需要注意以下几点:

- **过拟合风险**:每次训练时,都要注意监测验证集上的性能,避免模型过拟合。如果发现模型在验证集上的性能开始下降,可能需要采取措施,如早停法、数据增强等。

- **资源消耗**:每轮训练都需要消耗时间和计算资源。因此,要合理安排训练轮数和每次训练的`epochs`数量,以平衡性能提升和资源消耗。

- **备份模型**:每次训练结束后,都应该备份重要的模型文件(如`best.pt`),以免丢失重要的训练成果。

- **调整超参数**:除了增加训练轮数外,还可以通过调整其他超参数来改进模型,如学习率、批量大小、正则化强度等。

通过这样的迭代训练方式,你可以逐步优化模型,使其更加符合你的需求。

五、图片标注工具

通过上面的过程,我们了解到训练一个模型是需要图片,以及图片标注信息的,

我们上面使用的模型都是官方的通用模型,但是如果碰到一些他没见过的,识别的效率会非常低,我们需要给他一些新元素的概念,比如一些游戏中的某些物体,我们可以拿来做训练

 1、数据采集

首先,你需要收集足够的图像数据。对于游戏录屏而言,可以按如下步骤操作:

录制视频  #使用录屏软件录制游戏过程,确保覆盖各种典型的游戏场景。
视频转图片 #使用Python脚本(如前面提到的OpenCV示例)将录制的视频转换成图片帧。你可以选择每隔一定帧数提取一帧图片,以减少数据量。

 2、安装标注工具

数据标注是创建目标检测数据集的关键步骤之一。你需要标记出图片中的感兴趣区域(ROI),并为其分配类别标签。以下是常用的标注方法:

手动标注  #使用标注工具(如LabelImg、VGG Image Annotator (VIA)、Roboflow等)手动标注每一幅图片中的对象
#标注时,你需要绘制边界框(Bounding Boxes)并指定类别标签。

 参考文档

https://blog.csdn.net/u012930316/article/details/141291217?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522AECAC835-BAA7-4D85-BA7D-51135F2FF8A6%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=AECAC835-BAA7-4D85-BA7D-51135F2FF8A6&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~times_rank-2-141291217-null-null.142^v100^pc_search_result_base1&utm_term=LabelImg%E4%B8%AD%E6%96%87%E7%89%88&spm=1018.2226.3001.4187
#pip install labelimg

#执行命令
labelimg

#窗口汉化文档(没做)
https://blog.csdn.net/shaonian6/article/details/127771853

#先安装
pip install pyqt5


#克隆
 git clone https://mirror.ghproxy.com/https://github.com/HumanSignal/labelImg.git


#发现代码中报错
from libs.resources import *
ModuleNotFoundError: No module named 'libs.resources'

#libs目录同级旁边有个文件
resources.qrc

#拷贝到libs目录中
pyrcc5 -o libs/resources.py resources.qrc

#执行  (有个PyQt4显示红色的不管)
lablimg.py

3、打包

#我用这个好使
pip install pyinstaller
pyinstaller --hidden-import=pyqt5 --hidden-import=lxml -F -n "labelImg" -c labelImg.py -p ./libs -p ./


#如果失败用
pip install pyinstaller
pyinstaller --add-data 'data;data' --hidden-import=pyqt5 --hidden-import=lxml -F -n "labelImg" -w labelImg.py -p ./libs -p ./

4、打开图片然后手动标注

这串 数字就是标注信息,把txt文件放labels下面的训练目录下,图片放images的训练目录下就行(图片里面尽可能多标记出来)

5、自建数据集

随便项目名/
├── images/
│   ├── train2017/
│   └── val2017/
└── labels/
    ├── train2017/
    └── val2017/

照抄coco128那个就行

6、添加数据集文件

train: ./随便项目名/images/train2017  
val: ./随便项目名/images/val2017  # 


# Classes
names:
  0: 'che'

6、关于2次训练的想法

我突然有个疑问,假设我现在要训练能够识别一朵花,当训练完成我觉得没问题了,我希望再这个模型的基础上再去训练狗的图片,我应该怎么做

如果你已经训练了一个能够识别花朵的模型,并且现在希望在这个模型的基础上继续训练识别狗的图片,你可以通过以下步骤来实现这一目标:

### 1. 备份现有模型
在开始新的训练之前,确保备份现有的最佳模型(`best.pt`),以防新训练过程中出现问题。

### 2. 更新数据集
- **收集狗的图片**:收集包含狗的图片,并确保这些图片涵盖了狗的不同品种、姿势、环境等因素。
- **标注数据**:使用标注工具(如LabelImg、Roboflow等)标注狗的图片。确保每个狗都有相应的边界框和标签。
- **组织数据集**:将新的狗的图片及其标签文件放入数据集中,与现有的花朵图片一起组织。确保数据集分为训练集、验证集和测试集。

### 3. 更新配置文件
- **增加新的类别**:在你的数据集配置文件(如`my_dataset.yaml`)中增加新的类别。例如,如果原来的文件中只有花朵类别,现在需要增加狗的类别:
  ```yaml
  names:
    0: 'flower'  # 原有的花朵类别
    1: 'dog'     # 新增的狗类别
  ```

### 4. 微调(Fine-Tuning)
- **使用现有模型作为基模**:使用之前训练好的模型作为新的训练起点。这意味着你将使用`best.pt`作为预训练模型。
- **调整训练参数**:由于你已经有了一个初步训练好的模型,你可能需要调整一些训练参数,例如:
  - **学习率**:可以尝试降低学习率,因为微调阶段不需要大幅度更新权重。
  - **Epochs**:根据新增数据的数量和复杂度,调整训练的轮数。
  - **Batch Size**:根据GPU内存限制和数据量调整批处理大小。

### 5. 执行训练
使用更新后的数据集和配置文件,重新训练模型。命令如下:

```sh
yolo train model=./models/best.pt data=./my_dataset.yaml epochs=50 imgsz=640
```

这里的`./models/best.pt`是指你之前训练得到的最佳模型。

### 6. 评估模型
训练完成后,评估新模型在验证集上的性能。确保模型不仅能够识别原有的花朵,也能正确识别新增的狗。

### 7. 测试和优化
- **测试模型**:在独立的测试集上测试模型,确保其泛化能力。
- **优化模型**:根据测试结果,如果需要进一步优化,可以继续调整训练参数或增加更多的数据进行训练。

### 8. 部署模型
一旦模型的性能达到预期,你可以将其部署到实际应用中。

### 注意事项
- **类别不平衡**:如果新添加的狗的图片数量远少于花朵图片,可能会导致类别不平衡的问题。你可以通过数据增强或过采样(oversampling)来解决这个问题。
- **过拟合风险**:在微调阶段,要特别注意不要过度拟合新添加的数据。可以通过早停法(early stopping)、正则化技术等方式来避免过拟合。

通过上述步骤,你可以在已有模型的基础上,逐步扩展其识别能力,使之能够识别更多种类的对象。

也就是说,我只需要新建一个关于狗的数据集然后基于 花的模型进行二次训练即可吧,不需要在保存花的数据集

你有两种方法来实现基于已有模型(例如识别花朵的模型)进行扩展以识别狗。这两种方法各有优劣,取决于你的具体需求和资源:

### 方法一:合并数据集
1. **保留原有数据集**:
   - **保存花的数据集**:保留原有的花朵数据集。
   - **创建狗的数据集**:创建一个新的数据集,包含狗的图片及其标注信息。
   - **合并数据集**:将花的数据集和狗的数据集合并成一个新的数据集。这样做的好处是你可以利用已有的花朵数据来帮助模型更好地泛化。

2. **更新配置文件**:
   - 修改`names`部分,增加新的类别。例如:
     ```yaml
     names:
       0: 'flower'
       1: 'dog'
     ```

3. **组织目录结构**:
   - 确保合并后的数据集按照标准的目录结构组织,如:
     ```
     combined_dataset/
     ├── images/
     │   ├── train2017/
     │   └── val2017/
     └── labels/
         ├── train2017/
         └── val2017/
     ```

4. **进行训练**:
   - 使用合并后的数据集进行训练。命令如下:
     ```sh
     yolo train model=./models/best_flowers.pt data=./combined_dataset.yaml epochs=50 imgsz=640
     ```

### 方法二:仅使用新数据集
1. **创建狗的数据集**:
   - 创建一个新的数据集,仅包含狗的图片及其标注信息。

2. **使用原有模型进行微调**:
   - 使用原有的模型作为预训练模型,仅使用狗的数据集进行微调。这样做的好处是你可以专注于狗的识别,但可能会失去一些对花朵识别的泛化能力。

3. **更新配置文件**:
   - 修改`names`部分,增加新的类别。例如:
     ```yaml
     names:
       0: 'dog'
     ```

4. **组织目录结构**:
   - 确保狗的数据集按照标准的目录结构组织,如:
     ```
     dog_dataset/
     ├── images/
     │   ├── train2017/
     │   └── val2017/
     └── labels/
         ├── train2017/
         └── val2017/
     ```

5. **进行训练**:
   - 使用狗的数据集进行训练。命令如下:
     ```sh
     yolo train model=./models/best_flowers.pt data=./dog_dataset.yaml epochs=50 imgsz=640
     ```

### 选择哪种方法的考量
- **合并数据集**:
  - **优点**:可以充分利用原有的花朵数据,使模型具有更强的泛化能力。
  - **缺点**:数据量可能更大,需要更多的计算资源。

- **仅使用新数据集**:
  - **优点**:数据集更小,训练速度更快。
  - **缺点**:可能会影响模型对原有类别的识别效果,特别是如果新数据集和原数据集之间的差异较大。

### 结论
如果你希望模型既能识别花朵又能识别狗,并且希望保持模型对花朵的识别能力,建议采用**方法一**,即合并数据集。这样可以充分利用已有数据,提高模型的泛化能力。

如果你只需要模型识别狗,并且不介意可能对花朵识别能力的影响,可以选择**方法二**,即仅使用狗的数据集进行微调。这样做相对简单,但需要权衡模型的整体性能。

7、其他思路

我想要录制一个3d游戏的训练模型,能够识别图中出现的元素,然后根据元素去判断应该做什么操作,我能用视频转图片的方法提供模型的图片素材吗

当然可以!将3D游戏的视频转换为图片帧,并使用这些图片帧来训练模型,是一个有效的方法来获取用于训练的数据。这种方法特别适用于需要识别游戏内元素并据此做出决策的任务。以下是一些具体的步骤和技术建议:
1. 录制游戏视频

    选择录屏软件:选择一款适合录制3D游戏的录屏软件。推荐使用OBS Studio、XSplit、NVIDIA GeForce Experience等软件,它们可以提供高质量的视频录制功能。
    录制设置:
        分辨率:尽量使用高分辨率,以便模型能够更清晰地识别游戏内的细节。
        帧率:选择合适的帧率(如30 FPS或更高),以捕捉游戏中的动态变化。

2. 将视频转换为图片帧

    使用Python和OpenCV:可以使用Python中的OpenCV库来读取视频文件并将其转换为一系列图片帧。下面是一个简单的示例代码:
import cv2

def video_to_frames(video_path, output_dir, frame_rate=1):
    """Converts a video to frames."""
    cap = cv2.VideoCapture(video_path)
    frame_count = 0
    while(cap.isOpened()):
        ret, frame = cap.read()
        if not ret:
            break
        if frame_count % frame_rate == 0:  # 可以调整抽取帧的频率
            cv2.imwrite(f'{output_dir}/frame_{frame_count}.jpg', frame)
        frame_count += 1
    cap.release()

video_to_frames('path/to/video.mp4', 'path/to/output/directory', frame_rate=1)
3. 数据预处理

    裁剪和调整大小:根据需要裁剪图片,去除不必要的背景,或将图片调整到统一的大小。
    数据增强:为了提高模型的鲁棒性,可以使用数据增强技术,如旋转、翻转、缩放等。

4. 标注数据

    手动标注:使用标注工具(如LabelImg、Roboflow等)手动标注图片中的元素。标注包括框选目标物体的位置以及给定类别标签。
    自动标注辅助:如果已经有初步训练的模型,可以先用该模型进行自动标注,然后手动检查并修正错误。

5. 准备训练数据集

    组织数据集:将标注好的数据按照YOLO或其他目标检测框架的要求进行组织。通常需要将图片和对应的标签文件(如.txt文件)放在相应的文件夹中。

6. 训练模型

    选择模型架构:选择一个合适的目标检测模型架构,如YOLOv8、Faster R-CNN等。
    配置训练:设置训练参数,包括学习率、批次大小、优化器等。
    执行训练:使用准备好的数据集进行模型训练。例如,使用YOLO的训练命令:
yolo train model=./path/to/model.pt data=./path/to/data.yaml epochs=100 imgsz=640
7. 测试和评估

    测试模型:在独立的测试集上评估模型的性能,确保其能够准确识别游戏中的元素。
    调整模型:根据测试结果调整模型参数或数据集,以提高模型的准确性。

8. 应用模型

    实时检测:将训练好的模型应用于游戏中,实现实时检测游戏中的元素。
    决策制定:根据检测到的元素,设计算法或规则来决定游戏中的行动。

通过以上步骤,你可以有效地利用视频转图片的方法来生成训练数据,并训练一个能够识别游戏内元素并据此做出决策的模型。这不仅可以提高模型的准确性,还能减少手动标注的工作量。

六、模型转换为ONNX格式

将YOLOv8模型转换为ONNX格式是一个常见的步骤,特别是在需要将模型部署到不同的平台或使用不同的推理引擎时。ONNX(Open Neural Network Exchange)是一个开放格式,用于表示机器学习模型,允许模型在不同的框架之间共享

pip install torch onnx==1.16.1 onnx-simplifier


#如果装了最新版的onnx 报动态链接库问题,用下面的方法解决
https://blog.csdn.net/qq_38702496/article/details/141052666

 1、命令行模式

yolo export model=yolov8n.pt format=onnx simplify=True imgsz=640 output=yolov8n.onnx

 2、代码模式

import torch
import onnx
from ultralytics import YOLO

# 加载YOLOv8模型
model = YOLO('./best.pt')

# 设置输入大小
img_size = 640

# 创建一个示例输入
dummy_input = torch.randn(1, 3, img_size, img_size)

# 定义输出文件名
output_onnx_file = 'yolov8.onnx'

# 转换为ONNX格式
torch.onnx.export(
    model,
    dummy_input,
    output_onnx_file,
    input_names=['input'],
    output_names=['output'],
    dynamic_axes={
        'input': {0: 'batch_size'},
        'output': {0: 'batch_size'}
    },
    opset_version=11
)

print(f'Model has been converted to ONNX format and saved to {output_onnx_file}')
简化模型
import onnxsim

# 加载ONNX模型
onnx_model = onnx.load('yolov8.onnx')

# 简化模型
simplified_model, check = onnxsim.simplify(onnx_model)

# 检查简化后的模型是否与原始模型一致
assert check, "Simplified model is not equivalent to the original model"

# 保存简化后的模型
onnx.save(simplified_model, 'yolov8_simplified.onnx')
print('Simplified ONNX model saved.')

 为了提高模型的性能,你可以使用onnx-simplifier来简化ONNX模型。简化后的模型通常更小、更快,

3、两种方法的区别

简化模型:
命令行工具 通过--simplify参数自动简化模型。
Python脚本 需要手动调用onnx-simplifier进行简化。

输入大小:
命令行工具:通过--imgsz参数指定输入大小。
Python脚本:通过脚本中的dummy_input显式指定输入大小。

输出文件名:
命令行工具:通过--output参数指定输出文件名。
Python脚本:通过脚本中的output_onnx_file变量指定输出文件名。

4、验证模型

换后的ONNX模型应该进行验证,确保其输出与原始PyTorch模型一致。你可以使用以下代码片段来验证:

import onnxruntime
import numpy as np

# 加载简化后的ONNX模型
ort_session = onnxruntime.InferenceSession('yolov8_simplified.onnx')

# 创建一个示例输入
dummy_input_np = np.random.rand(1, 3, img_size, img_size).astype(np.float32)

# 推理
ort_inputs = {ort_session.get_inputs()[0].name: dummy_input_np}
ort_outs = ort_session.run(None, ort_inputs)

# 使用PyTorch模型进行推理
torch_out = model(dummy_input)

# 比较ONNX和PyTorch的输出
np.testing.assert_allclose(torch_out.cpu().detach().numpy(), ort_outs[0], rtol=1e-03, atol=1e-05)
print("Exported model has been successfully tested with ONNXRuntime!")

七、半自动标注工具

参考文档

#这个点赞高点
https://blog.csdn.net/ailaier/article/details/135647779?ops_request_misc=&request_id=&biz_id=102&utm_term=yolov8%E5%8D%8A%E8%87%AA%E5%8A%A8%E6%95%B0%E6%8D%AE%E9%9B%86%E6%A0%87%E6%B3%A8&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~sobaiduweb~default-1-135647779.nonecase&spm=1018.2226.3001.4450



#这个貌似说的详细
https://blog.csdn.net/qq_42178122/article/details/136322698?ops_request_misc=%257B%2522request%255Fid%2522%253A%252269829D46-2971-45F3-86E3-BF72C5F8DC5C%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=69829D46-2971-45F3-86E3-BF72C5F8DC5C&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~sobaiduend~default-1-136322698-null-null.nonecase&utm_term=yolov8%E5%8D%8A%E8%87%AA%E5%8A%A8%E6%95%B0%E6%8D%AE%E9%9B%86%E6%A0%87%E6%B3%A8&spm=1018.2226.3001.4450

试验完后补充

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐