YOLO 入门实战(二):用自定义数据训练你的第一个检测模型
上一篇中,我们从零开始,完成了目标检测项目的第一步:构建并标注了自己的小规模数据集 。通过 Conda 创建独立环境,使用 Label Studio 进行高效标注,并成功导出为 YOLO 可读的格式------现在,我们的硬盘里已经躺着一个结构清晰、标签准确的数据集了。 数据是"燃料",而模型就是"引擎"。今天,我们将点燃这台引擎,使用 Ultralytics YOLOv8,训练属于你自己的第一个目标检测模型!
1.构建YOLO开发环境
首先依旧使用conda创建一个用于开发YOLO的虚拟环境,然后激活这个虚拟环境并下载所需要的依赖。
bash
conda create -n yolo python=3.11 -y
conda activate yolo
# 下载依赖
pip install ultralytics
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126
2.将导出的数据集添加到项目
我们需要按照下面的结构来建立目录
kotlin
yolo-project/
├── dataset/
│ ├── images/
│ ├── labels/
│ └── data.yaml
└── runs/
将原先数据集中按照1:4的比例划分验证集和训练集,然后将图片和标签分别对应放入images文件夹和labels文件夹的train以及val文件夹集合中。然后我们可以开始编写我们的data.yaml,这个文件相当于是告诉YOLO我们的训练集、验证集、测试集(可选)的位置以及我们进行目标检测的一些配置参数,这个是我简单构造的一个data.ymal文件
yaml
path: ./boxing
train: images/train
val: images/val
augment: true
mosaic: true
mixup: true
degrees: 5.0 # 随机旋转角度
translate: 0.1 # 平移比例
scale: 0.5 # 缩放比例
flipud: 0.0 # 上下翻转概率
fliplr: 0.5
names:
0: Tissue box
其中参数
- path标识了数据集路径,比如我们的项目中肯呢个有多个数据集
- train标识了训练图片的位置
- val标识了验证图片的位置
- mosaic指的是使用马赛克数据增强,具体在训练中的体现是将4 张训练图像拼接成一张大图,作为一次输入送入网络进行训练。- 模型在一张图上看到更多场景和目标组合,增加了背景多样性
- mixup同样也是属于数据增强,具体的体现是将 两张图像按权重线性混合,生成一张新的"虚拟"训练图像。
- 其他几个参数也是用于在小数据集中为了防止过拟合增加图像的复杂度
3.开始训练和验证
python
from ultralytics import YOLO
CONFIG = {
'data' : 'datasets/boxing/dataset.yaml',
'model' : 'yolov8n.pt',
'epochs': 20,
'imgsz': 640,
'batch': -1,
'device': 0,
'name': 'boxing',
'exist_ok': True,
'lr0': 0.01,
}
def train_model():
print('Training model...')
#加载模型
model = YOLO(CONFIG['model'])
model.train(
data = CONFIG['data'],
epochs = CONFIG['epochs'],
imgsz = CONFIG['imgsz'],
batch = CONFIG['batch'],
device = CONFIG['device'],
name = CONFIG['name'],
lr0 = CONFIG['lr0'],
mosaic = 0.8,
mixup = 0.2
)
print('Training completed.')
return model
def val_model(model):
print('Validating model...')
metrics = model.val()
return metrics
def test_model(model,test_image):
print('Testing model...')
results = model(test_image)
results[0].show()
results[0].save(filename='test_result.jpg')
print('Testing completed.')
def main():
model = train_model()
val_model(model)
test_model(model,test_image='datasets/boxing/images/test/微信图片_20250828122329.jpg')
if __name__ == '__main__':
main()
这里我们先声明了一个常量来定义了模型训练中需要的参数。这里我们指定了模型使用了"yolov8n.pt",首次运行时框架会自动下载这个模型,一般在项目的根目录会出现一个yolov8n.pt的文件。然后我们对其他几个参数做个介绍
- epochs 训练的总轮数。每个epoch代表对整个数据集的一次完整遍历。调整此值会影响训练时长和模型性能。我的数据集非常小,所以设置了一个较小的值
- imgsz 用于训练的目标图像大小。图像被调整为边长等于指定值的正方形
- batch 批次大小,具有三种模式:设置为整数(例如,
batch=16
),自动模式,GPU 内存利用率为 60%(batch=-1
),或具有指定利用率分数的自动模式(batch=0.70
) - device 0 代表指定单个GPU
- name 训练运行的名称。用于在项目文件夹中创建一个子目录,训练日志和输出存储在该子目录中
python
model = YOLO(CONFIG['model'])
model.train(
data = CONFIG['data'],
epochs = CONFIG['epochs'],
imgsz = CONFIG['imgsz'],
batch = CONFIG['batch'],
device = CONFIG['device'],
name = CONFIG['name'],
lr0 = CONFIG['lr0'],
mosaic = 0.8,
mixup = 0.2
)
通过两行代码即可完成训练,第一步加载模型,第二步开始训练
这里我们可以看到有输出一些日志,日志大概会经历一下过程 首先打印了模型所使用的参数
txt
Ultralytics 8.3.186 Python-3.11.13 torch-2.6.0+cu126 CUDA:0 (NVIDIA GeForce RTX 4060, 8188MiB)
engine\trainer: agnostic_nms=False, amp=True, augment=False, auto_augment=randaugment, batch=-1, 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=datasets/boxing/dataset.yaml, degrees=0.0, deterministic=True, device=0, dfl=1.5, dnn=False, dropout=0.0, dynamic=False, embed=None, epochs=10, 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.2, mode=train, model=yolov8n.pt, momentum=0.937, mosaic=0.8, multi_scale=False, name=boxing4, nbs=64, nms=False, opset=None, optimize=False, optimizer=auto, overlap_mask=True, patience=100, perspective=0.0, plots=True, pose=12.0, pretrained=True, profile=False, project=None, rect=False, resume=False, retina_masks=False, save=True, save_conf=False, save_crop=False, save_dir=runs\detect\boxing4, 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=8, workspace=None
Overriding model.yaml nc=80 with nc=1
然后加载训练集的数据
txt
Transferred 319/355 items from pretrained weights
Freezing layer 'model.22.dfl.conv.weight'
AMP: running Automatic Mixed Precision (AMP) checks...
AMP: checks passed
train: Fast image access (ping: 0.10.0 ms, read: 2580.4884.8 MB/s, size: 938.8 KB)
train: Scanning G:\Personal\智能零售\yolo\datasets\boxing\labels\train.cache... 14 images, 0 backgrounds, 0 corrupt: 100% ━━━━━━━━━━━━ 14/14 0.0s
train: G:\Personal\\yolo\datasets\boxing\images\train\04584b67__e261c101-%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20250828144509.jpg: corrupt JPEG restored and saved
train: G:\Personal\\yolo\datasets\boxing\images\train\1692c175__228f9682-%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_202508281445095.jpg: corrupt JPEG restored and saved
train: G:\Personal\\yolo\datasets\boxing\images\train\1dbe9524__1c51d3d3-%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20250828144508.jpg: corrupt JPEG restored and saved
train: G:\Personal\\yolo\datasets\boxing\images\train\77e7630e__5ccc8767-%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_202508281445092.jpg: corrupt JPEG restored and saved
train: G:\Personal\\yolo\datasets\boxing\images\train\8ae9f90a__5de81dc2-%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20250828132718.jpg: corrupt JPEG restored and saved
train: G:\Personal\\yolo\datasets\boxing\images\train\9aed3697__44aaa78b-%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20250828144447.jpg: corrupt JPEG restored and saved
train: G:\Personal\\yolo\datasets\boxing\images\train\a3fbc99b__fcf8750d-%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20250828134930.jpg: corrupt JPEG restored and saved
train: G:\Personal\\yolo\datasets\boxing\images\train\bba171f6__5697ba4c-%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20250828122329.jpg: corrupt JPEG restored and saved
train: G:\Personal\\yolo\datasets\boxing\images\train\c34187c9__02c69289-%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20250828144510.jpg: corrupt JPEG restored and saved
train: G:\Personal\\yolo\datasets\boxing\images\train\e391b2d3__048eabe1-%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_202508281445096.jpg: corrupt JPEG restored and saved
train: G:\Personal\\yolo\datasets\boxing\images\train\ec26e83e__80d420a0-%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_202508281445094.jpg: corrupt JPEG restored and saved
AutoBatch: Computing optimal batch size for imgsz=640 at 60.0% CUDA memory utilization.
AutoBatch: CUDA:0 (NVIDIA GeForce RTX 4060) 8.00G total, 0.10G reserved, 0.06G allocated, 7.83G free
开始对模型进行训练,可以看到最后输出了模型训练的pt文件,并且告诉了我们训练过程的可视化结果的保存路径
txt
optimizer: AdamW(lr=0.002, momentum=0.9) with parameter groups 57 weight(decay=0.0), 64 weight(decay=0.00053125), 63 bias(decay=0.0)
Image sizes 640 train, 640 val
Using 8 dataloader workers
Logging results to runs\detect\boxing4
Starting training for 10 epochs...
Closing dataloader mosaic
Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size
1/10 1.77G 1.732 3.44 1.523 33 640: 100% ━━━━━━━━━━━━ 1/1 1.8it/s 0.5s
Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 1/1 9.4it/s 0.1s
all 2 6 0.01 1 0.03 0.0108
Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size
2/10 1.77G 1.799 3.402 1.651 32 640: 100% ━━━━━━━━━━━━ 1/1 7.7it/s 0.1s
Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 1/1 18.3it/s 0.1s
all 2 6 0.01 1 0.0299 0.011
...
10 epochs completed in 0.006 hours.
Optimizer stripped from runs\detect\boxing4\weights\last.pt, 6.2MB
Optimizer stripped from runs\detect\boxing4\weights\best.pt, 6.2MB
Validating runs\detect\boxing4\weights\best.pt...
Ultralytics 8.3.186 Python-3.11.13 torch-2.6.0+cu126 CUDA:0 (NVIDIA GeForce RTX 4060, 8188MiB)
Model summary (fused): 72 layers, 3,005,843 parameters, 0 gradients, 8.1 GFLOPs
Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 1/1 58.2it/s 0.0s
all 2 6 0.01 1 0.0323 0.0141
Speed: 0.5ms preprocess, 5.1ms inference, 0.0ms loss, 1.6ms postprocess per image
Results saved to runs\detect\boxing4
Training completed.
然后我们执行了
python
def val_model(model):
print('Validating model...')
metrics = model.val()
return metrics
模型开始对验证数据集进行了验证,会看到以下的日志输出,可以看到验证可视化输出的结果
txt
Validating model...
Ultralytics 8.3.186 Python-3.11.13 torch-2.6.0+cu126 CUDA:0 (NVIDIA GeForce RTX 4060, 8188MiB)
Model summary (fused): 72 layers, 3,005,843 parameters, 0 gradients, 8.1 GFLOPs
val: Fast image access (ping: 0.10.0 ms, read: 2277.7136.5 MB/s, size: 1029.1 KB)
val: Scanning G:\Personal\智能零售\yolo\datasets\boxing\labels\val.cache... 2 images, 0 backgrounds, 0 corrupt: 100% ━━━━━━━━━━━━ 2/2 1842.0it/s 0.0s
val: G:\Personal\\yolo\datasets\boxing\images\val\431e150e__3197926a-%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_202508281445091.jpg: corrupt JPEG restored and saved
val: G:\Personal\\yolo\datasets\boxing\images\val\444deb1d__0a394335-%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_202508281445093.jpg: corrupt JPEG restored and saved
Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 1/1 0.70it/s 1.4s
all 2 6 0.01 1 0.032 0.014
Speed: 0.8ms preprocess, 30.5ms inference, 0.0ms loss, 2.2ms postprocess per image
Results saved to runs\detect\boxing42
测试模型
我们现在可以通过YOLO来加载我们自己的模型对我们的测试图片进行目标检测
python
model = YOLO('runs/detect/boxing/weights/best.pt')
results = model('datasets/boxing/images/test/微信图片_20250828163243.jpg')
results[0].show()
可以看到还是检测出了目标,当然有些遮挡的目标没有识别出来我觉得可能是数据集太少的缘故

