深度学习-yolo-fastestV2使用自己的数据集训练自己的模型

这篇具有很好参考价值的文章主要介绍了深度学习-yolo-fastestV2使用自己的数据集训练自己的模型。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

虽然说yolo-fastestV2在coco数据集上map只达到了24.1,但是应付一些类别少的问题还是可以的。主要是这个速度是真的香!简单来说就是一个快到飞起的模型。

1.关于yolo-fastestV2

github地址如下:yolo-fastestV2
yolo-fastestV2采用了轻量化网络shufflenetV2为backbone,笔者在这里就不详解yolo-fastestV2了,只讲怎么训练自己的yolo-fastestV2模型。

2.修改训练代码

训练部分的代码只修改了一小部分,如下:

import os
import math
import time
import argparse
import numpy as np
from tqdm import tqdm
from numpy.testing._private.utils import print_assert_equal

import torch
from torch import optim
from torch.utils.data import dataset
from numpy.core.fromnumeric import shape

from torchsummary import summary

import utils.loss
import utils.utils
import utils.datasets
import model.detector

if __name__ == '__main__':
    # 指定训练配置文件
    parser = argparse.ArgumentParser()
    parser.add_argument('--data', type=str, default='./data/coco.data',
                        help='Specify training profile *.data')
    opt = parser.parse_args()
    cfg = utils.utils.load_datafile(opt.data)

    print("训练配置:")
    print(cfg)

    train_dataset = utils.datasets.TensorDataset(cfg["train"], cfg["width"], cfg["height"], imgaug = True)
    val_dataset = utils.datasets.TensorDataset(cfg["val"], cfg["width"], cfg["height"], imgaug = False)

    batch_size = int(cfg["batch_size"] / cfg["subdivisions"])
    nw = min([os.cpu_count(), batch_size if batch_size > 1 else 0, 8])
    print(nw)
    train_dataloader = torch.utils.data.DataLoader(train_dataset,
                                                   batch_size=batch_size,
                                                   shuffle=True,
                                                   collate_fn=utils.datasets.collate_fn,
                                                   num_workers=nw,
                                                   pin_memory=True,
                                                   drop_last=True,
                                                   persistent_workers=True
                                                   )
    val_dataloader = torch.utils.data.DataLoader(val_dataset,
                                                 batch_size=batch_size,
                                                 shuffle=False,
                                                 collate_fn=utils.datasets.collate_fn,
                                                 num_workers=nw,
                                                 pin_memory=True,
                                                 drop_last=False,
                                                 persistent_workers=True
                                                 )

    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

    load_param = False
    premodel_path = cfg["pre_weights"]
    if premodel_path != None and os.path.exists(premodel_path):
        load_param = True

    model = model.detector.Detector(cfg["classes"], cfg["anchor_num"], load_param).to(device)
    summary(model, input_size=(3, cfg["height"], cfg["width"]))

    # 加载预训练模型参数
    if load_param == True:
        model_dict = model.state_dict()
        pretrained_dict = torch.load(premodel_path, map_location=device)
        pretrained_dict = {k: v for k, v in pretrained_dict.items() if np.shape(model_dict[k]) == np.shape(v)}
        model_dict.update(pretrained_dict)
        model.load_state_dict(model_dict)
        print("Load finefune model param: %s" % premodel_path)
    else:
        print("Initialize weights: model/backbone/backbone.pth")

    optimizer = optim.SGD(params=model.parameters(),
                          lr=cfg["learning_rate"],
                          momentum=0.949,
                          weight_decay=0.0005,
                          )

    scheduler = optim.lr_scheduler.MultiStepLR(optimizer,
                                               milestones=cfg["steps"],
                                               gamma=0.1)

    print('Starting training for %g epochs...' % cfg["epochs"])

    batch_num = 0
    for epoch in range(cfg["epochs"]):
        model.train()
        pbar = tqdm(train_dataloader)

        for imgs, targets in pbar:
            imgs = imgs.to(device).float() / 255.0
            targets = targets.to(device)
            preds = model(imgs)
            iou_loss, obj_loss, cls_loss, total_loss = utils.loss.compute_loss(preds, targets, cfg, device)

            total_loss.backward()

            for g in optimizer.param_groups:
                warmup_num =  5 * len(train_dataloader)
                if batch_num <= warmup_num:
                    scale = math.pow(batch_num/warmup_num, 4)
                    g['lr'] = cfg["learning_rate"] * scale
                    
                lr = g["lr"]

            if batch_num % cfg["subdivisions"] == 0:
                optimizer.step()
                optimizer.zero_grad()

            info = "Epoch:%d LR:%f CIou:%f Obj:%f Cls:%f Total:%f" % (
                    epoch, lr, iou_loss, obj_loss, cls_loss, total_loss)
            pbar.set_description(info)

            batch_num += 1

        if epoch % 10 == 0 and epoch > 0:
            model.eval()
            print("computer mAP...")
            _, _, AP, _ = utils.utils.evaluation(val_dataloader, cfg, model, device)
            print("computer PR...")
            precision, recall, _, f1 = utils.utils.evaluation(val_dataloader, cfg, model, device, 0.3)
            print("Precision:%f Recall:%f AP:%f F1:%f"%(precision, recall, AP, f1))

            torch.save(model.state_dict(), "weights/%s-%d-epoch-%fap-model.pth" %
                      (cfg["model_name"], epoch, AP))

        scheduler.step()

