致谢声明

1.本文学习Patrick_Lxc的博客《Keras/Tensorflow+python+yolo3训练自己的数据集》并优化其中代码。
原博客链接:https://blog.csdn.net/Patrick_Lxc/article/details/80615433
2.本文学习qqwweee的github工程《keras-yolo3》并优化其中代码。
github链接:https://github.com/qqwweee/keras-yolo3

0.配置代码运行环境

0.1 硬件配置要求

YOLOv3对于电脑的显卡要求高,根据本文作者的经验,至少需要8GB的显存才能继续本文下面的实验。
只有Nvidia品牌的显卡可以运行深度学习,AMD品牌的显卡不可以运行深度学习。
那么Nvidia品牌具有8GB显存的最低价格显卡的型号为GTX1070。
2019年2月28日查询,京东上原装GTX1070的价格如下图所示:

Screenshot from 2019-02-21 17-15-49.png

2019年2月28日查询,淘宝上网吧二手拆机显卡GTX1070的价格为1800元左右,如下图所示:

Screenshot from 2019-02-21 17-21-07.png

如果购买资金充足,建议购买GTX1080Ti,11G显存可以运行准确率更高的YOLOv3-spp算法模型。
如果购买资金不足,最少也得购买GTX1070,否则无法继续本文下面的实验。
如果没有nvidia显卡,但有visa信用卡,请阅读我的另一篇文章《在谷歌云服务器上搭建深度学习平台》,链接: https://www.jianshu.com/p/893d622d1b5a

0.2 软件配置要求

各种软件版本:
Ubuntu :16.04
Anaconda :5.2
python : 3.6
CUDA :9.0
cudnn :7.3
tensorflow_gpu :1.10
Keras :2.2.4
如果有显存为8G的显卡,在Windows操作系统下也无法运行本文下面的代码。会报错"显存不足"。
所以读者需要安装Ubuntu操作系统,建议选择Ubuntu16.04,制作系统U盘后非常容易安装。
如果有显存为11G的显卡,在Windows操作系统下可以继续本文下面的实验。
有显卡之后需要配置深度学习环境,请阅读我的另一篇文章《深度学习环境搭建-CUDA9.0、cudnn7.3、tensorflow_gpu1.10的安装》,链接:https://www.jianshu.com/p/4ebaa78e0233

1.数据准备

1.1 数据下载

如果读者有自己已经使用labelImg软件标注好的数据,可以直接跳到1.4节图片压缩。
本文作者给读者演示的图片数据是来自ImageNet中的鲤鱼分类。
数据集压缩文件下载链接: https://pan.baidu.com/s/1NksESNqBX--YqMJ4zptGdw 提取码: 6p3u
本文作者在桌面中创建文件夹keras_YOLOv3,并将下载好的数据集压缩文件n01440764.tar放到其中,如下图所示:

image.png

在文件夹 keras_YOLOv3中鼠标右击,在显示的菜单中选择 Open in Terminal,即在文件夹 keras_YOLOv3中打开Terminal。
作为合格的Ubuntu系统使用者,要求会使用终端Terminal中的命令完成操作。
运行命令 mkdir n01440764创建文件夹 n01440764
运行命令 tar -xvf n01440764.tar -C n01440764完成压缩文件的解压,命令其中的-C参数后面必须为已经存在的文件夹,否则运行命令会报错。
解压完成后,文件夹和终端Terminal中的情况如下图所示:

image.png

1.2 在Ubuntu中安装软件labelImg

需要使用软件labelImg做图片的数据标注。
软件labelImg的下载地址:https://github.com/tzutalin/labelImg,页面如下图所示:

image.png

在文件夹 keras_YOLOv3中打开Terminal,运行下列命令:
1.加快apt-get命令的下载速度,需要做Ubuntu系统的换源。方法如下:
在Ubuntu的设置Settings中选择 Software & Updates,将Download from的值设置为 http://mirrors.aliyun.com/ubuntu,如下图所示:

image.png

