Open images v6 + Yolov5 轻松获取数据并做2D目标检测

2 篇文章 0 订阅
1 篇文章 0 订阅

记录一下从数据获取到做出符合需求的2d检测模型的全过程,记录一共分为四个章节.其中

fiftyone

简介

fiftyone是一款用于构建高质量数据集和计算机视觉模型的开源工具.这款工具不仅仅可以用来加载数据,还能用来评估模型性能,查找注释错误等等
想要了解更多关于fiftyone可以点击这里

安装

创建一个虚拟环境并安装 fiftyone

mkdir Fiftyone_Yolov5
cd Fiftyone_Yolov5
conda create -n Fiftyone_Yolov5 python=3.8
conda activate  Fiftyone_Yolov5
conda install jupyter notebook 
pip install fiftyone  # 安装数据集的API 

选择需要下载的数据集

首先导入 fiftyone 中的数据zoo。

import fiftyone as fo
import fiftyone.zoo as foz
help(foz)

需要根据你需要的实际需求设置数据的下载参数。

dataset = foz.load_zoo_dataset(
        "open-images-v6",
        split="train",
        classes=["Table","Human hand","Human head","Person"],
        max_samples=100000,
        shuffle=True,
        only_matching=True,  
        label_types=["detections"],  # 指定下载目标检测的类型,detections,
        dataset_dir="./OpenImageV6_20220921",# 保存的路径
        num_workers=4,  # 指定工作进程数
)

foz.load_zoo_dataset 参数简介

  1. 填写你需要数据集的名称(字符串类型)
  2. split 指定要加载的分段。支持的值是’ (“train”, “test”, “validation”) '(字符串类型)
  3. classes 选择你需要的检测的对象的类别。(字符串或list类型)
    NOTE: 类别字符串一定要与数据集的类别名称一致,如果不确定可以自行百度或者google一下数据集的类别。注意大小写。
  4. max_samples 要加载的样本的最大数量。(int类型)
  5. only_matching 是否只加载与您提供的’ classes ‘或’ attrs '需求匹配的标签(True),还是加载与需求匹配的样本的所有标签(False)
  6. num_workers 使用的进程数,默认使用multiprocessing.cpu_count()返回的cpu数量
  7. shuffle 是否打乱下载数据的顺序
  8. include_id 是否加载标签中包含某个样本的标签
  9. image_ids 指定需要加载的图像的id
  10. seed 随机种子
  11. attrs 指定需要加载的关系属性的字符串或字符串列表。此参数仅适用于“label_type”包含“relationships”的情况。

foz.load_zoo_dataset 参数官方文档

API参数可以参考这个文档进行自定义。

文档右边可以选择你需要的数据集进行下载。往下拉可以看到所有可以选择的参数。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

图片注释格式转换

经过第一章节,我们已经拿到了我们需要的数据集,但是由于注释格式的不同我们无法直接输入yolov5进行使用,这一章节我们通过open images v6 的数据进行演示,如何将OIDv6的数据格式转换成yolo txt的数据格式。
转换分为两步: oidv6格式到voc ; voc 到 yolo txt 。

OIDv6 >> voc

这一步骤使用了这个python工具包–(oidv6-to-voc)

安装 oidv6-to-voc

pip install oidv6-to-voc

使用 oidv6-to-voc 工具进行转换

oidv6-to-voc <annotation-file(s).csv>
             -d <class-names-file.csv> 
             --imgd <directory/to/your/images>
             --outd <your/output/diretory>

其中annotation-file(s).csv 可以在数据保存路径下的labels/文件夹中找到 detections.csv
在这里插入图片描述
class-names-file.csv 可以在下一小节中下载
<directory/to/your/images> 数据集的图片路径
<your/output/diretory> 转换成voc之后的注释保存路径

下载需要的标注文件

点击进入这个网页https://storage.googleapis.com/openimages/web/download.html

在这里插入图片描述
其中 红色框内的表示annotation-file(s).csv文件,open images 将其数据分割成了 train validation test
绿色框内的表示 class-names-file.csv 下载完直接使用即可

NOTE:
其中第1列代表的是open images 的类别id(这个不是给一般人看的),第2列代表的是类别id所对应的英文名字(你可以在其中找一下有没有你需要的类别)

在这里插入图片描述

VOC >> YOLO TXT

使用python实现格式转换