这里笔者修改了加载预训练参数的部分,如果不修改的话,在后面修改训练自己模型的类别会有问题。因为作者的预训练模型是coco数据集80类别,要是不修改简单来说只能让类别数为80,这是肯定不行的。

3.制作自己的目标检测数据集

(1).收集图片

首先使用opencv收集数据集的图片,代码如下:

import cv2

cap=cv2.VideoCapture(1)
i=1
while(cap.isOpened()):
    ret,f=cap.read()
    c=cv2.waitKey(1)
    cv2.imshow("f",f)
    if c==27:
        break
    elif c==ord("q"):
        print(i)
        path="./data/"+str(i)+".jpg"
        cv2.imwrite(path,f)
        i+=1
    else:
        pass

cap.release()
cv2.destroyAllWindows()

(2).打标签

上面的代码只要修改一下path就能保存到自己指定的路径了,图片建议保存成jpg格式,当然也可以不,但是建议全部图片保存为同一种后缀。当然图片的分辨率也得是一致的。
然后安装标注工具labelimg,一般使用在cmd使用如下命令就能安装了

pip install labelimg

然后在cmd键入labelimg就能进入labelimg了,然后给自己的数据集打上标签。打成的标签xml文件和图片放在同一个文件夹里面。

(3).数据处理

然后运行如下代码:

import xml.etree.ElementTree as et
import os

classes=["a","b"]

def find_xml(path):
    '''
    找到一个文件夹下所有的xml文件,返回一个装这这些文件路径名的所有文件的列表
    '''
    file_list=os.listdir(path)
    xml_list=[]
    for file in file_list:
        if file.endswith(".xml"):
            xml_list.append(path+"/"+file)

    return xml_list

def xml2txt(path,x=640,y=480):
    xml_list=find_xml(path)
    for xml in xml_list:
        file=xml[:-4]
        txt=file+".txt"
        #xml文件解析器,将xml文件解析成元素树
        tree=et.parse(xml)
        #拿到树的根
        root=tree.getroot()
        with open(txt,'w') as f:
            #root.iter创建迭代器,寻找所有object的节点
            for obj in root.iter('object'):
                #按找标记名寻找匹配的第一个元素,text返回字符串
                cls = obj.find('name').text
                if cls not in classes:
                    continue
                cls_id = classes.index(cls)
                xmlbox = obj.find('bndbox')
                b = (int(xmlbox.find('xmin').text), int(xmlbox.find('ymin').text), int(xmlbox.find('xmax').text),
                     int(xmlbox.find('ymax').text))
                w=float(b[2]-b[0])
                h=float(b[3]-b[1])
                center_x=float(b[0]+w/2)
                center_y=float(b[1]+h/2)
                d=[center_x/x,center_y/y,w/x,h/y]
                f.write(str(cls_id)+" "+" ".join([str(a) for a in d])+"\n")


if __name__ == '__main__':
    xml2txt("./xml")

上面代码的作用是将每一个xml文件生成一个txt标签文件,用于后续训练,其中第二个函数中的x,y分别为图片的宽和高。因为作者的代码是要从txt文件里面获取归一化后的框,我们从上面收集的图片来说分辨率都是一样的,所以就直接用我们这个固定的宽高分辨率来归一化,当然如果有不同分辨率的图片的话,可以打标签前做一个resize操作,也可以在解析xml文件的时候输出图片的宽高再用这个宽高归一化。
下面就是生成用于训练的train.txt和test.txt了,这两个文件就是储存了图片的路径,方便在训练或者评估的时候找到图片的路径。代码如下:

