YOLOv12 模型本地训练与推理-03

一、数据集准备

1、数据集标准软件

我们使用免费的数据集标准平台 https://www.coovally.com/, 或者开源的标注工具 labelme、 labelimg;

数据集有以下两种方式放置,都可以进行训练,常见的数据集放置是第一种,也有开源的数据集按照第二种方式放置的,我都遇见过,也能训练起来;

file

从 coovally.com 平台导出的yolo数据集格式:
file

2、数据集划分

拆分训练集和验证集代码,如下:
安装依赖:

!pip install scikit-learn

数据集拆分:

import os, shutil
from sklearn.model_selection import train_test_split

val_size = 0.2
postfix = 'jpg'
imgpath = './datasets-origin/images'
txtpath =  './datasets-origin/label/label'

output_train_img_folder ='./datasets-yolo/images/train'
output_val_img_folder =  './datasets-yolo/images/val'
output_train_txt_folder =  './datasets-yolo/labels/train'
output_val_txt_folder =  './datasets-yolo/labels/val'

os.makedirs(output_train_img_folder, exist_ok=True)
os.makedirs(output_val_img_folder, exist_ok=True)
os.makedirs(output_train_txt_folder, exist_ok=True)
os.makedirs(output_val_txt_folder, exist_ok=True)

listdir = [i for i in os.listdir(txtpath) if 'txt' in i]
train, val = train_test_split(listdir, test_size=val_size, shuffle=True, random_state=0)

#print("-------------- train -------------")
#print(train)

#print("---------------- val -------------")
#print(val)

for i in train:
    img_source_path = os.path.join(imgpath, '{}.{}'.format(i[:-4], postfix))
    txt_source_path = os.path.join(txtpath, i)

    img_destination_path = os.path.join(output_train_img_folder, '{}.{}'.format(i[:-4], postfix))
    txt_destination_path = os.path.join(output_train_txt_folder, i)

    shutil.copy(img_source_path, img_destination_path)
    shutil.copy(txt_source_path, txt_destination_path)

for i in val:
    img_source_path = os.path.join(imgpath, '{}.{}'.format(i[:-4], postfix))
    txt_source_path = os.path.join(txtpath, i)

    img_destination_path = os.path.join(output_val_img_folder, '{}.{}'.format(i[:-4], postfix))
    txt_destination_path = os.path.join(output_val_txt_folder, i)

    shutil.copy(img_source_path, img_destination_path)
    shutil.copy(txt_source_path, txt_destination_path)

3、修改yolo的训练配置文件

我们需要在项目下创建一个 data.yaml 的文件,文件名根据数据集名称取,我这里方便演示直接叫 data.yaml,如下图所示:

train: ./datasets-yolo/images/train  # train images (relative to 'path') 4 images
val: ./datasets-yolo/images/val  # val images (relative to 'path') 4 images

nc: 2

# class names
names: ['rised','lowed']

4、训练模型

!pip install ultralytics

import warnings
warnings.filterwarnings('ignore')
from ultralytics import YOLO

# model = YOLO(model=r'D:\2-Python\1-YOLO\YOLOv12\yolov12-main\ultralytics\cfg\models\v12\yolov12.yaml')
# model.load('yolo11n.pt') # 加载预训练权重,改进或者做对比实验时候不建议打开,因为用预训练模型整体精度没有很明显的提升

# Load a model
#model = YOLO("yolo11n.yaml")  # build a new model from YAML
#model = YOLO("yolo11n.pt")  # load a pretrained model (recommended for training)
#model = YOLO("yolo11n.yaml").load("yolo11n.pt")  # build from YAML and transfer weights

# Train the model
# results = model.train(data="coco8.yaml", epochs=100, imgsz=640)

# eg: https://docs.ultralytics.com/modes/train/#usage-examples

