个人笔记本上win10+yolov3+python+tensorflow+keras训练自己的识别模型
本文是在前人的很多基础上自己整理所得,借鉴的资料见文末链接,感谢各位大神的无私分享。
对于yolo小白,参阅博文学习:keras-yolov3目标检测详解——适合新手, (环境配置、用官方权重识别自己的图片)
前提准备:
1、配置好环境的 python、pycharm
2、labelimg 软件:下载方法: labelme
3、准备一些图片,创建训练需要的 VOC 文件
(1) 官方的VOC2007下载链接:http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar,可以从这里找需要的图片,或者一些有基础的朋友可以写爬虫去爬一些图片
(2) voc2007百度网盘下载链接:
链接:https://pan.baidu.com/s/18wqRTZDSz5NQEtvq0u0a1g
提取码:hexy
正式训练步骤:
1、打开文件夹
先按照这篇文章的步骤操作:keras-yolov3目标检测详解——适合新手
完成后打开的文件夹应该是这样的:
2、新建voc2007数据集(存放自己的图片及标注信息)
新建的文件夹:如下
ImageSets
文件夹下还有个名为 Main
的小文件夹
文件结构
VOCdevkit{VOC2007{ AnnotationsImageSets{main}JPEGImages } }
虽然表达的很丑,但是上面有图,应该还是可以看明白的
注意:文件夹的名称必须和上面展示的一样,这是 yolo 默认的不然还需要改代码才行
3、用labelimg软件对自己的图片进行信息标注
----labelimg 的使用方法:labelimg 下载和标注 xlm 文件
(1)需要训练的图片放在 JPEGImages
里面:
(2)labelimg 标注的 xml 文件放在 Annotations
里面:
4、在 VOC2007 里新建一个 py 文件,取名 voc.py
import os
import randomtrainval_percent = 0.2 #测试集占0.2
train_percent = 0.8 #训练集占0.8
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()
然后运行 voc.py 文件,运行成功的话 mian 文件夹里会多了四个 txt 文件
二、进行训练前的最后准备
1、修改 voc_annotation.py
文件并运行
更改这里的 classes 的数量,你voc2007里标注了哪几种,你就留哪几种就行
比如我的 voc 中只标注了 “person”,那我只留下“person”,然后再运行一下就行
运行完成后会多出这几个 txt 文件
2、修改 model_data
将 coco_classes.txt 和 voc_classes.txt 中也只留下VOC2007 中所标注的那个类型
比如我标注的只有 “person”。那我只留下“person”
3、修改 yolo3.cfg
大概在 610、696 和 783 行的位置,把 classes 的数值都改为 1
注:IDE里直接打开cfg文件,ctrl+f搜 yolo, 总共会搜出3个含有yolo的地方,睁开你的卡姿兰大眼睛,3个yolo!!
每个地方都要改3处,filters:3*(5+len(classes));
classes: len(classes) = 3,这里以红、黄、蓝三个颜色为例
4、添加官方权重
按照上篇博文步骤进行的朋友应该下载好了 yolov3.weights
文件并转为了 yolo.h5
文件
附上上篇博文的链接(里面有下载链接和转化方法):keras-yolov3目标检测详解——适合新手
将 yolo.h5
改名为 yolo_weights.h5
5、新建 logs 文件夹存放训练的 权重文件
6、开始训练
有官方版本,有些大神说官方版本出错,自己写了训练脚本,我用的官方的,没出问题,整体的原理一样,主要是第三方库的问题。
"""
Retrain the YOLO model for your own dataset.
"""import numpy as np
# import keras.backend as K
from tensorflow.compat.v1.keras import 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, EarlyStoppingfrom yolo3.model import preprocess_true_boxes, yolo_body, tiny_yolo_body, yolo_loss
from yolo3.utils import get_random_datadef _main():annotation_path = 'train.txt'log_dir = 'logs/'classes_path = 'model_data/voc_classes.txt'anchors_path = 'model_data/yolo_anchors.txt'class_names = get_classes(classes_path)num_classes = len(class_names)anchors = get_anchors(anchors_path)input_shape = (416, 416) # multiple of 32, hwis_tiny_version = len(anchors) == 6 # default settingif is_tiny_version:model = create_tiny_model(input_shape, anchors, num_classes,freeze_body=2, weights_path='model_data/tiny_yolo_weights.h5')else:model = create_model(input_shape, anchors, num_classes,freeze_body=2, weights_path='model_data/yolo_weights.h5') # make sure you know what you freezelogging = TensorBoard(log_dir=log_dir)checkpoint = ModelCheckpoint(log_dir + 'ep{epoch:03d}-loss{loss:.3f}-val_loss{val_loss:.3f}.h5',monitor='val_loss', save_weights_only=True, save_best_only=True, period=3)reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=3, verbose=1)early_stopping = EarlyStopping(monitor='val_loss', min_delta=0, patience=10, verbose=1)val_split = 0.1with open(annotation_path) as f:lines = f.readlines()np.random.seed(10101)np.random.shuffle(lines)np.random.seed(None)num_val = int(len(lines)*val_split)num_train = len(lines) - num_val# Train with frozen layers first, to get a stable loss.# Adjust num epochs to your dataset. This step is enough to obtain a not bad model.if True:model.compile(optimizer=Adam(lr=1e-3), loss={# use custom yolo_loss Lambda layer.'yolo_loss': lambda y_true, y_pred: y_pred})batch_size = 32print('Train on {} samples, val on {} samples, with batch size {}.'.format(num_train, num_val, batch_size))model.fit_generator(data_generator_wrapper(lines[:num_train], batch_size, input_shape, anchors, num_classes),steps_per_epoch=max(1, num_train//batch_size),validation_data=data_generator_wrapper(lines[num_train:], batch_size, input_shape, anchors, num_classes),validation_steps=max(1, num_val//batch_size),epochs=50,initial_epoch=0,callbacks=[logging, checkpoint])model.save_weights(log_dir + 'trained_weights_stage_1.h5')# Unfreeze and continue training, to fine-tune.# Train longer if the result is not good.if True:for i in range(len(model.layers)):model.layers[i].trainable = Truemodel.compile(optimizer=Adam(lr=1e-4), loss={'yolo_loss': lambda y_true, y_pred: y_pred}) # recompile to apply the changeprint('Unfreeze all of the layers.')batch_size = 32 # note that more GPU memory is required after unfreezing the bodyprint('Train on {} samples, val on {} samples, with batch size {}.'.format(num_train, num_val, batch_size))model.fit_generator(data_generator_wrapper(lines[:num_train], batch_size, input_shape, anchors, num_classes),steps_per_epoch=max(1, num_train//batch_size),validation_data=data_generator_wrapper(lines[num_train:], batch_size, input_shape, anchors, num_classes),validation_steps=max(1, num_val//batch_size),epochs=100,initial_epoch=50,callbacks=[logging, checkpoint, reduce_lr, early_stopping])model.save_weights(log_dir + 'trained_weights_final.h5')# Further training if needed.def get_classes(classes_path):'''loads the classes'''with open(classes_path) as f:class_names = f.readlines()class_names = [c.strip() for c in class_names]return class_namesdef get_anchors(anchors_path):'''loads the anchors from a file'''with open(anchors_path) as f:anchors = f.readline()anchors = [float(x) for x in anchors.split(',')]return np.array(anchors).reshape(-1, 2)def create_model(input_shape, anchors, num_classes, load_pretrained=True, freeze_body=2,weights_path='model_data/yolo_weights.h5'):'''create the training model'''K.clear_session() # get a new sessionimage_input = Input(shape=(None, None, 3))h, w = input_shapenum_anchors = len(anchors)y_true = [Input(shape=(h//{0:32, 1:16, 2:8}[l], w//{0:32, 1:16, 2:8}[l], \num_anchors//3, num_classes+5)) for l in range(3)]model_body = yolo_body(image_input, num_anchors//3, num_classes)print('Create YOLOv3 model with {} anchors and {} classes.'.format(num_anchors, num_classes))if load_pretrained:model_body.load_weights(weights_path, by_name=True, skip_mismatch=True)print('Load weights {}.'.format(weights_path))if freeze_body in [1, 2]:# Freeze darknet53 body or freeze all but 3 output layers.num = (185, len(model_body.layers)-3)[freeze_body-1]for i in range(num): model_body.layers[i].trainable = Falseprint('Freeze the first {} layers of total {} layers.'.format(num, len(model_body.layers)))model_loss = Lambda(yolo_loss, output_shape=(1,), name='yolo_loss',arguments={'anchors': anchors, 'num_classes': num_classes, 'ignore_thresh': 0.5})([*model_body.output, *y_true])model = Model([model_body.input, *y_true], model_loss)return modeldef create_tiny_model(input_shape, anchors, num_classes, load_pretrained=True, freeze_body=2,weights_path='model_data/tiny_yolo_weights.h5'):'''create the training model, for Tiny YOLOv3'''K.clear_session() # get a new sessionimage_input = Input(shape=(None, None, 3))h, w = input_shapenum_anchors = len(anchors)y_true = [Input(shape=(h//{0:32, 1:16}[l], w//{0:32, 1:16}[l], \num_anchors//2, num_classes+5)) for l in range(2)]model_body = tiny_yolo_body(image_input, num_anchors//2, num_classes)print('Create Tiny YOLOv3 model with {} anchors and {} classes.'.format(num_anchors, num_classes))if load_pretrained:model_body.load_weights(weights_path, by_name=True, skip_mismatch=True)print('Load weights {}.'.format(weights_path))if freeze_body in [1, 2]:# Freeze the darknet body or freeze all but 2 output layers.num = (20, len(model_body.layers)-2)[freeze_body-1]for i in range(num): model_body.layers[i].trainable = Falseprint('Freeze the first {} layers of total {} layers.'.format(num, len(model_body.layers)))model_loss = Lambda(yolo_loss, output_shape=(1,), name='yolo_loss',arguments={'anchors': anchors, 'num_classes': num_classes, 'ignore_thresh': 0.7})([*model_body.output, *y_true])model = Model([model_body.input, *y_true], model_loss)return modeldef data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes):'''data generator for fit_generator'''n = len(annotation_lines)i = 0while True:image_data = []box_data = []for b in range(batch_size):if i == 0:np.random.shuffle(annotation_lines)image, box = get_random_data(annotation_lines[i], input_shape, random=True)image_data.append(image)box_data.append(box)i = (i+1) % nimage_data = np.array(image_data)box_data = np.array(box_data)y_true = preprocess_true_boxes(box_data, input_shape, anchors, num_classes)yield [image_data, *y_true], np.zeros(batch_size)def data_generator_wrapper(annotation_lines, batch_size, input_shape, anchors, num_classes):n = len(annotation_lines)if n == 0 or batch_size <= 0:return Nonereturn data_generator(annotation_lines, batch_size, input_shape, anchors, num_classes)if __name__ == '__main__':_main()
成功开始训练,训练时间比较长,需要耐心等待
训练完成:
我的结果还没跑完,下面结果看看就行
训练好的权重都放在 logs 文件夹下的 000 文件夹里:
按理说训练会经过两个阶段,且自动从一堆 loss 中选则出 loss最低的文件(应该是 earlystop函数的作用):
应该就是下面的框选的这两个 h5文件,都可以使用
使用的方法就和前面那篇博文操作一样了(用这个h5权重模型去识别自己图片),
参考资料:
1、https://blog.csdn.net/qq_45504119/article/details/105052478 重点
2、https://blog.csdn.net/Patrick_Lxc/article/details/80615433
3、https://blog.csdn.net/m0_37857151/article/details/81330699
4、https://blog.csdn.net/mingqi1996/article/details/83343289
5、https://blog.csdn.net/davidlee8086/article/details/79693079
6、https://blog.csdn.net/u012746060/article/details/81183006
7、https://blog.csdn.net/weixin_45488478/article/details/98397947
8、https://blog.csdn.net/sinat_26917383/article/details/85614247?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase
9、
个人笔记本上win10+yolov3+python+tensorflow+keras训练自己的识别模型相关推荐
- Python基于keras训练简单微笑识别
文章目录 一.数据预处理 二.训练模型 创建模型 训练模型 训练结果 三.预测 效果 四.源代码 pretreatment.py train.py predict.py 一.数据预处理 实验数据来自g ...
- 使用Python+Tensorflow的CNN技术快速识别验证码
北京 上海巡回站 | NVIDIA DLI深度学习培训 2018年1月26/1月12日 NVIDIA 深度学习学院 带你快速进入火热的DL领域 阅读全文 ...
- python ocr中文训练_cnocr: cnocr是用来做中文OCR的Python 3包。cnocr自带了训练好的识别模型,安装后即可直接使用...
English README. cnocr 使用交流QQ群 欢迎扫码加入QQ交流群: 最近更新 [2020.05.29]:V1.2.2 主要变更: 优化了对数字识别的准确度. 优化了模型结构,进一步降 ...
- pythonocr训练模型_cnocr: cnocr是用来做中文OCR的Python 3包。cnocr自带了训练好的识别模型,安装后即可直接使用...
English README. cnocr 使用交流QQ群 欢迎扫码加入QQ交流群: Release Notes Update 2020.04.21: 发布 cnocr V1.1.0 V1.1.0对代 ...
- Win10系统Anaconda+TensorFlow+Keras 环境搭建教程
红色石头的个人网站:redstonewill.com 前天我在公众号推荐了<Python Deep Learning>这本书.该书是由 Keras 作者写的,所以全书基本围绕着 Keras ...
- 【Keras】Win10系统 + Anaconda+TensorFlow+Keras 环境搭建教程
1. 安装 Anaconda 打开 Anaconda 的官方下载地址:https://www.anaconda.com/download/ 选择 Python 对应的version 下载.下载完成后直 ...
- 云服务器上利用R运行tensorflow/keras
1. 利用virtualenv创建虚拟环境:我的环境名为r-tensorflow virtualenv 你的环境名 --python=python3.6(你想要的Python版本) 进入虚拟环境目录, ...
- python tensorflow pytorch 深度学习 车牌识别
车牌识别相关资料收集整理 1.License Plate Detection with RetinaFace 链接:https://github.com/zeusees/License-Plate-D ...
- 使用Python+OpenCV+Keras创建自己的图像分类模型
介绍 你是否曾经偶然发现一个数据集或图像,并想知道是否可以创建一个能够区分或识别图像的系统? 图像分类的概念将帮助我们解决这个问题.图像分类是计算机视觉最热门的应用之一,是任何想在这个领域工作的人都必 ...
最新文章
- java servlet post_Java中Servlet Post和Get乱码
- 互联网相似图像识别检索引擎 —— 基于图像签名的方式
- servlet解析演进(2-1)
- 如何避免Java线程中的死锁?
- 随机排列实现 -shuffle算法
- 作者:周涛,男,博士,教授级高工,就职于北京启明星辰信息安全技术有限公司。...
- 推荐两款工具给爱做实验的人
- linux nand 坏块_NAND Flash的坏块管理设计
- npm start 和 npm run start的关系以及npm run start传递参数
- 外包,你是外包,麻烦你不要偷吃公司零食,注意素质...
- 使用计算机能播放音乐也能观看视频,我电脑可以放歌有声音。怎么播放视频没声音啊?给我解决方案...
- Ubuntu20.04 + ROS Noetic 安装 Projectory Dave 仿真环境
- CORDIC算法 arctan反正切计算原理及C语言定点实现
- OpenGL ES 简介
- 爬取百度地图店家信息
- 本科课程【计算机网络】实验2 - 交换机的VLAN配置实验
- 苹果审核Metadata Rejected解决
- db(德邦快递单号查询)
- 实现一个简单的压测工具
- cmpp2.0 php,174短信发送状态回执错误码、返回值信息、错误原因