ssd训练自己数据集

1、用labelImg标数据

2、将数据转换为tfrecord

错误记录:

NotFoundError:无法创建NewWriteableFile 

解决方法:您需要在运行此脚本的运行环境文件夹中自己创建一个目录

1、前期准备工作

第一步:先将SSD框架下载到本地,解压出来;SSD源码下载

第二步:在解压出来的主目录下依次创建tfrecords_train_modelVOC2007文件夹,再将之前在SSD目标检测(2):如何制作自己的数据集(详细说明附源码)中制作的三个文件夹AnnotationsImageSetsJPEGImages全都拖入VOC2007文件夹内;
第2.5步:为方便操作不易混淆,请在PyCharm里建立工程;得到的截图如下,截图说明如下:

         1、请注意红色框VOCxxx使用的是具体的名字,不过一般都是VOC2007

         2、目录对应的从属关系不要出错

   3、tfrecords_文件夹是用来存储.tfrecords文件(后面有程序可以直接生成)

   4、train_model文件夹是用来存储模型的记录与参数的

这里写图片描述

2、生成.tfrecords文件的代码微调说明

第三步:修改标签项——打开datasets文件夹中pascalvoc_common.py文件,将自己的标签项填入。我之前做的图片标签.xml文件中,就只有一个标签项“watch”,所以要根据你自己数据集实际情况进行修改;

在这里插入图片描述

第四步:修改读取个数、读取方式——打开datasets文件夹中的pascalvoc_to_tfrecords.py文件,

  • 修改67行SAMPLES_PER_FILES的个数;
  • 修改83行读取方式为'rb'
  • 如果你的文件不是.jpg格式,也可以修改图片的类型;这里写图片描述

3、生成.tfrecords文件

第五步:生成.tfrecords文件——打开tf_convert_data.py文件,依次点击:run、Edit Configuration,在Parameters中填入以下内容,再运行tf_convert_data.py文件,在面板中得到成功信息,可以在tfrecords_文件夹下看到生成的.tfrecords文件;
 

--dataset_name=pascalvoc
--dataset_dir=./VOC2007/
--output_name=voc_2007_train
--output_dir=./tfrecords_

这里写图片描述

4、重新训练模型的代码微调说明

第六步:修改训练数据shape——打开datasets文件夹中的pascalvoc_2007.py文件,

    根据自己训练数据修改:NUM_CLASSES = 类别数;

说明:TRAIN_STATISTICS的数值我并没有深入了解,大于新数据集该标签的总数一般都不会报错。我的数据集是由20张、每张包含一只手表的图片组成,所以下图的值我设定为20,大于20也没有报错,如果你有更精确的想法,请留言告诉大家!
在这里插入图片描述

第七步:修改类别个数——打开nets文件夹中的ssd_vgg_300.py文件,

     根据自己训练类别数修改96 和97行:等于类别数+1

这里写图片描述

第八步:修改类别个数——打开eval_ssd_network.py文件,

        修改66行的类别个数:等于类别数+1

这里写图片描述

第九步:修改训练步数epoch——打开train_ssd_network.py文件

  • 修改27行的数据格式,改为'NHWC'
  • 修改135行的类别个数:等于类别数+1
  • 修改154行训练总步数,None会无限训练下去;
  • 说明:60行、63行是关于模型保存的参数;

这里写图片描述

5、加载vgg_16,重新训练模型

第十步:下载vgg_16模型——下载地址请点击,密码:ge3x;下载完成解压后存入checkpoint文件中;
最后一步:重新训练模型——打开train_ssd_network.py文件,依次点击:runEdit Configuration,在Parameters中填入以下内容,再运行train_ssd_network.py文件

