前言

上期我们已经完成了环境的搭建,以及环境的检测。我们接着在上期的基础上进行训练模型。

一、数据集的获取

点击这个链接,先下载数据集(提取码: 485q)。

这里取的是猫猫图片前121张,名字是cat.0.jpg到cat.120.jpg。

复制到项目文件夹yolov5-master\own_datas\images\train文件夹下作为训练集。

另外再新建出来yolov5-master\own_datas\labels这些文件夹。(有用)

yolov5cpu比gpu还快 cpu跑yolov5_yolov5cpu比gpu还快

二、打标签前的准备工作

我们在终端下面先输入以下代码。

pip install pyqt5 labelme
pip install pyqt5 labelme

yolov5cpu比gpu还快 cpu跑yolov5_YOLO_02

很遗憾,我这里报错了。如果你的报错跟我一样可以在下面接着输入。

pip install --upgrade setuptools
pip3 install wheel
pip3 install pyinstaller
pip install --upgrade setuptools
pip3 install wheel
pip3 install pyinstaller

yolov5cpu比gpu还快 cpu跑yolov5_pytorch_03

yolov5cpu比gpu还快 cpu跑yolov5_人工智能_04

运行完是这些效果。

接着再运行一遍下面这个代码。

pip install pyqt5 labelme
pip install pyqt5 labelme

yolov5cpu比gpu还快 cpu跑yolov5_pytorch_05

神奇的没有报错。

接着输入。

labelme
labelme

yolov5cpu比gpu还快 cpu跑yolov5_pytorch_06

接着在屏幕上弹出来了这个。

yolov5cpu比gpu还快 cpu跑yolov5_人工智能_07

准备工作结束!

三、打标签

点击左上角的Open Dir,选择yolov5-master\own_datas\images\train文件夹,就会出现训练集里的图片。右键选择Create Rectangle,框出图片里的猫猫。

yolov5cpu比gpu还快 cpu跑yolov5_yolov5cpu比gpu还快_08

框选结束后,输入标签名cat,点击ok,这个标签就保存下来了。如果有多只猫猫,就继续框选。整张图片框选完毕后,点击左侧的Next Image,根据提示把标注文件保存到路径yolov5-master\own_datas\labels\json中,文件的格式是.json。大概40分钟左右就能标注完成。

接着我们需要把json文件转换成txt文件,在此之前先在labels文件夹下面新建txt的文件夹,方便将数据保存。

接着我们在项目文件夹里面新建一个py文件。

yolov5cpu比gpu还快 cpu跑yolov5_YOLO_09

在下面写入以下代码

import json
import os

name2id = {'cat': 0}  # 标签名称


def convert(img_size, box):
    dw = 1. / (img_size[0])
    dh = 1. / (img_size[1])
    x = (box[0] + box[2]) / 2.0 - 1
    y = (box[1] + box[3]) / 2.0 - 1
    w = box[2] - box[0]
    h = box[3] - box[1]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)


def decode_json(json_floder_path, json_name):
    txt_name = 'C:/Users/华硕/Desktop/yolov5-master/own_datas/labels/txt/' + json_name[0:-5] + '.txt'
    # txt文件夹的绝对路径
    txt_file = open(txt_name, 'w')

    json_path = os.path.join(json_floder_path, json_name)
    data = json.load(open(json_path, 'r', encoding='gb2312', errors='ignore'))

    img_w = data['imageWidth']
    img_h = data['imageHeight']

    for i in data['shapes']:

        label_name = i['label']
        if (i['shape_type'] == 'rectangle'):
            x1 = int(i['points'][0][0])
            y1 = int(i['points'][0][1])
            x2 = int(i['points'][1][0])
            y2 = int(i['points'][1][1])

            bb = (x1, y1, x2, y2)
            bbox = convert((img_w, img_h), bb)
            txt_file.write(str(name2id[label_name]) + " " + " ".join([str(a) for a in bbox]) + '\n')


if __name__ == "__main__":

    json_floder_path = 'C:/Users/华硕/Desktop/yolov5-master/own_datas/labels/json/'
    # json文件夹的绝对路径
    json_names = os.listdir(json_floder_path)
    for json_name in json_names:
        decode_json(json_floder_path, json_name)
import json
import os

name2id = {'cat': 0}  # 标签名称


def convert(img_size, box):
    dw = 1. / (img_size[0])
    dh = 1. / (img_size[1])
    x = (box[0] + box[2]) / 2.0 - 1
    y = (box[1] + box[3]) / 2.0 - 1
    w = box[2] - box[0]
    h = box[3] - box[1]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)


def decode_json(json_floder_path, json_name):
    txt_name = 'C:/Users/华硕/Desktop/yolov5-master/own_datas/labels/txt/' + json_name[0:-5] + '.txt'
    # txt文件夹的绝对路径
    txt_file = open(txt_name, 'w')

    json_path = os.path.join(json_floder_path, json_name)
    data = json.load(open(json_path, 'r', encoding='gb2312', errors='ignore'))

    img_w = data['imageWidth']
    img_h = data['imageHeight']

    for i in data['shapes']:

        label_name = i['label']
        if (i['shape_type'] == 'rectangle'):
            x1 = int(i['points'][0][0])
            y1 = int(i['points'][0][1])
            x2 = int(i['points'][1][0])
            y2 = int(i['points'][1][1])

            bb = (x1, y1, x2, y2)
            bbox = convert((img_w, img_h), bb)
            txt_file.write(str(name2id[label_name]) + " " + " ".join([str(a) for a in bbox]) + '\n')