# 数据集数量较少(2500张),所以用预训练模型来做训练
# Load a COCO-pretrained YOLO12n model
model = YOLO("yolo12n.pt")
model.train(data='data.yaml',  #数据集配置文件的路径
            imgsz=640, #训练图像尺寸
            epochs=50, #训练轮次总数
            batch=4,  #批量大小,即单次输入多少图片训练
            workers=4, #加载数据的工作线程数
            device='cuda:0', #指定训练的计算设备,无nvidia显卡则改为 'cpu'
            optimizer='SGD', #训练使用优化器,可选 auto,SGD,Adam,AdamW 等
            amp= True,  #True 或者 False, 解释为:自动混合精度(AMP) 训练
            close_mosaic=10,
            resume=False,
            project='runs/train',
            name='exp',
            single_cls=False,
            cache=False,
            )

训练代码的参数解释:

  • model参数:该参数填入模型配置文件的路径,改进的话建议不需要填预训练模型权重
  • data参数:可以填入训练数据集配置文件的路径
  • imgsz参数:该参数代表输入图像的尺寸,指定为 640x640 像素
  • epochs参数:该参数代表训练的轮数
  • batch参数:该参数代表批处理大小,电脑显存越大,就设置越大,根据自己电脑性能设置。
  • workers参数:该参数代表数据加载的工作线程数,出现显存爆了的话可以设置为0,默认是8。
  • device参数:该参数代表用哪个显卡训练,留空表示自动选择可用的GPU或CPU
  • optimizer参数:该参数代表优化器类型
  • close_mosaic参数:该参数代表在多少个 epoch 后关闭 mosaic 数据增强
  • resume参数:该参数代表是否从上一次中断的训练状态继续训练。设置为False表示从头开始新的训练。如果设置为True,则会加载上一次训练的模型权重和优化器状态,继续训练。这在训练被中断或在已有模型的基础上进行进一步训练时非常有用。
  • project参数:该参数代表项目文件夹,用于保存训练结果
  • name参数:该参数代表命名保存的结果文件夹
  • single_cls参数:该参数代表是否将所有类别视为一个类别,设置为False表示保留原有类别
  • cache参数:该参数代表是否缓存数据,设置为False表示不缓存。

注意注意注意:一般做科研改进工作时候可以不用预训练权重,因为用预训练模型整体精度很难提高;

训练日志打印:
file

