YOLOv11代码下载

https://github.com/ultralytics/ultralytics

1.数据集制作

1.1 数据集准备

1.2 数据标注

  1. 下载安装Labelimg:Labelimg
    在这里插入图片描述

  2. 新建label文件夹保存标签
    在这里插入图片描述

  3. 打开数据集文件进行标注
    快捷键w进行标注,输入标签名,比如说person,保存,然后继续下一张,直到标注完成。
    在这里插入图片描述
    YOLO格式标签生成的是txt文件
    在这里插入图片描述
    在这里插入图片描述
    VOC格式标签生成的xml文件:
    在这里插入图片描述
    在这里插入图片描述
    包含图片信息和标注的object信息(坐标、类别)
    注意:如果是包含多个类别,请注意每个类型的顺序:比如说 0:类别1,1:类别2.

1.3数据集划分

将数据集划分为训练集、测试集、验证集。训练集:验证集:测试集=8:1:1
在YOLOv11代码ultralytics/目录下新建data.py文件,将数据集的data和label文件夹进行拆分:

import os
import random
import shutil

# 原数据集目录(相对目录)
root_dir = 'datasets/原始数据集'
# 划分比例:训练集:验证集:测试集=8:1:1
train_ratio = 0.8
valid_ratio = 0.1
test_ratio = 0.1

# 设置随机种子
random.seed(42)

# 拆分后数据集目录
split_dir = 'datasets/safe'
os.makedirs(os.path.join(split_dir, 'train/images'), exist_ok=True)
os.makedirs(os.path.join(split_dir, 'train/labels'), exist_ok=True)
os.makedirs(os.path.join(split_dir, 'valid/images'), exist_ok=True)
os.makedirs(os.path.join(split_dir, 'valid/labels'), exist_ok=True)
os.makedirs(os.path.join(split_dir, 'test/images'), exist_ok=True)
os.makedirs(os.path.join(split_dir, 'test/labels'), exist_ok=True)

# 获取图片文件列表
image_files = os.listdir(os.path.join(root_dir, 'images'))
label_files = os.listdir(os.path.join(root_dir, 'labels'))

# 随机打乱文件列表
combined_files = list(zip(image_files, label_files))#图片、标签转化为列表
random.shuffle(combined_files)#打乱
image_files_shuffled, label_files_shuffled = zip(*combined_files)#重新获取

# 根据比例计算划分的边界索引
train_bound = int(train_ratio * len(image_files_shuffled))#图片总数*训练集比例
valid_bound = int((train_ratio + valid_ratio) * len(image_files_shuffled))

# 将图片和标签文件移动到相应的目录
for i, (image_file, label_file) in enumerate(zip(image_files_shuffled, label_files_shuffled)):
    if i < train_bound:
        shutil.copy(os.path.join(root_dir, 'images', image_file), os.path.join(split_dir, 'train/images', image_file))
        shutil.copy(os.path.join(root_dir, 'labels', label_file), os.path.join(split_dir, 'train/labels', label_file))
    elif i < valid_bound:
        shutil.copy(os.path.join(root_dir, 'images', image_file), os.path.join(split_dir, 'valid/images', image_file))
        shutil.copy(os.path.join(root_dir, 'labels', label_file), os.path.join(split_dir, 'valid/labels', label_file))
    else:
        shutil.copy(os.path.join(root_dir, 'images', image_file), os.path.join(split_dir, 'test/images', image_file))
        shutil.copy(os.path.join(root_dir, 'labels', label_file), os.path.join(split_dir, 'test/labels', label_file))


最后生成的目录文件:
c1c6f8cff01284282a586a430bad9763.png)

1.4 新建.yaml配置文件

在ultralytics/datasets/下新建xx.yaml文件。
在这里插入图片描述

2.网络训练

权重文件

  1. 新建文件夹,放置下载的yolov26权重文件。下载链接
    在这里插入图片描述

在这里插入图片描述

