yolov8f1曲线的意义
YOLOv8F1曲线,全称为You Only Look Once版本8的F1 Score曲线,它是在YOLOv8(一种目标检测算法)中用于评估模型性能的标准工具之一。F1分数是精确率(Precision)和召回率(Recall)的调和平均值,通常用于衡量模型在检测目标时的准确性和完整性。
- 精确率 (Precision):指模型预测为正样本的实例中,实际为正样本的比例。
- 召回率 (Recall):指所有实际为正样本的实例中,模型能正确识别出的比例。
F1曲线展示了随着模型阈值的变化,精确率和召回率是如何变化的。一条理想的F1曲线应该尽可能接近顶部,左上角(高精度和高召回),这表明模型既能减少误报(False Positives),又能提高查准率(True Positives)。而F1分数越高,表示模型整体性能越好。
YOLOv8画PR曲线
使用 YOLOv8 绘制 PR 曲线
为了绘制 YOLOv8 模型的 Precision-Recall (PR) 曲线,通常需要评估模型在不同置信度阈值下的性能。这涉及计算每个类别的精确率和召回率,并将其绘制成图。
以下是具体实现方法:
准备工作
确保已经安装了必要的库并加载训练好的 YOLOv8 模型。如果使用的是自定义数据集,则需提前准备好测试集用于验证模型效果[^1]。
from ultralytics import YOLO
import matplotlib.pyplot as plt
import numpy as np
加载预训练模型
这里假设已有一个名为 yolov8_custom.pt
的本地权重文件。
model = YOLO('path/to/yolov8_custom.pt')
定义辅助函数来获取预测结果以及真实标签信息
此部分代码会遍历整个测试集,收集所有目标框的位置、类别ID及其对应的得分。
def get_predictions_and_ground_truths(model, dataloader):
predictions = []
ground_truths = []
model.eval()
with torch.no_grad():
for images, targets in dataloader:
outputs = model(images)
batch_size = len(targets)
for i in range(batch_size):
pred_boxes = outputs[i]['boxes'].cpu().numpy() # 预测边界框坐标
scores = outputs[i]['scores'].cpu().numpy() # 对应分数
gt_boxes = targets[i]['boxes'].cpu().numpy() # 实际边界框坐标
labels = targets[i]['labels'].cpu().numpy() # 类别编号
preds_per_image = [(pred_box.tolist(), score.item())
for pred_box, score in zip(pred_boxes, scores)]
gts_per_image = [{'box': box.tolist(),
'label': label}
for box,label in zip(gt_boxes, labels)]
predictions.append(preds_per_image)
ground_truths.append(gts_per_image)
return predictions, ground_truths
计算AP(Average Precision)
对于每一个类别分别计算其平均精度(AP),最终汇总得到mAP(mean Average Precision).
from pycocotools.coco import COCO
from pycocotools.cocoeval import COCOeval
cocoGt=COCO(annotation_file='annotations.json') # 测试集标注路径
results_dict = {'images':[],'type':'instances','annotations':[]}
for idx,(img_id,preds) in enumerate(zip(image_ids, all_preds)):
img_info=cocoGt.loadImgs([int(img_id)])
width,height=img_info[0]["width"],img_info[0]["height"]
result_img={'id':idx,'file_name':str(idx)+'.jpg'}
results_dict['images'].append(result_img)
for bbox,score in preds:
x,y,w,h=bbox
annotation={
"image_id": int(img_id),
"category_id": category,
"bbox":[float(x), float(y), float(w-x), float(h-y)],
"score": float(score)}
results_dict["annotations"].append(annotation)
json.dump(results_dict, open('result.json', 'w'))
cocoDt=cocoGt.loadRes('result.json')
cocoeval = COCOeval(cocoGt,cocoDt,"bbox")
cocoeval.evaluate()
cocoeval.accumulate()
cocoeval.summarize()
aps = cocoeval.stats[:5].tolist()[1:] # 取出各个类别的 AP 值
print(f"Per-class average precisions: {aps}")
绘制 PR 曲线
最后一步就是利用上述获得的数据画出每种类别的 PR 图像。
plt.figure(figsize=(10,7))
colors=['b','g','r','c','m']
for cls_idx,color in zip(range(len(aps)), colors):
precision_recall_curve = compute_precision_recall_for_class(cls_idx)
pr_x,pr_y=precision_recall_curve
plt.plot(pr_x, pr_y, color=color, lw=2, label=f'class{cls_idx}: ap={round(aps[cls_idx],3)}')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.title('Precision Recall Curve of Different Classes')
plt.legend(loc="lower left")
plt.show()
yolov8训练损失曲线
YOLOv8 训练过程中损失曲线分析
在YOLOv8训练期间,监控损失函数的变化对于理解模型的学习行为至关重要。通过观察损失曲线可以判断是否存在过拟合、欠拟合等问题,并据此调整超参数。
使用TensorBoard可视化损失曲线
为了方便地查看YOLOv8的训练日志并绘制损失曲线,推荐使用TensorBoard
工具。当启动YOLOv8训练时,默认情况下会自动记录必要的统计数据到指定的日志目录下[^1]:
tensorboard --logdir runs/train/
上述命令将在浏览器中打开一个交互式的界面,在该界面上能够直观看到不同阶段下的loss变化趋势图以及其他重要指标图表。
分析损失曲线特征
平稳下降:理想状态下,随着迭代次数增加,总损失应该逐渐减小直至收敛于某个较低水平。
波动较大:如果发现损失值上下起伏不定,则可能意味着学习率设置过高或数据集中存在异常样本影响了梯度更新稳定性。
停滞不前:当经过多个epoch之后仍然无法有效降低初始较高的平均误差时,这表明当前架构难以捕捉目标对象特征或者正则化强度不足导致泛化能力差。
针对以上几种常见现象,可以通过调节如下几个方面来优化性能表现:
- 调整学习速率(
lr0
)大小; - 增加/减少批量尺寸(batch size);
- 修改最大轮次数(epochs),给予更充分的时间让网络权重趋于稳定状态;
- 尝试其他预处理方法改善输入质量,比如增强图像变换多样性等措施提升鲁棒性和抗干扰特性。
import matplotlib.pyplot as plt
def plot_loss_curve(log_file_path):
with open(log_file_path, 'r') as f:
lines = f.readlines()
losses = []
for line in lines:
if "train_batch_iou:" not in line and \
"val_batch_iou:" not in line and \
"total_loss:" in line:
loss_value = float(line.split(' ')[-1].strip())
losses.append(loss_value)
plt.figure(figsize=(10, 6))
plt.plot(range(len(losses)), losses, label='Training Loss')
plt.title('Loss Curve During Training Process')
plt.xlabel('Iteration Steps')
plt.ylabel('Total Loss Value')
plt.legend()
plt.show()
plot_loss_curve('./runs/train/exp/results.txt')
相关推荐
