以下代码主要参考了这篇博客
首先导入我们所需要的数据包

import xml.etree.ElementTree as ET
import glob
import os
import json

导入两个函数

def xml_to_yolo_bbox(bbox, w, h):
    # xmin, ymin, xmax, ymax
    x_center = ((bbox[2] + bbox[0]) / 2) / w
    y_center = ((bbox[3] + bbox[1]) / 2) / h
    width = (bbox[2] - bbox[0]) / w
    height = (bbox[3] - bbox[1]) / h
    return [x_center, y_center, width, height]
def yolo_to_xml_bbox(bbox, w, h):
    # x_center, y_center width heigth
    w_half_len = (bbox[2] * w) / 2
    h_half_len = (bbox[3] * h) / 2
    xmin = int((bbox[0] * w) - w_half_len)
    ymin = int((bbox[1] * h) - h_half_len)
    xmax = int((bbox[0] * w) + w_half_len)
    ymax = int((bbox[1] * h) + h_half_len)
    return [xmin, ymin, xmax, ymax]

依次填入类别名称、VOC格式的注释文件所在目录,你想要输出YOLO TXT格式的注释文件所在目录、图片目录

classes = []
input_dir = "annotations/"
output_dir = "labels/"
image_dir = "images/"

if not os.path.isdir(output_dir):
    os.mkdir(output_dir)

这是注释格式转换的主要代码

files = glob.glob(os.path.join(input_dir, '*.xml'))
for fil in files:
    basename = os.path.basename(fil)
    filename = os.path.splitext(basename)[0]
    if not os.path.exists(os.path.join(image_dir, f"{filename}.jpg")):
        print(f"{filename} image does not exist!")
        continue
    files = glob.glob(os.path.join(input_dir, '*.xml'))
    result = []
    tree = ET.parse(fil)
    root = tree.getroot()
    width = int(root.find("size").find("width").text)
    height = int(root.find("size").find("height").text)
    for obj in root.findall('object'):
        label = obj.find("name").text
        if label not in classes:
            classes.append(label)
        index = classes.index(label)
        pil_bbox = [int(x.text) for x in obj.find("bndbox")]
        yolo_bbox = xml_to_yolo_bbox(pil_bbox, width, height)
        bbox_string = " ".join([str(x) for x in yolo_bbox])
        result.append(f"{index} {bbox_string}")
    if result:
        with open(os.path.join(output_dir, f"{filename}.txt"), "w", encoding="utf-8") as f:
            f.write("\n".join(result))

记录一下类别

with open('classes.txt', 'w', encoding='utf8') as f:
    f.write(json.dumps(classes))

Yolov5的训练

yolov5 训练前的准备工作

下载yolov5项目代码并安装需要的运行环境(最好在虚拟环境下运行)

git clone https://github.com/ultralytics/yolov5  # clone
cd yolov5
pip install -r requirements.txt  # install

移动数据集到指定位置

在yolov5的目录下创建一个datasets文件夹用以装载训练和测试数据
在这里插入图片描述
其中 images 装载图片训练和验证的数据分别装在train和val文件夹下
labels同理装载注释数据的txt文件

修改model的配置文件(yaml)

在data目录下创建一个关于自己数据的yaml文件 比如customerData.yaml

train: ./datasets/images/train  # 在这里写上训练路径 
val: ./datasets/images/val      # 在这里写上测试路径

nc: 3 # 写上你的种类数量

names: ["car","person","human face"]

修改data的配置文件(yaml)

进入models文件夹 选择你想要的yolov5模型,我们以yolov5l.yaml 为例,将文件中的nc: 80 改为你的类别数目。比如 如果你需要检测car、person、cycline三类 就写一个3。

# YOLOv5 🚀 by Ultralytics, GPL-3.0 license

# Parameters
nc: 80  # number of classes
depth_multiple: 1.0  # model depth multiple
width_multiple: 1.0  # layer channel multiple
anchors:
  - [10,13, 16,30, 33,23]  # P3/8
  - [30,61, 62,45, 59,119]  # P4/16
  - [116,90, 156,198, 373,326]  # P5/32