参数配置

  • ultralytics/cfg/default.yaml:这个文件里保存了我们模型训练的所有超参数。

  • 可以复制default.yaml文件,重命名为default1.yaml
    在这里插入图片描述

  • 修改default1.yaml里面的参数,比如说:

    • 一些训练的参数:
# Train settings -------------------------------------------------------------------------------------------------------
model: pt/yolov26n.pt #模型预训练权重路径
data: ultralytics/datasets/safe.yaml  # 数据集配置文件(yarm)文件路径
epochs: 600 # (int) 训练轮次
batch: 16 # batch size
imgsz: 640 # 图像大小
device: 0 # GPU训练还是cpu。(int | str | list) device: CUDA device=0 or [0,1,2,3] or "cpu/mps" or -1 or [-1,-1] to auto-select idle GPUs
workers: 4 # 加载数据集时的线程数
project: safe # 项目名,生成的训练结果会保存在这个目录下
  • 一些数据增强的参数:
scale: 0.5 # (float) image scale (+/- gain)
shear: 0.0 # (float) image shear (+/- deg)
perspective: 0.0 # (float) image perspective (+/- fraction), range 0-0.001
flipud: 0.0 # (float) image flip up-down (probability)
fliplr: 0.5 # (float) image flip left-right (probability)
bgr: 0.0 # (float) image channel BGR (probability)
mosaic: 1.0 # (float) image mosaic (probability)
mixup: 0.0 # (float) image mixup (probability)
cutmix: 0.0 # (float) image cutmix (probability)

训练方式

YOLO命令

  • 可以直接通过YOLO 命令来进行训练。yolo train data=ultralytics/datasets/traffic.yaml model=yolov811.pt epochs=600 lr0=0.01 batch=32
  • 参数必须以 arg=val 对,用等号分割 = 符号,每对之间用空格分隔。不要使用 -- 参数 , 参数之间。

新建py文件运行(推荐)

新建yolo.py进行训练。

  • 在代码根目录新建yolo.py,直接在代码里重写参数,会默认覆盖ultralytics/cfg/default.yaml里面的参数。 这种方式可以对网络结构进行修改。
    (yaml文件和pt文件一一对应,如果想训练YOLO的其他系列,切换模型就可以了。)

有两种训练方式:

  1. 利用预训练权重,比如说yolov11n.pt进行训练
from ultralytics import YOLO
import cv2
from PIL import Image

def tran():
    # 使用预训练权重进行训练
    model = YOLO(model="pt/yolo26n.pt")
    # 开始训练
    model.train(data="ultralytics/datasets/safe.yaml", cfg="ultralytics/cfg/default1.yaml",epochs=300, batch=32,workers=8,device="cpu")
  1. 不使用预训练权重,从零开始训练(如果对网络结构进行了修改,推荐从零开始训练)
    在这里插入图片描述

    # # 不使用预训练权重,从零开始训练(如果对网络结构进行了修改,推荐从零开始训练)
    model = YOLO('ultralytics/cfg/models/26/yolo26.yaml')
    model.train(cfg="ultralytics/cfg/default1.yaml", data="ultralytics/datasets/safe.yaml", epochs=600, close_mosaic=30, batch=4)
    # 这里写的参数会覆盖之前的default.yaml中的参数

3. 网络验证

需要加载训练好的best.pt权重模型,data参数需要传入数据集对应的yaml文件

def val():
    # 在训练数据集上进行验证
    model = YOLO(model='runs/detect/train/weights/best.pt')
    model.val(data='ultralytics/datasets/safe.yaml')

4. 模型预测

需要加载训练好的best.pt权重模型,source参数需要传入你想要预测的图片或者视频或者文件夹

def predict():

    model = YOLO(model="runs/detect/train/weights/best.pt")#训练完的模型文件路径
    # accepts all formats - image/dir/Path/URL/video/PIL/ndarray. 0 for webcam
    model.predict(source="ultralytics/datasets/safe/test/images",save=True,save_txt=True)  # #source="folder"预测数据的文件夹路径

    # # from PIL
    # im1 = Image.open("bus.jpg")
    # results = model.predict(source=im1, save=True)  # save plotted images
    #
    # # from ndarray
    # im2 = cv2.imread("bus.jpg")
    # results = model.predict(source=im2, save=True, save_txt=True)  # save predictions as labels
    #
    # # from list of PIL/ndarray
    # results = model.predict(source=[im1, im2])