2.运行命令 wget https://codeload.github.com/tzutalin/labelImg/zip/master -O labelImg-master.zip从github上下载labelImg的源码压缩文件。
3.运行命令 unzip labelImg-master.zip完成压缩文件的解压。
4.运行命令 sudo apt-get install pyqt5-dev-tools安装软件pyqt5-dev-tools。
5.运行命令 cd labelImg-master进入文件夹labelImg-master。
6.运行命令 pip install -r requirements/requirements-linux-python3.txt安装软件labelImg运行时需要的库,如果已经安装Anaconda此步可能不用进行。如果pip下载库的速度慢,请查看我的另外一篇文章《pip换源》,
链接: https://www.jianshu.com/p/46c17698bd4b
7.运行命令 make qt5py3编译产生软件labelImg运行时需要的组件。
8.运行命令 python labelImg.py运行代码文件labelImg.py,运行结果如下图所示:

image.png

1.3 获取像素足够的图片

新建一个代码文件generate_qualified_images.py或generate_qualified_images.ipynb,将下面一段代码复制到其中。
运行代码可以获取文件夹n01440764中的200张像素足够的图片,存放在文件夹selected_images中。
因为文件夹n01440764中有一部分图片像素不足416 * 416,不利于模型训练,所以本节内容有必要进行。

import os
import random
from PIL import Image
import shutil#获取文件夹中的文件路径
def getFilePathList(dirPath, partOfFileName=''):allFileName_list = list(os.walk(dirPath))[0][2]fileName_list = [k for k in allFileName_list if partOfFileName in k]filePath_list = [os.path.join(dirPath, k) for k in fileName_list]return filePath_list#获取一部分像素足够,即长,宽都大于416的图片
def generate_qualified_images(dirPath, sample_number, new_dirPath):jpgFilePath_list = getFilePathList(dirPath, '.JPEG')random.shuffle(jpgFilePath_list)if not os.path.isdir(new_dirPath):os.makedirs(new_dirPath)i = 0for jpgFilePath in jpgFilePath_list:image = Image.open(jpgFilePath)width, height = image.sizeif width >= 416 and height >= 416:i += 1new_jpgFilePath = os.path.join(new_dirPath, '%03d.jpg' %i)shutil.copy(jpgFilePath, new_jpgFilePath)if i == sample_number:break#获取数量为100的合格样本存放到selected_images文件夹中
generate_qualified_images('n01440764', 200, 'selected_images')

1.4 数据标注

数据标注是一件苦力活,本文作者标记200张图片花费90分钟左右。
本节演示单张图片的标注。
如下图红色箭头标记处所示,打开数据集文件夹。

image.png

如下图红色箭头标记处所示,选择文件夹 keras_YOLOv3中的文件夹 selected_images,选中后点击如下图下方红色箭头标记处所示的Choose按钮。

image.png

如下图红色箭头标记处所示,给这张图标记了2个物体:人脸human_face、鱼fish
在软件labelImg界面中,按w键即可开始标记物体。

image.png

本文作者标注好200张图片,上传到百度云盘,便于读者直接复现。
下载链接: https://pan.baidu.com/s/1-bZ5B5JKFB7R6aWUPBdP_w 提取码: 9rjg

1.5 检查标注数据

新建一个代码文件check_annotations.py或check_annotations.ipynb,将下面一段代码复制到其中。
运行代码可以完成2个检查功能:
1.检查代码检查标记好的文件夹是否有图片漏标
2.此段代码检查标记的xml文件中是否有物体标记类别拼写错误