--train_dir=./train_model/
--dataset_dir=./tfrecords_/
--dataset_name=pascalvoc_2007
--dataset_split_name=train
--model_name=ssd_300_vgg
--checkpoint_path=./checkpoints/vgg_16.ckpt
--checkpoint_model_scope=vgg_16
--checkpoint_exclude_scopes=ssd_300_vgg/conv6,ssd_300_vgg/conv7,ssd_300_vgg/block8,ssd_300_vgg/block9,ssd_300_vgg/block10,ssd_300_vgg/block11,ssd_300_vgg/block4_box,ssd_300_vgg/block7_box,ssd_300_vgg/block8_box,ssd_300_vgg/block9_box,ssd_300_vgg/block10_box,ssd_300_vgg/block11_box
--trainable_scopes=ssd_300_vgg/conv6,ssd_300_vgg/conv7,ssd_300_vgg/block8,ssd_300_vgg/block9,ssd_300_vgg/block10,ssd_300_vgg/block11,ssd_300_vgg/block4_box,ssd_300_vgg/block7_box,ssd_300_vgg/block8_box,ssd_300_vgg/block9_box,ssd_300_vgg/block10_box,ssd_300_vgg/block11_box
--save_summaries_secs=60
--save_interval_secs=100
--weight_decay=0.0005
--optimizer=adam
--learning_rate=0.001
--learning_rate_decay_factor=0.94
--batch_size=4
--gpu_memory_fraction=0.7

注意:上面是输入参数:

    --save_interval_secs是训练多少次保存参数的步长;
    --optimizer是优化器;
    --learning_rate是学习率;
    --learning_rate_decay_factor是学习率衰减因子;
    如果你的机器比较强大,可以适当增大--batch_size的数值,以及调高GPU的占比--gpu_memory_fraction
    --model_name:我并没有尝试使用其他的模型做增量训练,如果你有需要,也请留言联系我,我很乐意研究;

若得到下图日志,即说明模型开始训练:
在这里插入图片描述

训练结束可以在train_model文件夹下看到生成的参数文件;

在这里插入图片描述

到这里,训练终于结束了!!!

二、结果展示

这是我训练的loss,我的数据集总共就20张图片,进行4.8W次训练用了将近一个小时,我的配置是GTX1060的单显卡;

在这里插入图片描述

1、在日志中,选取最后一次生成模型作为测试模型进行测试;
2、在demo文件夹下放入测试图片;
3、最后在notebooks文件夹下建立demo_test.py测试文件,代码如下:
4、注意第48行,导入的新模型的名称是否正确