注意:网络训练和验证、推理(预测)不能同时进行,必须要训练完之后才能进行验证、推理(预测),主函数中只能同时运行一个,其余代码需要注释掉

完整代码:





from ultralytics import YOLO
import cv2
from PIL import Image

def tran():
    # 使用预训练权重进行训练
    model = YOLO(model="pt/yolo26n.pt")
    # model = YOLO(model="pt/yolo26s.pt")
    # model = YOLO(model="pt/yolo26m.pt")
    # model = YOLO(model="pt/yolo26l.pt")
    # model = YOLO(model="pt/yolo26x.pt")
    # 开始训练
    # model.train(data="ultralytics/datasets/safe.yaml", cfg="ultralytics/cfg/default1.yaml",epochs=300, batch=32,workers=8,device="cpu")

    # # # 不使用预训练权重,从零开始训练(如果对网络结构进行了修改,推荐从零开始训练)
    model = YOLO('ultralytics/cfg/models/26/yolo26.yaml')
    model.train(cfg="ultralytics/cfg/default1.yaml", data="ultralytics/datasets/safe.yaml", epochs=600, close_mosaic=30, batch=4)
    # 这里写的参数会覆盖之前的default.yaml中的参数

def val():
    # 在训练数据集上进行验证
    model = YOLO(model='runs/detect/train/weights/best.pt')
    model.val(data='ultralytics/datasets/safe.yaml')

def predict():

    model = YOLO(model="runs/detect/train/weights/best.pt")#训练完的模型文件路径
    # accepts all formats - image/dir/Path/URL/video/PIL/ndarray. 0 for webcam
    model.predict(source="ultralytics/datasets/safe/test/images",save=True,save_txt=True)  # #source="folder"预测数据的文件夹路径

    # # from PIL
    # im1 = Image.open("bus.jpg")
    # results = model.predict(source=im1, save=True)  # save plotted images
    #
    # # from ndarray
    # im2 = cv2.imread("bus.jpg")
    # results = model.predict(source=im2, save=True, save_txt=True)  # save predictions as labels
    #
    # # from list of PIL/ndarray
    # results = model.predict(source=[im1, im2])

if __name__ == '__main__':
    val()

5. 训练结果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

预测图片效果

在这里插入图片描述
在这里插入图片描述

6.模型导出

训练好的权重文件可以导出封装为torchscript|onnx|openvino,方便跨平台开发使用。

def export():
    model = YOLO(model="runs/detect/train/weights/best.pt")  # 训练完的模型文件路径
    # 将模型导出为 ONNX 格式以进行部署
    model.export(format="onnx")  # 返回导出模型的路径

在这里插入图片描述
在这里插入图片描述

7.目标计数

统计图片中的某个类别的数量:

#图片计数
import cv2
from ultralytics import YOLO

def count_specific_class(image_path, output_img_path, model_path, target_classes=[0]):
    model = YOLO(model_path)
    img = cv2.imread(image_path)
    results = model(img, classes=target_classes)[0]  # cls_id 换成你的类别ID
    obj_num = len(results.boxes)

    res_img = results.plot()
    cv2.imwrite(output_img_path, res_img)
    print(f"指定类别目标数量:{obj_num}")
    cv2.destroyAllWindows()

if __name__ == "__main__":
    # 示例:只统计类别0的目标
    count_specific_class("图片路径", "保存路径", "runs/train/weights/best.pt", target_classes=[0])#.pt文件替换为训练好的权重文件

统计视频中的检测目标数量:

#图片计数
# 批量文件夹图片计数
import os
import cv2
from ultralytics import YOLO