#获取文件夹中的文件路径
import os
def getFilePathList(dirPath, partOfFileName=''):allFileName_list = list(os.walk(dirPath))[0][2]fileName_list = [k for k in allFileName_list if partOfFileName in k]filePath_list = [os.path.join(dirPath, k) for k in fileName_list]return filePath_list#此段代码检查标记好的文件夹是否有图片漏标
def check_1(dirPath):jpgFilePath_list = getFilePathList(dirPath, '.jpg')allFileMarked = Truefor jpgFilePath in jpgFilePath_list:xmlFilePath = jpgFilePath[:-4] + '.xml'if not os.path.exists(xmlFilePath):print('%s this picture is not marked.' %jpgFilePath)allFileMarked = Falseif allFileMarked:print('congratulation! it is been verified that all jpg file are marked.')#此段代码检查标记的xml文件中是否有物体标记类别拼写错误
import xml.etree.ElementTree as ET
def check_2(dirPath, className_list):className_set = set(className_list)xmlFilePath_list = getFilePathList(dirPath, '.xml')allFileCorrect = Truefor xmlFilePath in xmlFilePath_list:with open(xmlFilePath) as file:fileContent = file.read()root = ET.XML(fileContent)object_list = root.findall('object')for object_item in object_list:name = object_item.find('name')className = name.textif className not in className_set:print('%s this xml file has wrong class name "%s" ' %(xmlFilePath, className))allFileCorrect = Falseif allFileCorrect:print('congratulation! it is been verified that all xml file are correct.')if __name__ == '__main__':dirPath = 'selected_images'className_list = ['fish', 'human_face']check_1(dirPath)check_2(dirPath, className_list)

1.6 图像压缩

预先压缩好图像,模型训练时不用再临时改变图片大小,或许可以加快模型训练速度。
新建一个代码文件compress_images.py或compress_images.ipynb,将下面一段代码复制到其中。
运行代码可以完成2个功能:
1.将旧文件夹中的jpg文件压缩后放到新文件夹中。
2.将旧文件夹中的jpg文件对应的xml文件修改后放到新文件夹中。

#获取文件夹中的文件路径
import os
def getFilePathList(dirPath, partOfFileName=''):allFileName_list = list(os.walk(dirPath))[0][2]fileName_list = [k for k in allFileName_list if partOfFileName in k]filePath_list = [os.path.join(dirPath, k) for k in fileName_list]return filePath_list#生成新的xml文件
import xml.etree.ElementTree as ET
def generateNewXmlFile(old_xmlFilePath, new_xmlFilePath, new_size):new_width, new_height = new_sizewith open(old_xmlFilePath) as file:fileContent = file.read()root = ET.XML(fileContent)#获得图片宽度变化倍数,并改变xml文件中width节点的值width = root.find('size').find('width')old_width = int(width.text)width_times = new_width / old_widthwidth.text = str(new_width)#获得图片高度变化倍数,并改变xml文件中height节点的值height = root.find('size').find('height')old_height = int(height.text)height_times = new_height / old_heightheight.text = str(new_height)#获取标记物体的列表,修改其中xmin,ymin,xmax,ymax这4个节点的值object_list = root.findall('object')for object_item in object_list:bndbox = object_item.find('bndbox')xmin = bndbox.find('xmin')xminValue = int(xmin.text)xmin.text = str(int(xminValue * width_times))ymin = bndbox.find('ymin')yminValue = int(ymin.text)ymin.text = str(int(yminValue * height_times))xmax = bndbox.find('xmax')xmaxValue = int(xmax.text)xmax.text = str(int(xmaxValue * width_times))ymax = bndbox.find('ymax')ymaxValue = int(ymax.text)ymax.text = str(int(ymaxValue * height_times))tree = ET.ElementTree(root)tree.write(new_xmlFilePath)#修改文件夹中的若干xml文件
def batch_modify_xml(old_dirPath, new_dirPath, new_size):xmlFilePath_list = getFilePathList(old_dirPath, '.xml')for xmlFilePath in xmlFilePath_list:xmlFileName = os.path.split(xmlFilePath)[1]new_xmlFilePath = os.path.join(new_dirPath, xmlFileName)generateNewXmlFile(xmlFilePath, new_xmlFilePath, new_size)#生成新的jpg文件
from PIL import Image
def generateNewJpgFile(old_jpgFilePath, new_jpgFilePath, new_size):old_image = Image.open(old_jpgFilePath)new_image = old_image.resize(new_size, Image.ANTIALIAS)new_image.save(new_jpgFilePath)#修改文件夹中的若干jpg文件
def batch_modify_jpg(old_dirPath, new_dirPath, new_size):if not os.path.isdir(new_dirPath):os.makedirs(new_dirPath)xmlFilePath_list = getFilePathList(old_dirPath, '.xml')for xmlFilePath in xmlFilePath_list:old_jpgFilePath = xmlFilePath[:-4] + '.jpg'jpgFileName = os.path.split(old_jpgFilePath)[1]new_jpgFilePath = os.path.join(new_dirPath, jpgFileName)generateNewJpgFile(old_jpgFilePath, new_jpgFilePath, new_size)if __name__ == '__main__':old_dirPath = 'selected_images'new_width = 416new_height = 416new_size = (new_width, new_height)new_dirPath = 'images_%sx%s' %(str(new_width), str(new_height))batch_modify_jpg(old_dirPath, new_dirPath, new_size)batch_modify_xml(old_dirPath, new_dirPath, new_size)

