Tensorflow113目标检测训练过程

环境列表如下:Win10系统,tensorflow版本为1.13,python版本3.6,模型框架SSD。目标检测模型训练过程具体步骤如下:

1,制作Pascal VOC图片数据集:

参考博客如下:https://www.cnblogs.com/kxqblog/p/16122532.html

2,配置SSD:
(1)首先,下载SSD代码

由于本案例是基于tensorflow的,因此,在github上下载一个基于tensorflow的SSD,地址是 https://github.com/balancap/SSD-Tensorflow ,文件目录如下:

(2)转换文件格式

将voc_2007格式的文件转换为tfrecord格式,tfrecord数据文件为tensorflow中的一种将图像数据和标签统一存储的二进制文件,能更加快速地在tensorflow中复制、移动、读取和存储等。在window下打开终端并在SSD-Tensorflow-master的目录下执行以下命令。SSD-Tensorflow-master提供了转换格式的脚本,转换命令如下,注意此处转换格式时使用的tensorflow版本最好为tf1版本:

python tf_convert_data.py --dataset_name=pascalvoc --dataset_dir=C:\Users\username\Desktop\ImageData\Pascal_VOC\ --output_name=voc_2007_train --output_dir=C:\Users\username\Desktop\mobilnetv3_ssd\SSD-Tensorflow-Test\test_cat_tfrecord\

其中:

dataset_dir=C:\Users\username\Desktop\ImageData\Pascal_VOC\ #此处改为VOC数据集制做的文件夹
output_dir=C:\Users\username\Desktop\mobilnetv3_ssd\SSD-Tensorflow-Test\test_cat_tfrecord\ #将在执行处新建一个文件夹test_cat_tfrecord,这里我在SSD-Tensorflow-master文件夹下执行,因此将在此文件夹下新建一个名为test_cat_tfrecord的文件夹保存.tfrecord格式数据

在转换过程中运行时还遭遇了以下错误:

错误1:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte

解决办法:在pascalvoc_to_tfrecords.py程序中将下面语句中

image_data = tf.gfile.FastGFile(filename, 'r').read()
改成:
image_data = tf.gfile.FastGFile(filename, 'rb').read()

错误2:

KeyError: 'jumao'

解决办法:由于是我们自定义的物体,因此,要修改SSD-Tensorflow-master中关于物体类别的定义,打开SSD-Tensorflow-master/datasets/pascalvoc_common.py文件,进行修改,将VOC_LABELS中的其它无关类别全部删掉,增加jumao,lanmao,buoumoa的名称、ID、类别,如下:

VOC_LABELS = {
    'none': (0, 'Background'),
    'jumao': (1, 'Animal'),
    'lanmao': (2, 'Animal'),
    'buoumao': (3, 'Animal'),
}

最终,在执行了python命令后,在test_cat_tfrecord文件夹下生成了如下.record文件,这里只生成了一个文件可能是因为本人仅为了测试程序用,标注的图片样本数较少,因此生成的.record文件不多,控制生成tfrecord文件多少的代码在pascalvoc_to_tfrecords.py文件下,其中SAMPLES_PER_FILES = 200控制200张图片生成一个tfrecords。

之后再修改datasets/pascalvoc_2007.py,其中标签改为自己标注的图像:

同时,其中,根据自己训练数据修改:NUM_CLASSES = 类别数,这里我设置为8。

打开nets/ssd_vgg_300.py 修改类别个数,根据自己训练类别数修改96 和97行:等于类别数+1;如下图:

打开主目录下的eval_ssd_network.py修改类别个数,修改66行的类别个数:等于类别数+1;

3,下载预训练模型:

SSD-Tensorflow提供了预训练好的模型,这里我们利用vgg16模型进行训练,其的权重文件下载链接如下:

https://pan.baidu.com/s/1diWbdJdjVbB3AWN99406nA 密码:ge3x 或者

https://share.weiyun.com/VbIUV9rP

以下是一些谷歌云上提供的预训练权重,这里本人未成功下载,就不作过多介绍。

解压并使用vgg_16_2016_08_28.tar.gz的权重。解压后新建一个文件夹保存,内容如下:

4,利用预训练模型开始训练模型:

在训练模型之前,有个参数要修改下,打开SSD-Tensorflow-master/train_ssd_network.py找到里面的DATA_FORMAT参数项,如果是使用cpu训练则值为NHWC,如果是使用gpu训练则值为NCHW,默认为GPU训练,如下:

DATA_FORMAT = 'NCHW'  # gpu

在tensorflow1.13环境切换到SSD-Tensorflow-master目录下下执行以下命令:

python train_ssd_network.py --train_dir=C:\Users\username\Desktop\mobilnetv3_ssd\SSD-Tensorflow-Test\cat_models --dataset_dir=C:\Users\username\Desktop\mobilnetv3_ssd\SSD-Tensorflow-Test\test_cat_tfrecord --dataset_name=pascalvoc_2007 --dataset_split_name=train --model_name=ssd_300_vgg --checkpoint_path=C:\Users\username\Desktop\mobilnetv3_ssd\VGG_VOC0712_SSD_300x300_ft_iter_120000\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=600 --weight_decay=0.0005 --optimizer=adam --learning_rate=0.0001 --batch_size=1 --gpu_memory_fraction=0.9

各个参数意义如下:

train_dir为训练生成模型的存放路径,这里我在SSD-Tensorflow-master目录下新建一个cat_models文件夹用于保存。

dataset_dir为数据存放路径,即之前转换后的tfrecord文件的存放路径。

dataset_name为数据名的前缀,一般不用更改,使用的是VOC2012格式的改为pascalvoc_2012即可。

dataset_split_name需要与之前生成tfrecord文件的文件名中第三个单词保持一致,训练下定义为train即可。