def batch_count_images(input_dir, output_dir, model_path, target_classes=[0]):
    # 创建输出文件夹,不存在则自动新建
    os.makedirs(output_dir, exist_ok=True)
    # 加载训练好的模型
    model = YOLO(model_path)

    # 遍历输入文件夹所有文件
    for file_name in os.listdir(input_dir):
        # 筛选常见图片格式
        suffix = file_name.lower()
        if not suffix.endswith((".jpg", ".jpeg", ".png", ".bmp")):
            continue

        img_path = os.path.join(input_dir, file_name)
        img = cv2.imread(img_path)
        if img is None:
            print(f"警告:{file_name} 图片读取失败,跳过")
            continue

        # 推理指定类别目标
        results = model(img, classes=target_classes)[0]
        obj_num = len(results.boxes)

        # 绘制检测框并保存
        res_img = results.plot()
        save_path = os.path.join(output_dir, file_name)
        cv2.imwrite(save_path, res_img)

        print(f"图片 {file_name} | 指定类别总数:{obj_num}")

    cv2.destroyAllWindows()

if __name__ == "__main__":
    # 配置路径
    input_folder = "ultralytics/datasets/safe/test/images"   # 原图文件夹
    output_folder = "runs/count"                             # 结果保存文件夹
    weight_path = "runs/detect/train/weights/best.pt"
    cls_list = [0, 1, 2, 3]

    batch_count_images(input_folder, output_folder, weight_path, target_classes=cls_list)

在这里插入图片描述

7.热力图可视化

用来显示某一层网络之后的输出特征图。

视频时序热力图:

#视频heatmap
import cv2

from ultralytics import solutions

cap = cv2.VideoCapture("path/to/video.mp4")
heatmap = solutions.Heatmap(show=True, model="yolo26n.pt", classes=[0, 2])

while cap.isOpened():
    success, im0 = cap.read()
    if not success:
        break
    results = heatmap(im0)
cap.release()
cv2.destroyAllWindows()

图片时序热力图:

import os
import cv2
from ultralytics import solutions

def accumulate_heatmap_multi_img(img_dir, out_save_path, model_path, target_classes):
    img_dir = os.path.abspath(img_dir)
    # 初始化仅一次,全程复用实例,热度持续累积
    heatmap = solutions.Heatmap(
        show=False,
        model=model_path,
        classes=target_classes,
        colormap=cv2.COLORMAP_HOT
    )
    img_suffix = (".jpg", ".jpeg", ".png", ".bmp")
    img_list = sorted([f for f in os.listdir(img_dir) if f.lower().endswith(img_suffix)])

    if len(img_list) == 0:
        print("文件夹无图片")
        return

    last_draw = None
    # 循环所有图片,持续叠加热度
    for name in img_list:
        full_path = os.path.join(img_dir, name)
        im = cv2.imread(full_path)
        if im is None:
            print(f"跳过损坏图片:{name}")
            continue
        res = heatmap(im)
        last_draw = res.plot_im
        print(f"已累积图片:{name}")

    # 全部图片处理完成,保存累积后的总热力图
    os.makedirs(os.path.dirname(out_save_path), exist_ok=True)
    if last_draw is not None:
        flag = cv2.imwrite(out_save_path, last_draw)
        if flag:
            print(f"累积热力图保存完成:{out_save_path}")
        else:
            cv2.imwrite(r"C:\Users\HP\Desktop\accum_heat.jpg", last_draw)
    cv2.destroyAllWindows()

if __name__ == "__main__":
    input_images = "ultralytics/datasets/safe/test/images"
    output_heat = "runs/heatmap/accum_total_heat.jpg"
    weight = "runs/detect/train/weights/best.pt"
    cls = [0, 1, 2, 3]
    accumulate_heatmap_multi_img(input_images, output_heat, weight, cls)

在这里插入图片描述

Grad-CAM 注意力热力图:

import cv2
import numpy as np
import torch
from ultralytics import YOLO
import matplotlib.cm as cm
import os