标注好的200张压缩后的图片,上传到百度云盘,便于读者直接复现。
链接: https://pan.baidu.com/s/121Vh8gzDElpzz190kbdUOw 提取码: a2tb

2.模型训练

2.1 下载github上的代码库

下载github上的代码库,链接:https://github.com/StevenLei2017/keras-yolo3
下载操作如下图所示,点击图中的Download ZIP

image.png

压缩文件 keras-yolo3-master.zip移动到文件夹 keras_YOLOv3中。
运行命令 unzip keras-yolo3-master.zip完成压缩文件的解压。
上面2步完成后,文件夹 keras_YOLOv3中示意图如下:

image.png

2.2 划分训练集和测试集

1.将文件夹images_416*416移动到文件夹keras-yolo3-master中,如下图所示:

image.png

2.打开文件夹 keras-yolo3-master中的文件夹 model_data,编辑其中的文件 voc_names.txt
文件 voc_names.txt中每1行代表1个类别。
3.文件夹 keras-yolo3-master中打开终端Terminal,然后运行命令 python generateTxtFile.py -dir images_416*416会划分训练集和测试集,并产生与之对应的文本文件。
训练集文件 dataset_train.txt,测试集文件 dataset_test.txt,如下图所示:

image.png

2.3 开始训练

文件夹keras-yolo3-master中打开终端Terminal,然后运行命令python train.py即可开始训练。
训练过程截图如下图所示:
从图中下方红色方框处可以看出每个epoch需要大约15秒,则200个epoch约1个小时能够运行完成。

image.png

3.模型测试

4.总结

1.本篇教程非常易于新手展开目标检测框架YOLOv3的实践。
2.此篇文章的代码集成性强,当读者做好数据准备后,只需要很短的时间即可完成模型训练的部署。

