Datawhale AI夏令营 第五期 CV方向 Task1笔记

Task1:跑通YOLO方案baseline!

赛题解读

根据您提供的图片内容,这是一份关于城市管理违规行为智能识别竞赛的赛题描述。以下是对内容的分析:

一、赛题描述

  • 背景:随着城市化进程的加速,城市管理面临新的挑战和机遇。城市管理的精细化和智能化是全球城市发展的关键。
  • 问题:城市违规行为如机动车违停、非机动车违停、占道经营等,对城市的美学、秩序和公众福祉构成威胁。
  • 传统挑战:传统的人力巡查和被动响应模式已不适应现代城市治理的需求。

二、赛题题目

  • 题目:城市管理违规行为智能识别。

三、赛题任务

  • 初赛任务:使用给定的城管视频监控数据集,检测城市违规行为。
  • 违规行为类型:包括垃圾桶满溢、机动车违停、非机动车违停等。
  • 任务要求:选手需要分析视频,标记违规行为,并提供违规行为发生的时间与位置信息。

分析

  • 技术需求:竞赛要求选手开发一套智能识别系统,利用图像处理和计算机视觉技术,自动检测和分类城市管理中的违规行为。
  • 目标:提高城市管理的效率,通过自动化系统减少对人工巡查的依赖,实现更快速的违规行为识别和响应。
  • 挑战:开发能够准确识别多种违规行为的算法,同时提供违规行为的详细信息,如时间和位置。

总结

这份赛题描述为参赛者提供了一个明确的研究方向和目标,即开发一个能够自动检测城市管理中违规行为的智能系统。这不仅有助于提升城市管理的智能化水平,也为参赛者提供了展示其技术能力的平台。参赛者需要具备图像处理和计算机视觉方面的知识,以及算法开发和数据分析的能力。

baseline解读

# 读取训练集视频
for anno_path, video_path in zip(train_annos[:5], train_videos[:5]):
    print(video_path)
    anno_df = pd.read_json(anno_path)
    cap = cv2.VideoCapture(video_path)
    frame_idx = 0 
    # 读取视频所有画面
    while True:
        ret, frame = cap.read()
        if not ret:
            break

        img_height, img_width = frame.shape[:2]
        
        # 将画面写为图
        frame_anno = anno_df[anno_df['frame_id'] == frame_idx]
        cv2.imwrite('./yolo-dataset/train/' + anno_path.split('/')[-1][:-5] + '_' + str(frame_idx) + '.jpg', frame)

        # 如果存在标注
        if len(frame_anno) != 0:
            with open('./yolo-dataset/train/' + anno_path.split('/')[-1][:-5] + '_' + str(frame_idx) + '.txt', 'w') as up:
                for category, bbox in zip(frame_anno['category'].values, frame_anno['bbox'].values):
                    category_idx = category_labels.index(category)
                    
                    # 计算yolo标注格式
                    x_min, y_min, x_max, y_max = bbox
                    x_center = (x_min + x_max) / 2 / img_width
                    y_center = (y_min + y_max) / 2 / img_height
                    width = (x_max - x_min) / img_width
                    height = (y_max - y_min) / img_height

                    if x_center > 1:
                        print(bbox)
                    up.write(f'{category_idx} {x_center} {y_center} {width} {height}\n')
        
        frame_idx += 1

这段代码实现了以下功能:

视频帧提取:代码通过OpenCV库读取视频文件,逐帧提取视频内容。

数据处理:使用Pandas库读取JSON格式的注释文件,这些注释包含了违规行为的类别和边界框信息。

YOLO格式转换:对于每一帧图像,如果存在对应的注释信息,代码会将边界框的位置从原始像素坐标转换为YOLO模型所需的归一化坐标。

注释文件生成:将转换后的注释信息写入到文本文件中,每个边界框的信息包括类别索引和归一化后的坐标。

整体来看,这段代码将原始视频和标注转换为适合YOLO模型训练的格式。

import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0"

import warnings
warnings.filterwarnings('ignore')

from ultralytics import YOLO
model = YOLO("yolov8n.pt")
results = model.train(data="yolo-dataset/yolo.yaml", epochs=10, imgsz=1080, batch=16, lr0=0.01, lrf=0.001, cos_lr=True)

这段代码先做了一些警告忽视处理。随后利用ultralytics 加载YOLOv8n的模型进行训练。

其中包含了多个参数,每个参数都有特定的作用:

  1. data="yolo-dataset/yolo.yaml":指定了数据集配置文件的路径。这个YAML文件包含了训练和验证数据集的详细信息,如图像路径、类别定义等。

  2. epochs=10:设置训练的周期数,即整个数据集遍历10次。每个epoch代表模型在整个训练数据集上训练一次。

  3. imgsz=1080:设置输入图像的尺寸。这里设置为1080,即模型将接受宽度和高度为1080像素的图像。

  4. batch=16:设置每个训练批次中的图像数量。这里设置为16,表示每次迭代将处理16张图像。

  5. lr0=0.01:设置初始学习率。学习率是控制模型权重更新幅度的超参数,这里设置为0.01。

  6. lrf=0.001:设置学习率的最终值。使用动态学习率调整策略,用于调整学习率。

  7. cos_lr=True:启用余弦退火学习率调度器。这是一种学习率调整策略,它根据余弦函数的变化来调整学习率,通常用于在训练过程中逐渐减小学习率。