New https://pypi.org/project/ultralytics/8.3.141 available 😃 Update with 'pip install -U ultralytics'
Ultralytics 8.3.140 🚀 Python-3.11.11 torch-2.2.2 CUDA:0 (NVIDIA L20, 45488MiB)
engine/trainer: agnostic_nms=False, amp=True, augment=False, auto_augment=randaugment, batch=4, bgr=0.0, box=7.5, cache=False, cfg=None, classes=None, close_mosaic=10, cls=0.5, conf=None, copy_paste=0.0, copy_paste_mode=flip, cos_lr=False, cutmix=0.0, data=data.yaml, degrees=0.0, deterministic=True, device=0, dfl=1.5, dnn=False, dropout=0.0, dynamic=False, embed=None, epochs=50, erasing=0.4, exist_ok=False, fliplr=0.5, flipud=0.0, format=torchscript, fraction=1.0, freeze=None, half=False, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, imgsz=640, int8=False, iou=0.7, keras=False, kobj=1.0, line_width=None, lr0=0.01, lrf=0.01, mask_ratio=4, max_det=300, mixup=0.0, mode=train, model=yolo12n.pt, momentum=0.937, mosaic=1.0, multi_scale=False, name=exp, nbs=64, nms=False, opset=None, optimize=False, optimizer=SGD, overlap_mask=True, patience=100, perspective=0.0, plots=True, pose=12.0, pretrained=True, profile=False, project=runs/train, rect=False, resume=False, retina_masks=False, save=True, save_conf=False, save_crop=False, save_dir=runs/train/exp, save_frames=False, save_json=False, save_period=-1, save_txt=False, scale=0.5, seed=0, shear=0.0, show=False, show_boxes=True, show_conf=True, show_labels=True, simplify=True, single_cls=False, source=None, split=val, stream_buffer=False, task=detect, time=None, tracker=botsort.yaml, translate=0.1, val=True, verbose=True, vid_stride=1, visualize=False, warmup_bias_lr=0.1, warmup_epochs=3.0, warmup_momentum=0.8, weight_decay=0.0005, workers=4, workspace=None
Downloading https://ultralytics.com/assets/Arial.ttf to '/home/leoking/.config/Ultralytics/Arial.ttf'...
100%|██████████| 755k/755k [00:00<00:00, 1.14MB/s]
Overriding model.yaml nc=80 with nc=2

                   from  n    params  module                                       arguments                     
  0                  -1  1       464  ultralytics.nn.modules.conv.Conv             [3, 16, 3, 2]                 
  1                  -1  1      4672  ultralytics.nn.modules.conv.Conv             [16, 32, 3, 2]                
  2                  -1  1      6640  ultralytics.nn.modules.block.C3k2            [32, 64, 1, False, 0.25]      
  3                  -1  1     36992  ultralytics.nn.modules.conv.Conv             [64, 64, 3, 2]                
  4                  -1  1     26080  ultralytics.nn.modules.block.C3k2            [64, 128, 1, False, 0.25]     
  5                  -1  1    147712  ultralytics.nn.modules.conv.Conv             [128, 128, 3, 2]              
  6                  -1  2    180864  ultralytics.nn.modules.block.A2C2f           [128, 128, 2, True, 4]        
  7                  -1  1    295424  ultralytics.nn.modules.conv.Conv             [128, 256, 3, 2]              
  8                  -1  2    689408  ultralytics.nn.modules.block.A2C2f           [256, 256, 2, True, 1]        
  9                  -1  1         0  torch.nn.modules.upsampling.Upsample         [None, 2, 'nearest']          
 10             [-1, 6]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           
 11                  -1  1     86912  ultralytics.nn.modules.block.A2C2f           [384, 128, 1, False, -1]      
 12                  -1  1         0  torch.nn.modules.upsampling.Upsample         [None, 2, 'nearest']          
 13             [-1, 4]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           
 14                  -1  1     24000  ultralytics.nn.modules.block.A2C2f           [256, 64, 1, False, -1]       
 15                  -1  1     36992  ultralytics.nn.modules.conv.Conv             [64, 64, 3, 2]                
 16            [-1, 11]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           
 17                  -1  1     74624  ultralytics.nn.modules.block.A2C2f           [192, 128, 1, False, -1]      
 18                  -1  1    147712  ultralytics.nn.modules.conv.Conv             [128, 128, 3, 2]              
 19             [-1, 8]  1         0  ultralytics.nn.modules.conv.Concat           [1]                           
 20                  -1  1    378880  ultralytics.nn.modules.block.C3k2            [384, 256, 1, True]           
 21        [14, 17, 20]  1    431062  ultralytics.nn.modules.head.Detect           [2, [64, 128, 256]]           
YOLOv12n summary: 272 layers, 2,568,438 parameters, 2,568,422 gradients, 6.5 GFLOPs

Transferred 640/691 items from pretrained weights
Freezing layer 'model.21.dfl.conv.weight'
AMP: running Automatic Mixed Precision (AMP) checks...
Downloading https://github.com/ultralytics/assets/releases/download/v8.3.0/yolo11n.pt to 'yolo11n.pt'...
100%|██████████| 5.35M/5.35M [00:01<00:00, 4.11MB/s]
AMP: checks passed ✅
train: Fast image access ✅ (ping: 0.0±0.0 ms, read: 2508.6±1095.2 MB/s, size: 126.7 KB)
train: Scanning /home/leoking/app/data/cvtest/yolo-test/test/datasets-yolo/labels/train... 944 images, 0 backgrounds, 0 corrupt: 100%|██████████| 944/944 [00:01<00:00, 842.30it/s]
train: New cache created: /home/leoking/app/data/cvtest/yolo-test/test/datasets-yolo/labels/train.cache

val: Fast image access ✅ (ping: 0.0±0.0 ms, read: 1090.2±129.5 MB/s, size: 158.6 KB)
val: Scanning /home/leoking/app/data/cvtest/yolo-test/test/datasets-yolo/labels/val... 236 images, 0 backgrounds, 0 corrupt: 100%|██████████| 236/236 [00:00<00:00, 714.78it/s]
val: New cache created: /home/leoking/app/data/cvtest/yolo-test/test/datasets-yolo/labels/val.cache