目标检测第5步-使用keras版YOLOv3训练相关推荐

  1. 目标检测:EfficientDet(官方开源版)训练自己的数据

    写在前面: 本教程将介绍从原始标注数据到训练EfficientDet的全部过程,适合入门级选手,你将得到: (1)详细的步骤介绍 (2)数据集处理代码 (3)EfficientDet训练示例代码 (4 ...

  2. 目标检测第3步:如何在Windows 10系统下安装CUDA(更新时间2022.03.22)

    (请先看置顶博文)本博打开方式!!!请详读!!!请详读!!!请详读!!!_Cat-CSDN博客 目录 一.自检 1.查看PC是否有NVIDIA的独立显卡 2.查看自己NVIDIA独立显卡是否支持CUD ...

  3. 目标检测第4步:显卡、GPU、CUDA、cuDNN的介绍及如何在Windows 10下安装cuDNN?

    (请先看置顶博文)本博打开方式!!!请详读!!!请详读!!!请详读!!!_Cat-CSDN博客 目录 (请先看置顶博文)本博打开方式!!!请详读!!!请详读!!!请详读!!!_Cat-CSDN博客 一 ...

  4. 目标检测第7步:如何在Windows 10下,配置Pycharm中的YOLOv5(5.0)虚拟环境?

    (请先看这篇文章:本博打开方式!!!请详读!!!请详读!!!请详读!!!_Cat-CSDN博客) 这一篇博文和这一篇有异曲同工之妙,有兴趣的同学可以看一下:目标检测第5步:如何在Windows 10系 ...

  5. 目标检测第5步:如何在Windows 10系统下,搭建YOLOv5(5.0)环境?保姆级,没有人比这个更详细了(更新时间2022.3.22)

    (请先看置顶博文)本博打开方式!!!请详读!!!请详读!!!请详读!!!_Cat-CSDN博客 目录 一.安装Anaconda或Miniconda 二.安装CUDA 三.安装cuDNN 四.安装Pyt ...

  6. [Intensive Reading]目标检测(object detection)系列(九) YOLOv3:取百家所长成一家之言

    目标检测系列: 目标检测(object detection)系列(一) R-CNN:CNN目标检测的开山之作 目标检测(object detection)系列(二) SPP-Net:让卷积计算可以共享 ...

  7. 深度学习论文阅读目标检测篇(六)中文版:YOLOv3《 An Incremental Improvement》

    深度学习论文阅读目标检测篇(六)中文版:YOLOv3< An Incremental Improvement> 摘要 1. 引言 2. 方案 2.1. 边界框预测 2.2. Class P ...

  8. keras版yolov3绘制acc和loss曲线

    keras版yolov3绘制acc和loss曲线 基本概念 程序 基本概念 loss表示损失函数值,随着训练过程的进行,loss会越来越小.acc表示模型预测准确率.写论文时,loss曲线和acc曲线 ...

  9. 深度学习目标检测:YOLOv5实现车辆检测(含车辆检测数据集+训练代码)

    深度学习目标检测:YOLOv5实现车辆检测(含车辆检测数据集+训练代码) 目录 深度学习目标检测:YOLOv5实现车辆检测(含车辆检测数据集+训练代码) 1. 前言 2. 车辆检测数据集说明 (1)车 ...

最新文章

  1. python读取excel画散点图-python学习之matplotlib绘制散点图实例
  2. C++ 函数--幽径初探索
  3. binlog2mysql,MySQL 数据恢复工具之binlog2sql
  4. css3蒙版运动,纯CSS3制作逼真的汽车运动动画
  5. MongoDB最简单的入门教程之四:使用Spring Boot操作MongoDB
  6. linux webapi测试,Webapi管理和性能测试工具WebBenchmark
  7. exit()函数_complete函数
  8. kaggle房价预测特征意思_Kaggle竞赛丨房价预测(House Prices)
  9. 06 php 单例模式
  10. 回顾:你对Windows 8了解有多少?开启浏览器javascr
  11. 【转】HP laserjet p2055dn的自动双面打印功能
  12. 2020年低压电工模拟考试题库及低压电工模拟考试系统
  13. 小程序公众图标素材6113个菜单栏素材
  14. 计算机丢失bass,dll,bassasio.dll(缺失bassasio.dll文件修复工具)V1.0 正式版
  15. Building Trustworthy Semantic Webs
  16. 8081端口被nexus占用的情况如何解决
  17. 代码获取DEP按钮及获取DEP控件
  18. 【水汐のpython】 用python抓取外网的本子站并获取本子封面和信息
  19. 小而巧的数字压缩算法:zigzag
  20. 让GIS三维可视化变得简单-初识Cesium

热门文章

  1. 索尼发布新Bravia液晶电视 84英寸4K分辨率!
  2. 王艾老哥------不是境况造就人,而是人造就境况。
  3. shell命令之ln
  4. Android自定义守望先锋loading学习
  5. Qt扫盲-QSlider理论总结
  6. 各种友(e)善(xin)数论总集(未完待续),从入门到绝望
  7. OWT Server信令分析 (下) [Open WebRTC Toolkit]
  8. 计算机程序占用端口,程序启动发现端口被占?3步查出它是谁!
  9. 用c语言写一个简单的名人名言播放器
  10. T检验 ANOVA