import os
import random
random.seed(0)

def find_xml(path):
    '''
    path用绝对路径
    找到一个文件夹下所有的xml文件,返回一个装这这些文件路径名的所有文件的列表
    '''
    file_list=os.listdir(path)
    xml_list=[]
    for file in file_list:
        if file.endswith(".xml"):
            xml_list.append(path+"/"+file)
    return xml_list

def wri_txt(path,tu="jpg",train_path="train.txt",test_path="test.txt",train_precent=0.8):
    xml_list=find_xml(path)
    train_len=int(len(xml_list)*train_precent)
    ftrain=open(train_path,'w')
    ftest=open(test_path,'w')
    train_list=random.sample(xml_list,train_len)
    for xml in xml_list:
        if xml in train_list:
            pp = xml[:-4] + "." + tu
            ftrain.write(str(pp) + "\n")
        else:
            pp = xml[:-4] + "." + tu
            ftest.write(str(pp) + "\n")
    print("写入完成")


if __name__ == '__main__':
    wri_txt(path=r"D:\python1\python\pytorch\object-detection\Yolo-FastestV2-main\xml")

然后注意第二个函数wri_txt函数中的路径必须用绝对路径。

4.修改超参数

(1).生成先验框

生成anchors的代码在作者的genanchors.py中,我们在main函数中修改traintxt参数的defaul也就是默认参数为我们上面写入的train.txt文件的路径即可。然后就会生成一个anchors6.txt文件,打开它如下:

53.74,73.54, 79.35,106.18, 83.11,168.08, 107.49,135.43, 119.73,183.46, 158.47,204.21
0.847014

第一行就是我们的6个先验框的宽高了。第二行可以不用管。

(2).修改超参数

打开data文件夹下的coco.data,把anchors后面的数字改成我们生成的第一行数据即可。
coco.data的数据如下:

[name]
model_name=fruit   #模型名字

[train-configure]
epochs=300      #批次数
steps=150,250
batch_size=2
subdivisions=1
learning_rate=0.001

[model-configure]
pre_weights=./modelzoo/coco2017-0.241078ap-model.pth  #预训练参数路径
classes=2   #分类数
width=352
height=352
anchor_num=3   #每个特征层的anchor数
anchors=53.74,73.54, 79.35,106.18, 83.11,168.08, 107.49,135.43, 119.73,183.46, 158.47,204.21
[data-configure]
train=D:\\python1\\python\\pytorch\\object-detection\\Yolo-FastestV2-main\train.txt   #训练集路径
val=D:\\python1\\python\\pytorch\\object-detection\\Yolo-FastestV2-main\\test.txt    #测试集路径
names=./data/coco.names   #保存对应类别名字的文件

然后按照上面的注释,把这些超参数改成自己需要的就好了,一些基础的超参数笔者就不解释了。
随后把coco.names文件改成自己数据的类别,一个类别对应一行。

5.开始训练

随后就可以运行train.py文件用自己的数据集训练自己的模型了。在这里笔者建议安装的torch1.9.0,torchvision0.10.0。这是项目作者的环境,不然可能会因为api不兼容报错。
然后万一训练好的模型泛化不到训练场景以外的场景,最简单的方法就是添加这个场景的数据,将预训练权重修改成自己之前训练好的权重继续训练。这样更节省时间。然后在数据集的收集上的话,建议每个类别的数量在1500个框以上吧。文章来源地址https://www.toymoban.com/news/detail-461900.html