Plotting labels to runs/train/exp/labels.jpg... 
optimizer: SGD(lr=0.01, momentum=0.937) with parameter groups 113 weight(decay=0.0), 120 weight(decay=0.0005), 119 bias(decay=0.0)
Image sizes 640 train, 640 val
Using 4 dataloader workers
Logging results to runs/train/exp
Starting training for 50 epochs...

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
       1/50      1.08G      1.411      3.012       1.34         14        640: 100%|██████████| 236/236 [00:18<00:00, 12.71it/s]
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 30/30 [00:05<00:00,  5.54it/s]
                   all        236        291      0.922      0.416      0.517      0.313

      Epoch    GPU_mem   box_loss   cls_loss   dfl_loss  Instances       Size
       2/50      1.08G      1.222      1.911      1.165          7        640: 100%|██████████| 236/236 [00:16<00:00, 14.19it/s]
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 30/30 [00:01<00:00, 22.25it/s]
                   all        236        291      0.603      0.638      0.675      0.403

...
50 epochs completed in 0.305 hours.
Optimizer stripped from runs/train/exp/weights/last.pt, 5.5MB
Optimizer stripped from runs/train/exp/weights/best.pt, 5.5MB

Validating runs/train/exp/weights/best.pt...
Ultralytics 8.3.140 🚀 Python-3.11.11 torch-2.2.2 CUDA:0 (NVIDIA L20, 45488MiB)
YOLOv12n summary (fused): 159 layers, 2,557,118 parameters, 0 gradients, 6.3 GFLOPs
                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95): 100%|██████████| 30/30 [00:01<00:00, 19.69it/s]
                   all        236        291      0.924      0.951      0.971      0.781
                 rised         49         50      0.885       0.98      0.966      0.801
                 lowed        209        241      0.964      0.921      0.975      0.762
Speed: 0.1ms preprocess, 3.0ms inference, 0.0ms loss, 0.7ms postprocess per image
Results saved to runs/train/exp
ultralytics.utils.metrics.DetMetrics object with attributes:

ap_class_index: array([0, 1])
box: ultralytics.utils.metrics.Metric object
confusion_matrix: <ultralytics.utils.metrics.ConfusionMatrix object at 0x7e152a70b710>
curves: ['Precision-Recall(B)', 'F1-Confidence(B)', 'Precision-Confidence(B)', 'Recall-Confidence(B)']

...

fitness: 0.8000751227493044
keys: ['metrics/precision(B)', 'metrics/recall(B)', 'metrics/mAP50(B)', 'metrics/mAP50-95(B)']
maps: array([    0.80063,     0.76164])
names: {0: 'rised', 1: 'lowed'}
plot: True
results_dict: {'metrics/precision(B)': 0.9244337289542359, 'metrics/recall(B)': 0.9505809128630704, 'metrics/mAP50(B)': 0.9705155906166117, 'metrics/mAP50-95(B)': 0.7811372929862702, 'fitness': 0.8000751227493044}
save_dir: PosixPath('runs/train/exp')
speed: {'preprocess': 0.11476875930014303, 'inference': 3.0429928121551617, 'loss': 0.0011303335807080997, 'postprocess': 0.7453218804893352}
task: 'detect'

训练过程如图,耐心等待训练完成即可,训练完成后会生成.pt权重文件,可以用来验证训练效果。

在训练的时候,监控GPU使用情况:

(base) leoking@leoking-desktop:~$ nvidia-smi
Wed May 21 11:43:30 2025
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 560.35.05              Driver Version: 560.35.05      CUDA Version: 12.6     |
|-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA L20                     Off |   00000000:A8:00.0 Off |                    0 |
| N/A   61C    P0            122W /  350W |    1924MiB /  46068MiB |     21%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI        PID   Type   Process name                              GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|    0   N/A  N/A   1673247      C   .../miniconda3/envs/yolov12/bin/python        314MiB |
|    0   N/A  N/A   1681119      C   .../miniconda3/envs/yolov12/bin/python       1596MiB |
+-----------------------------------------------------------------------------------------+
(base) leoking@leoking-desktop:~$