# -*- coding:utf-8 -*-
# -*- author:zzZ_CMing  CSDN address:https://blog.csdn.net/zzZ_CMing
# -*- 2018/07/20; 15:19
# -*- python3.6
import os
import math
import random
import numpy as np
import tensorflow as tf
import cv2
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from nets import ssd_vgg_300, ssd_common, np_methods
from preprocessing import ssd_vgg_preprocessing
from notebooks import visualization
import syssys.path.append('../')
slim = tf.contrib.slim
# TensorFlow session: grow memory when needed. TF, DO NOT USE ALL MY GPU MEMORY!!!
gpu_options = tf.GPUOptions(allow_growth=True)
config = tf.ConfigProto(log_device_placement=False, gpu_options=gpu_options)
isess = tf.InteractiveSession(config=config)# 定义数据格式,设置占位符
net_shape = (300, 300)
# 输入图像的通道排列形式,'NHWC'表示 [batch_size,height,width,channel]
data_format = 'NHWC'
# 预处理,以Tensorflow backend, 将输入图片大小改成 300x300,作为下一步输入
img_input = tf.placeholder(tf.uint8, shape=(None, None, 3))
# 数据预处理,将img_input输入的图像resize为300大小,labels_pre,bboxes_pre,bbox_img待解析
image_pre, labels_pre, bboxes_pre, bbox_img = ssd_vgg_preprocessing.preprocess_for_eval(img_input, None, None, net_shape, data_format, resize=ssd_vgg_preprocessing.Resize.WARP_RESIZE)
# 拓展为4维变量用于输入
image_4d = tf.expand_dims(image_pre, 0)# 定义SSD模型
# 是否复用,目前我们没有在训练所以为None
reuse = True if 'ssd_net' in locals() else None
# 调出基于VGG神经网络的SSD模型对象,注意这是一个自定义类对象
ssd_net = ssd_vgg_300.SSDNet()
# 得到预测类和预测坐标的Tensor对象,这两个就是神经网络模型的计算流程
with slim.arg_scope(ssd_net.arg_scope(data_format=data_format)):predictions, localisations, _, _ = ssd_net.net(image_4d, is_training=False, reuse=reuse)# 导入新训练的模型参数
ckpt_filename = '../train_model/model.ckpt-xxx'   # 注意xxx代表的数字是否和文件夹下的一致
# ckpt_filename = '../checkpoints/VGG_VOC0712_SSD_300x300_ft_iter_120000.ckpt'
isess.run(tf.global_variables_initializer())
saver = tf.train.Saver()
saver.restore(isess, ckpt_filename)# 在网络模型结构中,提取搜索网格的位置
# 根据模型超参数,得到每个特征层(这里用了6个特征层,分别是4,7,8,9,10,11)的anchors_boxes
ssd_anchors = ssd_net.anchors(net_shape)
"""
每层的anchors_boxes包含4个arrayList,前两个List分别是该特征层下x,y坐标轴对于原图(300x300)大小的映射
第三,四个List为anchor_box的长度和宽度,同样是经过归一化映射的,根据每个特征层box数量的不同,这两个List元素
个数会变化。其中,长宽的值根据超参数anchor_sizes和anchor_ratios制定。
"""# 主流程函数
def process_image(img, select_threshold=0.6, nms_threshold=.01, net_shape=(300, 300)):# select_threshold:box阈值——每个像素的box分类预测数据的得分会与box阈值比较,高于一个box阈值则认为这个box成功框到了一个对象# nms_threshold:重合度阈值——同一对象的两个框的重合度高于该阈值,则运行下面去重函数# 执行SSD模型,得到4维输入变量,分类预测,坐标预测,rbbox_img参数为最大检测范围,本文固定为[0,0,1,1]即全图rimg, rpredictions, rlocalisations, rbbox_img = isess.run([image_4d, predictions, localisations, bbox_img],feed_dict={img_input: img})# ssd_bboxes_select()函数根据每个特征层的分类预测分数,归一化后的映射坐标,# ancohor_box的大小,通过设定一个阈值计算得到每个特征层检测到的对象以及其分类和坐标rclasses, rscores, rbboxes = np_methods.ssd_bboxes_select(rpredictions, rlocalisations, ssd_anchors,select_threshold=select_threshold, img_shape=net_shape, num_classes=21, decode=True)"""这个函数做的事情比较多,这里说的细致一些:首先是输入,输入的数据为每个特征层(一共6个,见上文)的:rpredictions: 分类预测数据,rlocalisations: 坐标预测数据,ssd_anchors: anchors_box数据其中:分类预测数据为当前特征层中每个像素的每个box的分类预测坐标预测数据为当前特征层中每个像素的每个box的坐标预测anchors_box数据为当前特征层中每个像素的每个box的修正数据函数根据坐标预测数据和anchors_box数据,计算得到每个像素的每个box的中心和长宽,这个中心坐标和长宽会根据一个算法进行些许的修正,从而得到一个更加准确的box坐标;修正的算法会在后文中详细解释,如果只是为了理解算法流程也可以不必深究这个,因为这个修正算法属于经验算法,并没有太多逻辑可循。修正完box和中心后,函数会计算每个像素的每个box的分类预测数据的得分,当这个分数高于一个阈值(这里是0.5)则认为这个box成功框到了一个对象,然后将这个box的坐标数据,所属分类和分类得分导出,从而得到:rclasses:所属分类rscores:分类得分rbboxes:坐标最后要注意的是,同一个目标可能会在不同的特征层都被检测到,并且他们的box坐标会有些许不同,这里并没有去掉重复的目标,而是在下文中专门用了一个函数来去重"""# 检测有没有超出检测边缘rbboxes = np_methods.bboxes_clip(rbbox_img, rbboxes)rclasses, rscores, rbboxes = np_methods.bboxes_sort(rclasses, rscores, rbboxes, top_k=400)# 去重,将重复检测到的目标去掉rclasses, rscores, rbboxes = np_methods.bboxes_nms(rclasses, rscores, rbboxes, nms_threshold=nms_threshold)# 将box的坐标重新映射到原图上(上文所有的坐标都进行了归一化,所以要逆操作一次)rbboxes = np_methods.bboxes_resize(rbbox_img, rbboxes)return rclasses, rscores, rbboxes# 测试的文件夹
path = '../demo/'
image_names = sorted(os.listdir(path))
# 文件夹中的第几张图,-1代表最后一张
img = mpimg.imread(path + image_names[-1])
rclasses, rscores, rbboxes = process_image(img)# visualization.bboxes_draw_on_img(img, rclasses, rscores, rbboxes, visualization.colors_plasma)
visualization.plt_bboxes(img, rclasses, rscores, rbboxes)

