win10+keras+yolo4训练自己的数据集

win10+keras+yolo4训练自己的数据集

**

一、下载准备

1、(1)yolo4的github代码:https://github.com/Ma-Dan/keras-yolo4
(2)所准备数据集::Safety-Helmet-Wearing-Dataset;
github链接::https://github.com/njvisionpower/Safety-Helmet-Wearing-Dataset
(3)yolov4权重文件yolov4.weights(包含已转换完成的yolov4.h5文件,如果想偷懒可以直接将yolov4.h5文件放入keras-yolo4-master\model_data下,不需conver.py转换这一过程):
下载链接:链接:https://pan.baidu.com/s/1_HFT8f_K0LMQNiURMNA4kQ
提取码:nnz4

2、本人电脑试验环境:
python 3.7.4
tensorflow 1.14
keras 2.2.5
CUDA 10.0
cuDNN 7.5.x

二、数据集准备及处理

数据集格式为VOC2028,可参考链接文章对自己数据集进行修改,已有很多博文解析了制作VOC格式数据集的方法,参考如下:目标检测数据集制作流程
身为小白的自己,在此列出各位大哥们需要注意的地方,防止后续运行报错
1、路径问题
keras-yolo4-master文件夹内 VOCdevkit用于存放你自己记的VOC数据集
在这里插入图片描述
2. VOC2028中,Annotation文件夹下xml,是Labelimage运行后生成的xml文件,需要包含正确的path,filename,且不得包含非法字符(比如汉字)
!!!若path,filename有误,可以参考如下代码进行修改(注意写入自己的路径)
该代码引用自博主Jack_0601 ,在此表示感谢,原文链接如下:python批量修改xml文件path与filenames


'''
修改xml中的路径path
'''

import xml.dom.minidom
import os

path = r'E:\models\VOCdevkit\VOC2028\Annotations'  # xml文件存放路径
sv_path = r'E:\models\VOCdevkit\VOC2028\Annotations'  # 修改后的xml文件存放路径
files = os.listdir(path)
cnt = 1

for xmlFile in files:
    dom = xml.dom.minidom.parse(os.path.join(path, xmlFile))  # 打开xml文件,送到dom解析
    root = dom.documentElement    # 得到文档元素对象
    item = root.getElementsByTagName('path')  # 获取path这一node名字及相关属性值
    for i in item:
        i.firstChild.data = 'E:\\models\\keras-yolo3-helmet\\VOCdevkit\\VOC2028\\JPEGImages' + str(cnt).zfill(6) + '.jpg'  # xml文件对应的图片路径

3、(1)若Main文件夹下为空,
则在VOC2028文件夹里新建test.py,运行代码将会在Main文件夹里生成train.txt,val.txt,test.txt和trainval.txt四个文件。代码如下:

import os
import random

trainval_percent = 0.1
train_percent = 0.9
xmlfilepath = 'Annotations'
txtsavepath = 'ImageSets\Main'
total_xml = os.listdir(xmlfilepath)

num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)

ftrainval = open('ImageSets/Main/trainval.txt', 'w')
ftest = open('ImageSets/Main/test.txt', 'w')
ftrain = open('ImageSets/Main/train.txt', 'w')
fval = open('ImageSets/Main/val.txt', 'w')

for i in list:
    name = total_xml[i][:-4] + '\n'
    if i in trainval:
        ftrainval.write(name)
        if i in train:
            ftest.write(name)
        else:
            fval.write(name)
    else:
        ftrain.write(name)

ftrainval.close()
ftrain.close()
fval.close()
ftest.close()


(2)VOC2028\ImageSets\Main中包含以下4个文件,其中,test.txt不是必要,但最好要有
在这里插入图片描述

三、准备工作

1、权重转换convert.py

keras所用权重为.h5文件,因此需要转化yolov4.weights格式。利用convert.py代码将yolov4.weights权重转化为keras所需yolov4.h5权重文件,代码位于keras-yolo4-master/convert.py,具体流程如下

1、下载本文开头所发链接中yolov4.weights权重文件
2、yolov4.weights移动至keras-yolo4-master文件目录下

3、运行python convert.py即可
在这里插入图片描述

4、将keras-yolo4-master文件目录下生成的yolov4.h5移动至keras-yolo4-master\model_data

2、voc_annotation

1、(1)修改voc_annotation.py,将sets修改为自己数据集的名称,classes修改为自己的类别。
我的数据集路径为:E:\models\keras-yolo4-master\VOCdevkit\VOC2028,且voc_annotation.py文件位于E:\models\keras-yolo4-master下。
(2)可能会报错路径错误,原voc_annotation.py文件代码中路径与我的不一致,我修改了in_file=open(xxx);image_ids=open(xxx) ;list_file=open(xxx) 这几行代码,修改为自己的路径。在此贴出自己的代码,以作参考

import xml.etree.ElementTree as ET
# xml.etree.ElementTree 实现了解析和创建xml数据的简单高效API
from os import getcwd

sets=[('2028', 'train'), ('2028', 'val'), ('2028', 'test')]

classes = ["person", "hat"]


def convert_annotation(year, image_id, list_file):
    in_file = open('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id))

    # 从文件读取数据
    tree=ET.parse(in_file)
    root = tree.getroot()
    '''
    从字符串读取数据
    root=ET.fromstring(xml_data_as_string)
    ''' 
    
    for obj in root.iter('object'):
        difficult = obj.find('difficult').text
        cls = obj.find('name').text
        if cls not in classes or int(difficult)==1:
            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))
        list_file.write(" " + ",".join([str(a) for a in b]) + ',' + str(cls_id))