模型效果评价

相关的指标:

file

从你提供的 YOLOv12 训练结果截图(results.csv)来看,以下是对关键指标的详细分析(按训练过程和最终结果两个维度):


✅ 一、训练过程趋势分析:

1. 损失函数(Loss)分析

  • train/box_loss: 从约 1.41 降到 0.94 左右,逐步降低,说明模型定位能力在稳步提升。
  • train/cls_loss: 从 3.01 降到 0.67 左右,下降明显,代表分类准确性持续提高。
  • train/dfl_loss: 从 1.34 降到 1.02 左右,说明用于预测回归的分布焦点损失(Distribution Focal Loss)也在改善。

2. 验证集损失(val)对比训练集

  • val/box_lossval/cls_lossval/dfl_loss 均逐步下降,且变化趋势与训练集保持一致,没有出现过拟合迹象。

✅ 二、关键评估指标(Metrics)分析:

1. 精度(Precision)

  • metrics/precision(B)0.92 上升至 0.94(波动较小),说明预测结果中 TP 比例较高,模型对目标检测较保守但准确。

2. 召回率(Recall)

  • metrics/recall(B)0.41 上升到 0.95+,提升显著,说明模型在检测目标的完整性方面进步巨大。

3. mAP(mean Average Precision)

  • metrics/mAP50(B): 从 0.51 增长到 0.95,表示 IOU ≥ 0.5 情况下目标检测能力已趋近饱和。
  • metrics/mAP50-95(B): 从 0.31 增长到 0.73,提升幅度大,表明模型在严格IOU标准下也取得了强表现。

✅ 三、超参数变化趋势(学习率调度):

  • lr/pg0lr/pg1lr/pg20.007\~0.009 逐步下降到 0.004\~0.005,说明模型采用了 Cosine Decay 或 Step LR Schedule,合理地控制了训练稳定性。

✅ 四、最终评估(Epoch 31 时):

指标名称 解读
metrics/precision(B) 0.88408 精度高,模型预测目标准确
metrics/recall(B) 0.95169 召回能力非常强,几乎无漏检
metrics/mAP50(B) 0.95492 常规mAP接近饱和,非常优秀
metrics/mAP50-95(B) 0.72611 严格评估下表现良好,可再优化
val/box_loss 0.89106 模型定位能力好,误差较低
val/cls_loss 0.5837 分类误差显著降低
val/dfl_loss 1.02488 分布焦点损失较为稳定

📌 建议与下一步:

  1. 模型已基本收敛,继续训练收益可能边际递减。
  2. 若需进一步提升 mAP50-95,可考虑:

    • 更复杂的骨干网络(如 CSPResNet 改为 EfficientNet)。
    • 更高分辨率的输入图像。
    • 更精细的数据增强(如 mosaic、mixup)。
  3. 若训练目标是部署至边缘设备,可以用当前模型量化部署。

如果你有P_curve.pngF1_curve.png等指标曲线图,也可以上传,我可以进一步可视化分析训练过程稳定性。是否需要我帮你生成可视化图表或进行进一步的模型评估建议?

file
( P_curve.png)

file
( F1_curve.png)

从你提供的两张图(Precision-Confidence Curve 和 F1-Confidence Curve)中,我们可以详细分析模型在不同置信度阈值下的表现,以优化预测决策阈值或进一步调优模型。


📈 一、Precision-Confidence Curve 分析

含义:

该图展示了模型在不同预测置信度阈值下的 精确率(Precision) 表现。

观察结果:

  • 总体表现(蓝色粗线)
    在整个置信度范围内保持了较高的精确率,尤其在 0.2 以上时迅速接近 0.9。最终在置信度为 1.0 时达到 0.99 的精度。

  • 类别对比:

    • rised(蓝色细线):整体曲线较为平稳,在高置信度下略有波动,精确率约为 0.95。
    • lowed(橙色细线):整体精度略高于 rised 类别,说明模型对 lowed 类别的判断更可靠。