if __name__ == "__main__":

    json_floder_path = 'C:/Users/华硕/Desktop/yolov5-master/own_datas/labels/json/'
    # json文件夹的绝对路径
    json_names = os.listdir(json_floder_path)
    for json_name in json_names:
        decode_json(json_floder_path, json_name)

大家别忘记把文件地址改一下。这是我的电脑文件夹地址。

运行一下py文件,你会得到转换后的数据。

yolov5cpu比gpu还快 cpu跑yolov5_yolov5cpu比gpu还快_10

最后一步,把txt文件夹中的文件全部复制到yolov5-master\own_datas\labels\train文件夹中。

四、修改配置文件,开始跑模型

首先先复制两个文件

在yolov5-master\data路径下找到coco128.yaml文件,复制到yolov5-master\own_datas路径下,改名为cat.yaml

在yolov5-master\models路径下找到yolov5s.yaml文件,同样复制到yolov5-master\own_datas路径下。选择yolov5s是因为,虽然它效果不太好,但是速度比较快。

打开cat.yaml文件,首先需要修改的是这三行:

# path: ../datasets/coco128  # dataset root dir
train: own_datas/images/train  # train images (relative to 'path') 128 images
val: own_datas/images/train  # val images (relative to 'path') 128 images
# path: ../datasets/coco128  # dataset root dir
train: own_datas/images/train  # train images (relative to 'path') 128 images
val: own_datas/images/train  # val images (relative to 'path') 128 images

yolov5cpu比gpu还快 cpu跑yolov5_pytorch_11

第一行注释掉,第二行和第三行的相对路径,如果是一模一样跟着我做下来的,按我这个来就可以了

然后修改这两行:

nc: 1  # number of classes
names: ['cat']  # class names
nc: 1  # number of classes
names: ['cat']  # class names

yolov5cpu比gpu还快 cpu跑yolov5_pytorch_12

最后把这一行给注释掉

yolov5cpu比gpu还快 cpu跑yolov5_深度学习_13

打开yolov5s.yaml文件,需要修改的是这一行:

nc: 1  # number of classes
nc: 1  # number of classes

yolov5cpu比gpu还快 cpu跑yolov5_深度学习_14

打开train.py文件找到这几行。

yolov5cpu比gpu还快 cpu跑yolov5_人工智能_15

parser.add_argument('--weights', type=str, default='yolov5s.pt', help='initial weights path')
    parser.add_argument('--cfg', type=str, default='own_datas/yolov5s.yaml', help='model.yaml path')
    parser.add_argument('--data', type=str, default='own_datas/cat.yaml', help='dataset.yaml path')
    parser.add_argument('--epochs', type=int, default=150)
parser.add_argument('--workers', type=int, default=0, help='maximum number of dataloader workers')
    parser.add_argument('--weights', type=str, default='yolov5s.pt', help='initial weights path')
    parser.add_argument('--cfg', type=str, default='own_datas/yolov5s.yaml', help='model.yaml path')
    parser.add_argument('--data', type=str, default='own_datas/cat.yaml', help='dataset.yaml path')
    parser.add_argument('--epochs', type=int, default=150)
parser.add_argument('--workers', type=int, default=0, help='maximum number of dataloader workers')

修改成这个样子。

五、开始训练

运行train.py,然后静静等待

报错了!!!!!

yolov5cpu比gpu还快 cpu跑yolov5_YOLO_16

解决方法:找到5.0版报错的loss.py中最后那段for函数,将其整体替换为yolov5-master版中loss.py最后一段for函数即可正常运行。