# ---------------------- 中文绘制工具函数 ----------------------
def put_chinese_text(img, text, pos, font_size=1.4, color=(255,255,255), thickness=2):
    # 适配Windows系统微软雅黑字体,路径可自行修改
    font_path = "C:/Windows/Fonts/msyh.ttc"
    from PIL import Image, ImageDraw, ImageFont
    # OpenCV转PIL
    img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    draw = ImageDraw.Draw(img_pil)
    try:
        font = ImageFont.truetype(font_path, int(font_size * 16))
    except:
        font = ImageFont.load_default()
    draw.text(pos, text, font=font, fill=color)
    # 转回OpenCV格式
    return cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)

# ---------------------- Grad-CAM可视化类 ----------------------
class YOLOGradCAM:
    def __init__(self, model_path, class_chinese_dict):
        self.model = YOLO(model_path)
        self.device = self.model.device
        self.activation = None
        self.hook_handle = None
        self.class_chinese = class_chinese_dict  # 类别ID→中文名称映射
        self._register_hook()

    def _register_hook(self):
        def hook_func(module, input, output):
            self.activation = output.detach()
        target_layer = self.model.model.model[-5]
        self.hook_handle = target_layer.register_forward_hook(hook_func)

    def get_gradcam(self, img_path, target_cls_ids=None):
        ori_img = cv2.imread(img_path)
        if ori_img is None:
            raise FileNotFoundError("图片读取失败")
        h, w = ori_img.shape[:2]
        res = self.model(img_path, classes=target_cls_ids)[0]
        if len(res.boxes) == 0:
            print("图片未检测到目标,无热力图")
            return ori_img

        # 生成热力图
        feat = self.activation.mean(dim=1, keepdim=True)
        feat = torch.nn.functional.interpolate(feat, size=(h, w), mode="bilinear")
        heat_np = feat.squeeze().cpu().numpy()
        heat_np = (heat_np - heat_np.min()) / (heat_np.max() - heat_np.min() + 1e-8)
        heat_color = cm.jet(heat_np)[..., :3] * 255
        heat_color = heat_color.astype(np.uint8)
        heat_color = cv2.cvtColor(heat_color, cv2.COLOR_RGB2BGR)

        # 热力与原图融合
        alpha = 0.4
        blend = cv2.addWeighted(ori_img, 1 - alpha, heat_color, alpha, 0)

        # 绘制检测框 + 中文标签
        boxes = res.boxes
        for box in boxes:
            xyxy = box.xyxy[0].cpu().numpy().astype(int)
            conf = float(box.conf[0])
            cid = int(box.cls[0])
            # 获取中文类别名
            cls_cn = self.class_chinese.get(cid, f"未知类别{cid}")
            # 白色检测框
            cv2.rectangle(blend, (xyxy[0], xyxy[1]), (xyxy[2], xyxy[3]), (255,255,255), 2)
            # 绘制中文文字
            text_content = f"{cls_cn} {conf:.2f}"
            blend = put_chinese_text(blend, text_content, (xyxy[0], xyxy[1]-20), font_size=1.3)
        return blend

    def release(self):
        if self.hook_handle:
            self.hook_handle.remove()

# ---------------------- 主程序运行 ----------------------
if __name__ == "__main__":
    # ========== 【重要】在这里修改你的类别中文映射 ==========
    # key=模型类别ID,value=对应中文名称
    class_cn_map = {
        0: '类别1',
        1: '类别2',
        2: '类别3',
        3: '类别4',

    }

    # 路径配置
    img_path = "ultralytics/datasets/safe/test/images/1007.jpg"
    save_out = "runs/heatmap/gradcam_中文热力图.jpg"
    weight_path = "runs/detect/train/weights/best.pt"
    target_classes = [0,1,2,3]

    # 生成热力图
    cam = YOLOGradCAM(weight_path, class_chinese_dict=class_cn_map)
    result_img = cam.get_gradcam(img_path, target_cls_ids=target_classes)
    cv2.imwrite(save_out, result_img)
    print(f"中文热力图保存完成:{save_out}")
    cam.release()

    # 弹窗查看结果
    cv2.imshow("GradCAM 中文热力图", result_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

Grad-CAM 注意力热力图结果:
在这里插入图片描述

Logo

免费领 150 小时云算力,进群参与显卡、AI PC 幸运抽奖

更多推荐