到了这里,关于深度学习-yolo-fastestV2使用自己的数据集训练自己的模型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深度学习必备知识——模型数据集Yolo与Voc格式文件相互转化

    在深度学习中,第一步要做的往往就是 处理数据集 ,尤其是学习百度飞桨PaddlePaddle的小伙伴,数据集经常要用Voc格式的,比如性能突出的ppyolo等模型。所以学会 数据集转化 的本领是十分必要的。这篇博客就带你一起进行Yolo与Voc格式的相互转化,附详细代码! Yolo数据集主要

    2024年01月17日
    浏览(45)
  • 大数据毕设选题 - 深度学习火焰识别检测系统(python YOLO)

    🔥 Hi,大家好,这里是丹成学长的毕设系列文章! 🔥 对毕设有任何疑问都可以问学长哦! 这两年开始,各个学校对毕设的要求越来越高,难度也越来越大… 毕业设计耗费时间,耗费精力,甚至有些题目即使是专业的老师或者硕士生也需要很长时间,所以一旦发现问题,一定

    2023年04月11日
    浏览(43)
  • 深度学习目标检测数据VisDrone2019(to yolo / voc / coco)---MMDetection数据篇

    配备摄像头的无人机(或通用无人机)已被快速部署到广泛的应用领域,包括农业、航空摄影、快速交付和监视。因此,从这些平台上收集的视觉数据的自动理解要求越来越高,这使得计算机视觉与无人机的关系越来越密切。我们很高兴为各种重要的计算机视觉任务展示一个大

    2024年02月04日
    浏览(55)
  • 深度学习——制作自己的VOC图像分割数据集

    1、数据集介绍 COCO数据集有80个类别,VOC数据集有20个类别。当这些数据集类别中没有自己需要的时候,就需要自己动手做自己的数据集了。 我自己在做数据集的时候主要使用到了labelme和labelImg两个工具。labelme主要是制作语义分割数据集(ImageSets,JPEGImages,SegmentationClass,Segmenta

    2024年02月04日
    浏览(45)
  • 精华整理几十个Python数据科学、机器学习、深度学习、神经网络、人工智能方面的核心库以及详细使用实战案例,轻松几行代码训练自己的专有人工智能模型

    精华整理几十个Python数据科学、机器学习、深度学习、神经网络、人工智能方面的核心库以及详细使用实战案例,轻松几行代码训练自己的专有人工智能模型。 机器学习 人工智能的核心,是使计算机具有智能的根本途径。机器学习专注于算法,允许机器学习而不需要编程,

    2024年01月25日
    浏览(71)
  • 【三维重建】【深度学习】【数据集】基于COLMAP制作自己的NeRF(LLFF格式)数据集

    提示:最近开始在【三维重建】方面进行研究,记录相关知识点,分享学习中遇到的问题已经解决的方法。 LLFF格式是NeRF网络模型训练使用的数据集格式之一,本文基于COLMAP软件展示从LLFF格式数据集的制作到开始模型训练的完整流程。NeRF(神经辐射场)通过输入同一场景不同视角下

    2024年02月10日
    浏览(48)
  • 深度学习(目标检测):YOLO网络学习笔记(YOLO v1,YOLO v2和 YOLO v3)

    两种进行目标检测任务的深度学习方法 : 分类 :深度学习的目标检测的方法可以分为两类,分别是一阶段方法和二阶段方法。 一阶段方法 :YOLO系列模型都是一阶段方法,这一类方法可以一步到位地使用卷积神经网络进行特征提取并输出标注框。 两阶段方法 :两阶段阶段

    2023年04月11日
    浏览(39)
  • 深度学习Docker使用, (Pytorch/TensorRT/DeepStream),标记上传制作自己的DockerHub

    https://docs.docker.com/engine/install/ubuntu/ Set Up Install Docker Engine 安装nvidia cuda tookit 加入了之后重启了才能使用 Docker Root Dir: /data/docker 我的docker数据的挂载就是在/data/docker下面的 https://catalog.ngc.nvidia.com/containers 全部镜像都是在NVIDIA官方找的 登陆自己的账号 标记自己的镜像 在这里面

    2024年02月13日
    浏览(39)
  • 深度学习(28)——YOLO系列(7)

    咱就是说,需要源码请造访:Jane的GitHub :在这里 上午没写完的,下午继续,是一个小尾巴。其实上午把训练的关键部分和数据的关键部分都写完了,现在就是写一下推理部分 在推理过程为了提高效率,速度更快: 1.1 attempt_load(weights) weights是加载的yolov7之前训练好的权重 刚

    2024年02月16日
    浏览(47)
  • 深度学习(27)——YOLO系列(6)

    咱就是说,需要源码请造访:Jane的GitHub :在这里等你哦 嗨,好久不见,昨天结束了yolov7的debug过程,真的在尽力句句理解,我想这应该是我更新的yolo系列的最后一篇,但是仅限于yolo,detect的话题还不会结束,还会继续进行,detect结束以后再说segmentation。和往常以一样的过程

    2024年02月15日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包