for i in range(self.nl):
            anchors, shape = self.anchors[i], p[i].shape
            gain[2:6] = torch.tensor(shape)[[3, 2, 3, 2]]  # xyxy gain
 
            # Match targets to anchors
            t = targets * gain  # shape(3,n,7)
            if nt:
                # Matches
                r = t[..., 4:6] / anchors[:, None]  # wh ratio
                j = torch.max(r, 1 / r).max(2)[0] < self.hyp['anchor_t']  # compare
                # j = wh_iou(anchors, t[:, 4:6]) > model.hyp['iou_t']  # iou(3,n)=wh_iou(anchors(3,2), gwh(n,2))
                t = t[j]  # filter
 
                # Offsets
                gxy = t[:, 2:4]  # grid xy
                gxi = gain[[2, 3]] - gxy  # inverse
                j, k = ((gxy % 1 < g) & (gxy > 1)).T
                l, m = ((gxi % 1 < g) & (gxi > 1)).T
                j = torch.stack((torch.ones_like(j), j, k, l, m))
                t = t.repeat((5, 1, 1))[j]
                offsets = (torch.zeros_like(gxy)[None] + off[:, None])[j]
            else:
                t = targets[0]
                offsets = 0
 
            # Define
            bc, gxy, gwh, a = t.chunk(4, 1)  # (image, class), grid xy, grid wh, anchors
            a, (b, c) = a.long().view(-1), bc.long().T  # anchors, image, class
            gij = (gxy - offsets).long()
            gi, gj = gij.T  # grid indices
 
            # Append
            indices.append((b, a, gj.clamp_(0, shape[2] - 1), gi.clamp_(0, shape[3] - 1)))  # image, anchor, grid
            tbox.append(torch.cat((gxy - gij, gwh), 1))  # box
            anch.append(anchors[a])  # anchors
            tcls.append(c)  # class
        for i in range(self.nl):
            anchors, shape = self.anchors[i], p[i].shape
            gain[2:6] = torch.tensor(shape)[[3, 2, 3, 2]]  # xyxy gain
 
            # Match targets to anchors
            t = targets * gain  # shape(3,n,7)
            if nt:
                # Matches
                r = t[..., 4:6] / anchors[:, None]  # wh ratio
                j = torch.max(r, 1 / r).max(2)[0] < self.hyp['anchor_t']  # compare
                # j = wh_iou(anchors, t[:, 4:6]) > model.hyp['iou_t']  # iou(3,n)=wh_iou(anchors(3,2), gwh(n,2))
                t = t[j]  # filter
 
                # Offsets
                gxy = t[:, 2:4]  # grid xy
                gxi = gain[[2, 3]] - gxy  # inverse
                j, k = ((gxy % 1 < g) & (gxy > 1)).T
                l, m = ((gxi % 1 < g) & (gxi > 1)).T
                j = torch.stack((torch.ones_like(j), j, k, l, m))
                t = t.repeat((5, 1, 1))[j]
                offsets = (torch.zeros_like(gxy)[None] + off[:, None])[j]
            else:
                t = targets[0]
                offsets = 0
 
            # Define
            bc, gxy, gwh, a = t.chunk(4, 1)  # (image, class), grid xy, grid wh, anchors
            a, (b, c) = a.long().view(-1), bc.long().T  # anchors, image, class
            gij = (gxy - offsets).long()
            gi, gj = gij.T  # grid indices
 
            # Append
            indices.append((b, a, gj.clamp_(0, shape[2] - 1), gi.clamp_(0, shape[3] - 1)))  # image, anchor, grid
            tbox.append(torch.cat((gxy - gij, gwh), 1))  # box
            anch.append(anchors[a])  # anchors
            tcls.append(c)  # class

yolov5cpu比gpu还快 cpu跑yolov5_pytorch_17

点运行train.py

yolov5cpu比gpu还快 cpu跑yolov5_深度学习_18

六、跑完测试

大概跑了2个多小时,跑完是这个样子

yolov5cpu比gpu还快 cpu跑yolov5_人工智能_19

打开训练好的结果查看一下,没毛病

我的输出是exp3文件夹的原因是我前两次因为bug,失败了两次。如果你是一次就成功的那么输出文件会直接是exp。

yolov5cpu比gpu还快 cpu跑yolov5_pytorch_20

weights文件夹里面的best.pt文件是训练好的模型,测试的时候用

yolov5cpu比gpu还快 cpu跑yolov5_pytorch_21

我在训练集中随便选了一张,以为当时训练的时候用了前100多张,后面的图片我就可以随便抽一张,进行测试。

打开detect.py文件

改两行代码(第一行代码要看一下模型的具体位置,我这里因为前面失败了两次,第三次才炼制成功了)

yolov5cpu比gpu还快 cpu跑yolov5_YOLO_22

parser.add_argument('--weights', nargs='+', type=str, default='runs/train/exp3/weights/best.pt', help='model path(s)')
    parser.add_argument('--source', type=str, default='own_datas/images/test', help='file/dir/URL/glob, 0 for webcam')
parser.add_argument('--weights', nargs='+', type=str, default='runs/train/exp3/weights/best.pt', help='model path(s)')
    parser.add_argument('--source', type=str, default='own_datas/images/test', help='file/dir/URL/glob, 0 for webcam')

第一个default就是之前说过的训练出来的模型文件的相对路径

第二个default就是存放测试文件的文件夹的相对路径

运行一下detect.py

yolov5cpu比gpu还快 cpu跑yolov5_人工智能_23

看一下效果

yolov5cpu比gpu还快 cpu跑yolov5_深度学习_24

这里我又选取了一段有猫猫的视频(我是随便下载了一段,不建议下载太长,因为测试起来会消耗很长的时间),我又进行了测试。

yolov5cpu比gpu还快 cpu跑yolov5_YOLO_25

这是一段47秒的视频,大概跑了3分钟左右。

这里我截图一张,看看效果。

yolov5cpu比gpu还快 cpu跑yolov5_pytorch_26

七、总结

效果差强人意,毕竟只训练了121张图片,还用了比较差的yolov5s网络,下次再增加一下训练集的数量。要是用GPU跑应该会好一点吧。