wd = getcwd()

for year, image_set in sets:
    image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'%(year, image_set)).read().strip().split()
    list_file = open('%s_%s.txt'%(year, image_set), 'w')
    for image_id in image_ids:
        list_file.write('%s/VOCdevkit/VOC%s/JPEGImages/%s.jpg'%(wd, year, image_id))
        convert_annotation(year, image_id, list_file)
        list_file.write('\n')
    list_file.close()

2、运行voc_annotation.py 生成三个txt文件在keras-yolo4-master/目录下,如下图所示
在这里插入图片描述3、分别重命名 2028_test为 test。2028_train为 train。2028_val 为 val。
这一步别忘了,否则后面报错文件不存在,它其实一直都在,只不过你忘了重命名而已

3、训练的准备工作

(1)、k-means维度聚类
维度聚类的目的是 根据你自己的数据集生成合适的先验框,为了有更好的训练效果,建议大家不要忘了运行k-means.py文件,步骤如下
1、修改k-means.py文件文件内代码 “2012_train.txt” 为 “train.txt”,注意共有两处修改
2、运行k-means.py
3、将主目录keras-yolo4-master下生成的yolo_anchors.txt移动至keras-yolo4-master\model_data文件夹下
在这里插入图片描述
(2)修改CFG文件
打开主目录keras-yolo4-master下yolov4.cfg文件,ctrl+h搜索yolo,会出现三个[yolo],(位于cfg文件后半部分)。每个[yolo]需要修改三处,共计9处要修改,修改它们!!!下图仅展示第一个[yolo]的修改
在这里插入图片描述每一个[yolo]的三处修改都是一样的
第一处:filters=3*(5+类别数),比如我的是2类,filters=3*(5+2)=21
第二处:anchors为刚才生成yolo_anchors文本的内容
第三处:classes有几类就写几
切记不要擅自修改其他地方(大神请自动屏蔽这句话)

(3)新建my_classes.txt
在主目录keras-yolo4-master\model_data下新建txt文件,命名为my_classes.txt,注意文件内不要有多余的空格或空行,以免训练时候读取出错
在这里插入图片描述

四、开始训练吧!

1、修改keras-yolo4-master/train.py
若使用GPU,我加了一行代码位于第24行,GOU编号为0
若电脑配置较低,注意修改batchsize,防止内存不足CUDA_memory_out
在这里插入图片描述
2、注意修改4处文件名称,
2012_train.txt修改为train.txt 共计修改
1

2012_val.txt修改为val.txt 共计修改2
epoch由50000改为50轮 共计1处,(50000轮迭代太久,等换了好的GPU再试试)

此处粘贴出train.py代码,代码来源于本文开头yolov4的github文件,感谢keras-yolo4-master的创作,也希望大家能提出优化修改意见,一起学习进步

"""
Retrain the YOLO model for your own dataset.
"""

import math
import random
import os
import cv2

import numpy as np
import keras.backend as K
from keras.layers import Input, Lambda
from keras.models import Model
from keras.optimizers import Adam
from keras.callbacks import TensorBoard, ModelCheckpoint, ReduceLROnPlateau, EarlyStopping
import keras.layers as layers

from yolo4.model import preprocess_true_boxes, yolo4_body, yolo_loss
from yolo4.utils import get_random_data

from callback_eval import Evaluate
import keras.backend.tensorflow_backend as KTF
import tensorflow as tf
os.environ["CUDA_VISIBLE_DEVICES"] = "0"



def _main():

    annotation_train_path = 'train.txt'
    annotation_val_path = 'val.txt'
    log_dir = 'logs/000/'
    classes_path = 'model_data/my_classes.txt'
    anchors_path = 'model_data/yolo4_anchors.txt'
    class_names = get_classes(classes_path)
    num_classes = len(class_names)
    class_index = ['{}'.format(i) for i in range(num_classes)]
    anchors = get_anchors(anchors_path)

    max_bbox_per_scale = 150

    anchors_stride_base = np.array([
        [[12, 16], [19, 36], [40, 28]],
        [[36, 75], [76, 55], [72, 146]],
        [[142, 110], [192, 243], [459, 401]]
    ])
    # 一些预处理
    anchors_stride_base = anchors_stride_base.astype(np.float32)
    anchors_stride_base[0] /= 8
    anchors_stride_base[1] /= 16
    anchors_stride_base[2] /= 32

    input_shape = (608, 608) # multiple of 32, hw
    
    #不全部占满显存, 按需分配
    config = tf.ConfigProto()
    config.gpu_options.allow_growth=True   #不全部占满显存, 按需分配
    sess = tf.Session(config=config)
    KTF.set_session(sess)

    model, model_body = create_model(input_shape, anchors_stride_base, num_classes, load_pretrained=False, freeze_body=2, weights_path='yolo4_weight.h5')

    logging = TensorBoard(log_dir=log_dir)
    checkpoint = ModelCheckpoint(log_dir + 'ep{epoch:03d}-loss{loss:.3f}.h5',
        monitor='loss', save_weights_only=True, save_best_only=True, period=1)
    reduce_lr = ReduceLROnPlateau(monitor='loss', factor=0.1, patience=3, verbose=1)
    early_stopping = EarlyStopping(monitor='loss', min_delta=0, patience=10, verbose=1)
    evaluation = Evaluate(model_body=model_body, anchors=anchors, class_names=class_index, score_threshold=0.05, tensorboard=logging, weighted_average=True, eval_file='val.txt', log_dir=log_dir)

    with open(annotation_train_path) 
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值