model_name为加载的模型的名字,这里为ssd_300_vgg。

checkpoint_path为所加载预训练模型的路径,这里为,刚刚解压下来的预训练模型的文件路径。

checkpoint_model_scope为所加载模型里面的作用域名

checkpoint_exclude_scopes指定哪些层的参数不需要从vgg16模型里面加载进来

trainable_scopes指定哪些层的参数是需要训练的,未指定的参数保持不变,若注释掉此命令,所有的参数均需要训练

save_summaries_secs为每多少秒保存一下日志,这里我设置为60s。

save_interval_secs为每多少秒保存一下模型,这里我设置为600s。

weight_decay为正则化的权值衰减的系数。

optimizer为选取的最优化函数。

learning_rate为学习率。

batch_size为表示批量处理的数量,显存越大则可以设置越大。小显存设置为1即可。

gpu_memory_fraction指定占用gpu内存的百分比

执行命令后碰到如下错误:

错误1:

2022-04-10 19:47:17.769976: E tensorflow/stream_executor/cuda/cuda_driver.cc:806] failed to allocate 3.60G (3865470464 bytes) from device: CUDA_ERROR_OUT_OF_MEMORY: out of memory
2022-04-10 19:47:17.770090: E tensorflow/stream_executor/cuda/cuda_driver.cc:806] failed to allocate 3.24G (3478923264 bytes) from device: CUDA_ERROR_OUT_OF_MEMORY: out of memory

解决办法:是GPU内存不足造成的。需要在运行的train_ssd_network.py程序前加以下一段代码:

from tensorflow import ConfigProto
from tensorflow import InteractiveSession

config = ConfigProto()
config.gpu_options.allow_growth = True
session = InteractiveSession(config=config)

此时成功训练过程运行截图:

等待loss稳定在一个比较小的值之间,则可以停止训练。(直接关闭窗口以上即可)

5,监控训练过程:

进入 tensorflow环境下进入C:\Users\username\Desktop\mobilnetv3_ssd\SSD-Tensorflow-Test目录,在终端下输入以下指令:

tensorboard --logdir="cat_models"

并在浏览器中输入127.0.0.1:6006即可查看训练过程

错误问题记录,在训练完毕之后再重新打开tensorboard查看时,出现以下错误:

解决办法:

在tensorboard命令的末尾加一句--host=127.0.0.1,即:

tensorboard --logdir="cat_models" --host=127.0.0.1

再在浏览器下输入网址:127.0.0.1:6006即可打开。

最后,训练完毕的模型将保存在C:\Users\username\Desktop\mobilnetv3_ssd\SSD-Tensorflow-Test\cat_models目录下,如下图所示。

6,训练模型结果测试:

SSD-Tensorflow-master自带了一个notebooks脚本,可通过jupyter直接使用模型。没有安装Jupyter则在tensorflow环境下安装,执行以下命令,若是已经完成安装jupyter的,跳过此步:

conda install jupyter

启动jupyter-notebook,在tensorflow环境下,进入SSD-Tensorflow-master目录,执行以下代码:

cd C:\Users\username\Desktop\mobilnetv3_ssd

jupyter-notebook

成功打开jupyter后,进入SSD-Tensorflow-Test\notebooks目录,然后打开ssd_notebook.ipynb并更改以下几处:

a,In[6]代码块中设置训练完毕的模型路径:

# Restore SSD model.

ckpt_filename = 'C:\Users\username\Desktop\mobilnetv3_ssd\SSD-Tensorflow-Test\cat_models\model.ckpt-22105'

b,在最后的代码块中,设置要测试的图像路径path,选取一张图片放在一个新文件夹下即可:

# Test on some demo image and visualize output.

path = 'C:\Users\username\Desktop\ImageData\testImg\000058.jpg'
image_names = sorted(os.listdir(path))

由于只有1张测试的图片,再将图片数目改为1张,代码改为:

img = mpimg.imread(path + image_names[0])

然后点击菜单“Cell”,点击子菜单“Run All”,便能按顺序全部执行代码,并显示出结果出来:

其中,左边字数3含义为之前定义的buoumao定义的序号, 右边0.803表示检测的概率。

在此处中遇到的问题如下:

错误1:

ImportError: cannot import name ‘ssd_vgg_300’

解决办法:为ssd_notebook.ipynb文件存放位置路径问题,将此文件拷贝到SSD-Tensorflow-Test主目录下,再重启jupyter notebook并打开。

错误2:

SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape

解决办法:在windows系统当中读取文件路径可以使用,但是在python字符串中\有转义的含义,如\t可代表TAB,\n代表换行,所以我们需要采取一些方式使得\不被解读为转义字符。在路径前面加r,即保持字符原始值的意思或者将\全部改为\\。即更改路径为:

ckpt_filename = r'C:\Users\username\Desktop\mobilnetv3_ssd\SSD-Tensorflow-Test\cat_models\model.ckpt-22105'
path = 'C:\\Users\\username\\Desktop\\ImageData\\testImg\\000058.jpg'

错误3:

NotADirectoryError: [WinError 267] 目录名称无效。:

解决办法:是因为只需要path信息,不要写到文件。将path路径更改为:

path = 'C:\\Users\\username\\Desktop\\ImageData\\testImg\\'

参考博客:

https://my.oschina.net/u/876354/blog/1927351?tdsourcetag=s_pcqq_aiomsg

https://blog.csdn.net/Wangkongrong/article/details/98874088

https://blog.csdn.net/hezuo1181/article/details/91380182

https://blog.csdn.net/w5688414/article/details/78217574

https://www.cnblogs.com/GrPhoenix/p/10018072.html

posted @ 2022-04-11 13:06  Deceiver_Ker  阅读(455)  评论(0编辑  收藏  举报