这些参数共同定义了模型训练的配置,包括数据集、训练周期、图像尺寸、批次大小、学习率及其调整策略。通过调整这些参数,可以优化模型的训练过程,提高模型的性能和准确性。

from ultralytics import YOLO
model = YOLO("runs/detect/train/weights/best.pt")
import glob

for path in glob.glob('测试集/*.mp4'):
    submit_json = []
    results = model(path, conf=0.05, imgsz=1080,  verbose=False, stream=True)
    for idx, result in enumerate(results):
        boxes = result.boxes  # Boxes object for bounding box outputs
        masks = result.masks  # Masks object for segmentation masks outputs
        keypoints = result.keypoints  # Keypoints object for pose outputs
        probs = result.probs  # Probs object for classification outputs
        obb = result.obb  # Oriented boxes object for OBB outputs

        if len(boxes.cls) == 0:
            continue

        xywh = boxes.xyxy.data.cpu().numpy().round()
        cls = boxes.cls.data.cpu().numpy().round()
        conf = boxes.conf.data.cpu().numpy()
        for i, (ci, xy, confi) in enumerate(zip(cls, xywh, conf)):
            submit_json.append(
                {
                    'frame_id': idx,
                    'event_id': i+1,
                    'category': category_labels[int(ci)],
                    'bbox': list([int(x) for x in xy]),
                    "confidence": float(confi)
                }
            )

    with open('./result/' + path.split('/')[-1][:-4] + '.json', 'w', encoding='utf-8') as up:
        json.dump(submit_json, up, indent=4, ensure_ascii=False)

这段代码首先是加载上次训练中得到的最佳模型,利用模型对测试集中的视频取帧进行预测,并写成json文件格式写入result文件夹中。

baseline的修改

对于原本baseline的数据加载部分中,只是选择了少量数据进行训练,通过加载大量数据可以有效提升模型的泛化能力,从而提升模型性能。

这里由于云机器的磁盘内存不足,只是挑选了部分数据进行训练。

# for anno_path, video_path in zip(train_annos[:5], train_videos[:5]):
for anno_path, video_path in zip(train_annos[::2], train_videos[::2]):
    print(video_path)
    anno_df = pd.read_json(anno_path)
    cap = cv2.VideoCapture(video_path)
    frame_idx = 0 
    while True:
        ret, frame = cap.read()
        if not ret:
            break
······

对于验证集的数据也能进行如此操作,只需要避免与训练集数据有重复即可。

如:for anno_path, video_path in zip(train_annos[1::8], train_videos[1::8])

同时,baseline原本代码中会出现有大量警告提示,只需增改这部分代码即可:

随后便可进行模型的训练,本次训练我使用了两个不同大小模型(YOLOv8n/s)进行训练,此处对比这两个模型的训练:

YOLOv8n

从数据中可以看出,box_losscls_loss在训练过程中逐渐减小,这表明模型在训练过程中逐渐学习并改善了预测的准确性。

精度和mAP50在训练过程中有所波动,但整体趋势是向上的,表明模型在识别目标方面变得更加准确。mAP50-95提供了一个更全面的模型性能视图,它考虑了不同置信度阈值下的模型性能。

召回率指标显示了模型能够识别出多少比例的实际正类样本。召回率的增加表明模型漏检的情况在减少。

YOLOv8s

边界框损失和分类损失在训练过程中逐渐减小,这通常表示模型在学习和改进其预测的准确性。同时边界框损失的数值相对较大,这可能意味着边界框预测的准确性还有改进空间。

精度和mAP50在训练过程中有所波动,但整体趋势是向上的,这表明模型的性能在提高。召回率的数值相对较低,这可能意味着模型在检测所有实际目标方面存在一定的困难。

在两者的最佳模型进行预测后提交的分数中,YOLOv8n(0.190)的评分是稍大于YOLOV8s(0.159)的,或许是模型太大出现了过拟合的情况,这就更需要对训练数据集的增加了。

问题与思考

在我随机筛选的数据集中出现了极大的问题:

如图所示,训练集的数据在各个标签的分布及其不均,虽然这也与原本所有数据的标签分布也不均有关,但随机筛选的情况有可能加大这样的不均,甚至在验证集中 ‘违法经营’ 一个都没有(如下图),这会极大地影响到最佳模型的评判。

这就需要在接下来的任务中有主观地去筛选数据集,尽可能将所有标签总数较少的数据都用上。

  • 18
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值