结果展示:这是我自己拍的照片,得到的识别效果还算勉强吧(请自动忽略我那性感的手毛!)

在这里插入图片描述

如果你的测试结果是下面这样的:

导致的原因:

   1 训练次数太少,loss过高——解决方法除了优化数据集外,就是增大训练次数(要明白谷歌公布的模型都是在大型集群上训练好多天的结果,我们就在GTX1060单显卡上训练4.8W次就想出非常好的结果?偶然的成功比失败更可怕,而且想弯道超谷歌不太可能吧!)
   2 另外上面程序65行的select_threshold、 nms_threshold参数你也可以做调整;观察下图可以发现误标框框的预测值都小于0.55,而唯一正确的框框预测值等于0.866。所以认真理解上面程序66、67行我写的注释,对你的问题会有帮助;
在这里插入图片描述

本博客用的测试数据集在这,只有20张标记图片。并不包含最后训练得到的模型

参考自https://blog.csdn.net/zzZ_CMing/article/details/81131523

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/567788.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

elasticsearch date_MySQL数据实时增量同步到Elasticsearch

Mysql到Elasticsearch的数据同步,一般用ETL来实现,但性能并不理想,目前大部分的ETL是定时查询Mysql数据库有没有新增数据或者修改数据,如果数据量小影响不大,但如果几百万上千万的数据量性能就明显的下降很多&#xff…

联想计算机不能进入系统桌面,联想笔记本进不去桌面的解决方法

联想笔记本进不去桌面的解决方法笔记本电脑开机后,电源指示灯亮,显示器屏如果有显示,但进不了系统,这种情况多数是系统故障导致的,可以尝试开机按F8键,进入安全模式,然后进入最后一次安全配置进…

win10 make命令的安装

1、下载MinGWMinGW官网下载:http://www.mingw.org ,点击右上角Downloads 或者网盘下载:链接:https://pan.baidu.com/s/1vQVKycK1TKVsnLV_OMgiCg 提取码:bbhl 点击下载 mingw-get-setup.exe 安装 mingw-get-setup.exe…

html中svg的css,HTML5 内联 SVG

什么是SVG?SVG 指可伸缩矢量图形 (Scalable Vector Graphics)SVG 用于定义用于网络的基于矢量的图形SVG 使用 XML 格式定义图形SVG 图像在放大或改变尺寸的情况下其图形质量不会有损失SVG 是万维网联盟的标准SVG 的优势与其他图像格式相比(比如 JPEG 和 GIF)&#x…

fast-rcnn win10 tensorflow部署

1、下载代码https://github.com/chde222/Faster-RCNN-TensorFlow-Python3 2、安装所依赖包 pip install -r requirements.txt 或者单独利用pip install cython pip install easydict 3、在 ./data/coco/pythonAPI 下打开cmd运行: python setup.py build_ext --in…

vue 获取url地址的参数_Vue之vuerouter的使用

1. 什么是vue-router?所谓的vue-router, 通俗的来讲 就是路由 但是这个和后端路由是不同的, 这是前端路由,是url和单页面组件的对应关系, 也就是SPA(单页应用)的路径管理器。再通俗的说,vue-router就是WebApp的链接路径管理系统。vue-router是Vue.js官方的路由插件…

win10下openpose1.5安装

历经一个星期的安装挫折,终于安装成功了。赶紧记录一下。 1、准备所需资料 (1)下载cuda和cudnn。版本最好都是cuda10和cudnn10.我下载的是下图所示版本。 如果不是这个版本可能会出错,而且出错几率很高。本人就因为安装的cuda10…

div展示html文本,html – 使文本适合div

我一直在努力重新创建我在90年代创建的父亲网站(呃),我一直无法让文本适合div内部并水平对齐.我需要将文本放在一起,以便它们适合div.这是jsfiddle中页面的代码示例HTMLHomeInside StaffOur Mission示例CSSdiv img#header{width: 50%;height: 15%;margin-left: 125px;margin-ri…

ImportError: cannot import name 'pyopenpose' from 'openpose'错误解决方法