# YOLOv5 v6.0 backbone
backbone:
  # [from, number, module, args]
  [[-1, 1, Conv, [64, 6, 2, 2]],  # 0-P1/2
   [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4
   [-1, 3, C3, [128]],
   [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
   [-1, 6, C3, [256]],
   [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
   [-1, 9, C3, [512]],
   [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
   [-1, 3, C3, [1024]],
   [-1, 1, SPPF, [1024, 5]],  # 9
  ]

# YOLOv5 v6.0 head
head:
  [[-1, 1, Conv, [512, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 6], 1, Concat, [1]],  # cat backbone P4
   [-1, 3, C3, [512, False]],  # 13

   [-1, 1, Conv, [256, 1, 1]],
   [-1, 1, nn.Upsample, [None, 2, 'nearest']],
   [[-1, 4], 1, Concat, [1]],  # cat backbone P3
   [-1, 3, C3, [256, False]],  # 17 (P3/8-small)

   [-1, 1, Conv, [256, 3, 2]],
   [[-1, 14], 1, Concat, [1]],  # cat head P4
   [-1, 3, C3, [512, False]],  # 20 (P4/16-medium)

   [-1, 1, Conv, [512, 3, 2]],
   [[-1, 10], 1, Concat, [1]],  # cat head P5
   [-1, 3, C3, [1024, False]],  # 23 (P5/32-large)

   [[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
  ]

yolov5 的训练参数

改好之后就可以开始训练了

python3 train.py --img-size 640 \  # 图片的size大小 需要注意的是必须要是32的倍数,常用的有640 1280 1440
--batch-size 16 \  
--epochs 300 \
--data ./data/customerData.yaml \  # 数据配置文件
--cfg ./models/yolov5l.yaml \      # 模型配置文件
--weights weights/yolov5l.pt \ # yolo 会自动下载不用管
--device 0,1 # 使用电脑的GPU下标
其他可选参数简介:
  1. –evolve {num} 使用yolo自带的进化算法调整模型超参数(num为训练的代数3)
  2. –multi-scale 随机调整 imgsz的大小 调整范围为 “±50%”
  3. –workers {num} 多进程设置(num 为需要设定的进程数)
  4. –cache 将数据提前加载到内存
  5. –hyp xxx.yaml 手动调整模型和数据增强的超参数
  6. –optimizer 模型优化器选择,默认 SGD,可从这三个里面进行选择[‘SGD’, ‘Adam’, ‘AdamW’]
  7. –image-weights 测试过程中,图像的那些测试地方不太好,对这些不太好的地方加权重

可参考一下链接,如果有参数名称找不到,需要自行查看一下train.py文件中的keyword ,名字可能有所改动。(列如:–cache-images 更改为了 --cache)

NOTE: 当使用 --multi-scale 参数时 需要预留足够的GPU显存,不然会导致GPU内存溢出。

yolov5 训练经验记录

数据增强超参数调整:

# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
# Hyperparameters for high-augmentation COCO training from scratch
# python train.py --batch 32 --cfg yolov5m6.yaml --weights '' --data coco.yaml --img 1280 --epochs 300
# See tutorials for hyperparameter evolution https://github.com/ultralytics/yolov5#tutorials

lr0: 0.01  # initial learning rate (SGD=1E-2, Adam=1E-3)
lrf: 0.1  # final OneCycleLR learning rate (lr0 * lrf)
momentum: 0.937  # SGD momentum/Adam beta1
weight_decay: 0.0005  # optimizer weight decay 5e-4
warmup_epochs: 3.0  # warmup epochs (fractions ok)
warmup_momentum: 0.8  # warmup initial momentum
warmup_bias_lr: 0.1  # warmup initial bias lr
box: 0.05  # box loss gain
cls: 0.3  # cls loss gain
cls_pw: 1.0  # cls BCELoss positive_weight
obj: 0.7  # obj loss gain (scale with pixels)
obj_pw: 1.0  # obj BCELoss positive_weight
iou_t: 0.20  # IoU training threshold
anchor_t: 4.0  # anchor-multiple threshold
# anchors: 3  # anchors per output layer (0 to ignore)
fl_gamma: 0.0  # focal loss gamma (efficientDet default gamma=1.5)
hsv_h: 0.015  # image HSV-Hue augmentation (fraction)
hsv_s: 0.7  # image HSV-Saturation augmentation (fraction)
hsv_v: 0.4  # image HSV-Value augmentation (fraction)
degrees: 90.0  # image rotation (+/- deg)
translate: 0.1  # image translation (+/- fraction)
scale: 0.9  # image scale (+/- gain)
shear: 0.5  # image shear (+/- deg)
perspective: 0.0  # image perspective (+/- fraction), range 0-0.001
flipud: 0.2  # image flip up-down (probability)
fliplr: 0.5  # image flip left-right (probability)
mosaic: 1.0  # image mosaic (probability)
mixup: 0.3  # image mixup (probability)
copy_paste: 0.1  # segment copy-paste (probability)

数据集中出现图片注释不完善

这个问题应该是open image 这个数据集特有的,暂时没在其他数据集上发现。
问题如下,比如我需要检测 人脸 人眉毛和人这三类。但是有些图片中明明有人脸和人的眉毛,数据集却并没有该类的标记,而是仅仅只标记了人出来,这就会导致模型在训练的时候,明明图片中有一个人的眉毛并且模型可以将其识别出来,但是由于没有这个注释导致进行loss计算的正确答案是背景类(而不是眉毛类)。因此噪音多了就会让模型无法学习到真正的眉毛。

其他

yolov5 的模型检测命令

python detect.py --source 
                 --weights
                 --imgsz 1280 
                 --conf-thres 0.05 
                 --iou-thres 0.05
                 --data ./data/customerData.yaml
                 --save-txt
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,下面我将为你详细介绍如何在 Django 中配置 YOLOv5 模型进行目标检测。 1. 安装必要的 Python 库 首先,你需要安装必要的 Python 库,包括 Django、PyTorch 和 torchvision。你可以使用 pip 命令来安装它们: ``` pip install django torch torchvision ``` 2. 下载 YOLOv5 的代码和权重文件 你可以从 YOLOv5 的官方 GitHub 仓库中下载代码和权重文件:https://github.com/ultralytics/yolov5 你可以将下载的代码和权重文件放在 Django 项目的某个目录下。在本例中,我们将它们放在项目根目录下的 `yolov5` 目录中。 3. 创建 Django 视图函数 在 Django 项目中创建一个视图函数来处理目标检测请求。以下是一个可以帮助你开始编写代码的示例: ```python import torch import torchvision.transforms as transforms from PIL import Image from django.http import JsonResponse from yolov5.models.experimental import attempt_load from yolov5.utils.general import non_max_suppression def detect(request): # 加载模型 weights = 'yolov5/weights/yolov5s.pt' device = torch.device('cpu') model = attempt_load(weights, map_location=device) model.eval() # 处理图像 image = request.FILES.get('image') img = Image.open(image) img_tensor = transforms.ToTensor()(img) # 进行推理 with torch.no_grad(): results = model([img_tensor])[0] results = non_max_suppression(results, 0.5, 0.5) # 处理结果 detections = [] for result in results: for detection in result: detections.append({ 'label': detection[-1], 'confidence': detection[-2], 'bbox': detection[:4].tolist(), }) # 返回结果 return JsonResponse({'detections': detections}) ``` 在上面的代码中,我们首先加载 YOLOv5 模型和权重,然后获取传递给视图函数的图像。接下来,我们将图像转换为 PyTorch 张量,并将其传递给模型进行推理。最后,我们将检测结果处理为 JSON 格式,并将其返回给客户端。 4. 配置 Django 路由 最后,你需要在 Django 项目中配置路由来将请求路由到上述视图函数。以下是一个示例路由配置: ```python from django.urls import path from . import views urlpatterns = [ path('detect/', views.detect, name='detect'), ] ``` 在上面的代码中,我们将 `/detect/` 路径映射到名为 `detect` 的视图函数。 5. 运行 Django 项目并进行测试 现在,你可以运行 Django 项目并通过发送图像文件的 POST 请求来测试目标检测功能。你可以使用 Postman 等工具来测试,也可以编写一个简单的 HTML 表单来测试。 以下是一个 HTML 表单示例: ```html <html> <body> <form method="POST" enctype="multipart/form-data" action="http://localhost:8000/detect/"> {% csrf_token %} <input type="file" name="image"> <button type="submit">提交</button> </form> </body> </html> ``` 在上面的代码中,我们创建了一个包含文件选择器和提交按钮的 HTML 表单,并将其提交到 `/detect/` 路径。你需要将 `action` 属性设置为你的 Django 项目的 URL。 当你提交表单后,Django 项目将会返回 JSON 格式的检测结果。你可以根据需要对其进行处理和显示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值