然后我们可以选择进行导出模型用于我们的部署
python
from ultralytics import YOLO
def export_model(path):
model = YOLO(path)
model.export(
format="onnx",
imgsz=640,
dynamic=False,
simplify=True,
opset=12
)
if __name__ == '__main__':
path = 'runs/detect/boxing/weights/best.pt'
export_model(path)
运行该脚本可以将之前的模型参数保存成一个onnx文件
总结:从数据到模型,我们走通了第一步
在本篇中,我们完整实现了使用自定义数据训练 YOLOv8 检测模型的核心流程:
- ✅ 数据准备 :将上一篇标注的数据整理为标准目录结构,编写
data.yaml
配置文件; - ✅ 模型训练 :基于
yolov8n
轻量模型,启用 Mosaic、MixUp 等增强策略,在小数据集上高效训练; - ✅ 验证与测试:通过 mAP、Precision、Recall 等指标评估模型性能,可视化检测结果;
- ✅ 模型导出 :将训练好的模型导出为
.pt
或ONNX
格式,为后续部署做好准备。
至此,我们不仅拥有了一个"看得懂"图片中目标的智能模型,更重要的是,走通了目标检测项目从数据到模型输出的完整闭环。这为后续的实际应用打下了坚实基础。
但这还只是开始------模型的价值,不在于它能否在本地跑通,而在于它能否被集成、被调用、被用起来。
🔮 下一篇预告:《YOLO 入门实战(三):用 FastAPI 构建模型推理服务》