前提条件:openpose1.5配置过程前面都成功,c api成功运行,但是python api配置中,cmake也添加了build_python_path.运行中仍出现 ImportError: cannot import name pyopenpose from openpose 这个错误。 解决方法: 将你…

python语句join_详解Python中的join()函数的用法

原博文 2017-08-07 20:51 − 函数:string.join() Python中有join()和os.path.join()两个函数,具体作用如下: join(): 连接字符串数组。将字符串、元组、列表中的元素以指定的字符(分隔符)连接生成一个新的字符串 &n...0584 相…

python glob.glob使用

函数功能:匹配所有的符合条件的文件,并将其以list的形式返回 示例: 当前文件夹下有如下文件 import globlist glob.glob(‘*g’)print(list) 结果: [dog.1012.jpg, dog.1013.jpg, dog.1014.jpg, dog.1015.jpg, dog.1016.jpg]

nohup启动jar_nohup命令详解

nohup命令详解在我们想要把SpringBoot微服务工程部署到远程服务器时,会通过java -jar springboot.jar的方式启动SpringBoot微服务。但是当我们把运行这个命令的SSH客户端退出登录就会导致SpringBoot进程也一起停止了,然后当然就没法访问我们启动的项目了…

python用pip安装pygame_安装pygame和pip的问题以及过程

1. 先安装pip(一个重要的工具cnqqtd) 2. 安装与python版和系统本相匹配的pygame 详细安装过程 Pip请到这里安装 https://pypi.python.org/pypi/pip#download 下载完成后,会获得一个叫git-pip.py的文件 • 打开git-pip.py文件存在的目录,按下shift rightClick • 打开windows Po…

.net fileupload批量上传可删除_【JavaWeb基础】文件上传和下载(修订版)

前言只有光头才能变强。文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y什么是文件上传?文件上传就是把用户的信息保存起来。为什么需要文件上传?在用户注册的时候,可能需要用户提交照片。…

object detection之Win10配置

1、下载models。 https://github.com/tensorflow/models 并文件解压。 2、下载protos文件 https://github.com/protocolbuffers/protobuf/releases?afterv3.9.1 我这里下载的3.7.0版本。注意一定要下载protoc-xxx-win64.zip版本。必须是带有win64的压缩包,否则可…

idea卸载不干净怎么办_fxfactory卸载不干净?Fxfactory及插件卸载教程

fxfactory卸载不干净怎么办?fxfactory是一款非常受欢迎的视频特效插件合集,能应用到FCPX、AE、PR、motion等软件中。过多特效插件下载会导致这些软件运行打开速度慢,那么如何卸载fxfactory这款软件或者删除那些特效插件呢?跟随小编…

矩阵标准型的系数是特征值吗_「线性代数」根据特征值,将二次型化为标准形、规范形...

今天我们来聊一聊线性代数中的二次型化为规范形、标准形的内容,这块知识相当重要,我看了看,几乎每一年的考研数学中都会涉及到一道关于这个知识点的题目,这次的整理,不仅帮助大家整理清楚思路,也是为自己整…

计算机丢失UxTheme无法修复,Win7系统启动程序失败提示“计算机中丢失UxTheme.dll”怎么办...

win7系统启动程序失败出错提示”无法启动此程序,因为计算机中丢失UxTheme.dll。尝试重新安装该程序以解决此问题“怎么办呢?UxTheme.dll是什么?其实UxTheme.dll是支持win7主题的核心文件,丢失UxTheme.dll就无法使用第三方主题了&a…

docker 设置 jvm 内存_是否值得付费?Oracle,Open JDK等四大JVM性能全面对比

市面上可供选择的JVM发行版还是有不少的。选择合适的JVM需要考虑不同的因素。性能是其中一个重要的因素。靠谱的性能研究是很困难的。在本文中,我创建了一个测试,在不同的JVM上执行对比测试。测试程序包括Spring Boot REST应用,使用Prometheu…

计算机考研初试复试比例,考研初试400多分,16人都被刷,计算机专业报考人太多,报应来了...

在目前大家都一味地挤着报考计算机专业,其他工科专业都被抛弃,以至于很多考研分数400的依然是被刷掉,这就是近期天津大学计算机专业考研复试的情况,在以前,考400以上都被称之为神人,但现在报考计算机专业40…