结论:

  • 模型具有 很强的精确性,尤其当设定高置信度阈值时。
  • 若追求高精度的预测输出,可以将阈值设置在 0.8 \~ 1.0。

🧮 二、F1-Confidence Curve 分析

含义:

该图展示的是不同置信度阈值下的 F1 值(精确率与召回率的调和平均),用于衡量整体预测效果的平衡性。

观察结果:

  • 总体 F1 曲线(蓝色粗线)

    • 在置信度 0.552 附近达到最高 F1 值 0.94
    • 当置信度高于 0.8 时,F1 值明显下降,这说明虽然精度高,但召回率开始严重下降。
  • 类别表现:

    • rised 类 在较宽的置信区间保持高 F1(≈0.95)。
    • lowed 类 在高置信度下 F1 值下降更快,说明对该类的召回能力较弱。

结论:

  • 最佳置信度阈值建议设为 约 0.55,在此处模型达到最佳精确率与召回率平衡。
  • 超过此阈值会牺牲召回率,适合高精度场景;低于此阈值虽有较高召回率但精度下降。

✅ 综合建议

目标 推荐置信度阈值 说明
通用高性能分类 0.55 平衡精确率和召回率,F1 最优
追求高精度预测(低误报) ≥ 0.8 精度高,但可能漏掉一些正确样本
召回率优先(高覆盖) 0.3\~0.5 找全更多样本,接受部分误判

5、模型测试

找到之前训练的结果保存路径,创建一个yolov11_predict.py文件,内容如下

默认置信度阈值为 conf=0.25,也就是只保留模型预测概率 > 0.25 的目标。根据提供的 F1 曲线图,最佳置信度阈值是 0.55,因此建议这样写:

from ultralytics import YOLO
# 加载训练好的模型,改为自己的路径
model = YOLO('runs/detect/train/weights/best.pt')  #修改为训练好的路径
source = 'test1.jpg' #修改为自己的图片路径及文件名

# 运行推理,并附加参数,使用 F1 最佳阈值进行预测
model.predict(source=source, conf=0.55, save=True)

# 视频流
# model.predict(source='path/to/folder_or_video.mp4', conf=0.55, save=True)

yolo coco 数据集格式

ultralytics 官网YOLO数据集放置方式:

dataset/
├── train/
│   ├── images/
│   └── labels/
└── val/
    ├── images/
    └── labels/

整理数据集:将数据集排列到正确的文件夹结构中。您应该 train/val/ 顶层目录,而在每个顶层目录中,都有一个 images/labels/ 子目录。

创建一个 data.yaml 文件:在数据集的根目录中,创建一个 data.yaml 文件,其中描述了数据集、类和其他必要信息。

COCO8数据集 YAML

COCO8 数据集配置是在 YAML(另一种标记语言)文件中定义的,该文件指定了数据集路径、类名和其他重要元数据。您可以查看官方的 coco8.yaml 文件中的 Ultralytics GitHub 存储库.

# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license

# COCO8 dataset (first 8 images from COCO train2017) by Ultralytics
# Documentation: https://docs.ultralytics.com/datasets/detect/coco8/
# Example usage: yolo train data=coco8.yaml
# parent
# ├── ultralytics
# └── datasets
#     └── coco8  ← downloads here (1 MB)

# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: ../datasets/coco8 # dataset root dir
train: images/train # train images (relative to 'path') 4 images
val: images/val # val images (relative to 'path') 4 images
test: # test images (optional)

# Classes
names:
  0: person
  1: bicycle
  2: car
  3: motorcycle
  4: airplane
  5: bus
  6: train
  7: truck
  8: boat
  9: traffic light
  10: fire hydrant

...
  79: toothbrush

# Download script/URL (optional)
download: https://github.com/ultralytics/assets/releases/download/v0.0.0/coco8.zip

相关文章:
ultralytics 官网YOLO数据集
Yolo模型训练文章

为者常成,行者常至