SSD-MobileNetv2之Ubuntu18.04训练VOC格式数据集-超详细

Ubuntu**

python3.6
tensorflow1.15.0

TensorFlow Object Detection API下载

https://github.com/tensorflow/models

我的目录层次

models/ --research
                  --object_detection
                  --slim
                  --protoc-3.13.0-linux-x86_64
                  --dataset
                          --pascal_label_map.pbtxt                  
                          --tfrecord                  
                          --VOCdevkit
                                    --VOC2007     
                          --output
                                    --model
                                    --export_inference_graph
        --ssd_mobilenet_v2_coco_2018_03_29
                  --model.ckpt

Aanconda安装

下载安装包,包含所有前期版本:
Anaconda installer archive
安装.sh文件:

$bash Anaconda3-5.2.0-Linux-x86_64.sh

连续按回车,并接受 license terms。
设置安装路径,这里采用默认路径,按回车。
等待安装结束,选择 yes 添加环境变量。
下一步选择 no,不安装VSCode,完成 Anaconda 的安装。
关闭终端,重新打开一个终端,输入如下命令,没有报错,则 Anaconda 安装成功。

$conda --version
$python

创建虚拟环境

conda create -n ssd pip python=3.6

激活环境

source activate ssd

配置环境

sudo apt-get install protobuf-compiler python-pil python-lxml python-tk
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple tensorflow==1.15.0
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple Cython
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple contextlib2
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple pillow
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple lxml
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple jupyter
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple matplotlib
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple scipy
pip3 install pycocotools

安装protobuf

主要考虑apt-get 安装protobuf的版本不兼容:
下载:Protocol Buffers v3.13.0
查看系统架构,下载对应版本,如:

$uname -m
x86_64

进入models/research/下执行例如以下命令:

$protoc-3.13.0-linux-x86_64/bin/protoc object_detection/protos/*.proto --python_out=.

添加环境变量:

$gedit ~/.bashrc
export PYTHONPATH=/home/wjc/models/research:/home/wjc/models/research/slim:$PYTHONPATH
$source ~/.bashrc

编译

1.在models/research/slim目录下执行:

$python3 setup.py build
$python3 setup.py install 

2.在models/research目录下执行:

$python3 setup.py build
$python3 setup.py install 

测试

在models/research下测试是否正确安装Tensorflow API:
#有问题:

$python3 object_detection/builders/model_builder_test.py  

#成功:

$python3 object_detection/builders/model_builder_tf1_test.py

制作自己的数据集

使用labelImg制作,参考:Window+Anaconda下安装labelImg
参考VOC2007数据格式,.xml标签文件放在Annotations文件夹,自己的图片集先放在VOC2007文件夹下。

答应我标签文件和图片集文件路径中不要存在中文路径好吗?不然训练可能会报相关utf-8 gbk的编码错误。如果报错,你就可能需要像我一样用到下面的代码。
.xml批量修改folder属性:

import xml.dom.minidom
import os
path = r'./Annotations'  # xml文件存放路径
sv_path = r'./Annotations1'  # 修改后的xml文件存放路径
files = os.listdir(path)
cnt = 0
for xmlFile in files:
    dom = xml.dom.minidom.parse(os.path.join(path, xmlFile))  # 打开xml文件,送到dom解析
    root = dom.documentElement  # 得到文档元素对象
    item = root.getElementsByTagName('folder')  # 获取path这一node名字及相关属性值
    for i in item:
        i.firstChild.data = 'VOC2007'  # xml文件对应的图片路径

    with open(os.path.join(sv_path, xmlFile), 'w') as fh:
        dom.writexml(fh)
    cnt += 1

.xml批量修改path属性:

import xml.dom.minidom
import os
path = r'./Annotations'  # xml文件存放路径
sv_path = r'./Annotations1'  # 修改后的xml文件存放路径
files = os.listdir(path)
cnt = 0
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\\research\\dataset\\VOCdevkit\\VOC2007\\JPEGImages\\' + str(cnt).zfill(6) + '.jpg'  # xml文件对应的图片路径
    with open(os.path.join(sv_path, xmlFile), 'w') as fh:
        dom.writexml(fh)
    cnt += 1

如果你把某些图片中的‘car’错误标注成‘cai’,你还需要:

import os.path
import glob
import xml.etree.ElementTree as ET
import xml.dom.minidom
path = r'./Annotations/'
for xml_file in glob.glob(path + '/*.xml'):
    tree = ET.parse(xml_file)
    root = tree.getroot()
    for member in root.findall('object'):
        objectname = member.find('name').text
        if objectname == 'cai':
            print(objectname)
            member.find('name').text = str('car')
            tree.write(xml_file)

批量修改文件名:

#修改一个文件夹下所有图片的名字,修改成例如000000六位格式
import os
path = "./JPEGImages/"  #"./Annotations/
filelist = os.listdir(path)
filelist.sort()
count=1
for file in filelist:
    print(file)
for file in filelist:
    Olddir=os.path.join(path,file)
    if os.path.isdir(Olddir):
        continue
    filename=os.path.splitext(file)[0]
    filetype=os.path.splitext(file)[1]
    Newdir=os.path.join(path,str(count).zfill(6)+filetype)
    os.rename(Olddir,Newdir)
    print(Olddir, '----->', Newdir)
    count+=1

根据.xml文件名批量修改filename属性:

import xml.dom.minidom
import os
path = r'./Annotations'  # xml文件存放路径
sv_path = r'./AnnotationsFilename'  # 修改后的xml文件存放路径
files = os.listdir(path)
for xmlFile in files:
    dom = xml.dom.minidom.parse(os.path.join(path, xmlFile))  # 打开xml文件,送到dom解析
    root = dom.documentElement  # 得到文档元素对象
    names = root.getElementsByTagName('filename')
    a, b = os.path.splitext(xmlFile)  # 分离出文件名a
    for n in names:
        n.firstChild.data = a + '.jpg'
    with open(os.path.join(sv_path, xmlFile), 'w') as fh:
        dom.writexml(fh)

.record训练样本生成

*将create_pascal_tf_record.py中Line164和Line165:

   examples_path = os.path.join(data_dir, year, 'ImageSets', 'Main',
                                 'aeroplane_' + FLAGS.set + '.txt')

变为:

   examples_path = os.path.join(data_dir, year, 'ImageSets', 'Main',+ FLAGS.set + '.txt')
   ###                             'aeroplane_' + FLAGS.set + '.txt')

*其中SETS = [‘train’, ‘val’, ‘trainval’, ‘test’]的获取方法为:

import os
import random
trainval_percent = 0.5 #训练全集
train_percent = 0.5   #训练集
xmlfiles_path= 'Annotations'
txtsavepath = 'ImageSets/Main'
all_xmlfiles = os.listdir(xmlfiles_path)

num=len(all_xmlfiles)#图片xml总数
xmlfiles_list=range(num) #列表
num_val=int(num*trainval_percent)#训练全集数
num_tra=int(num_val*train_percent)#训练全集中训练集数
trainval= random.sample(xmlfiles_list,num_val)#在全部图片xml中随机取训练全集数
train=random.sample(trainval,num_tra)#在训练全集中随机取训练集数

trainval_file = open(txtsavepath+'/trainval.txt', 'w')
test_file = open(txtsavepath+'/test.txt', 'w')
train_file = open(txtsavepath+'/train.txt', 'w')
val_file= open(txtsavepath+'/val.txt', 'w')
for i in xmlfiles_list:
    name=all_xmlfiles[i][:-4]+'\n' #[:-4]从0开始到倒数第4个但不包括该位 此时为6位数图片名称.即文件名称000000.xml去掉.xml保留数字
    if i in trainval:
       trainval_file.write(name)
       if i in train:
          train_file.write(name)
       else:
          val_file.write(name)
    else:
     test_file.write(name)

trainval_file.close()
train_file.close()
val_file.close()
test_file.close()

生成训练/验证集:

python3 object_detection/dataset_tools/create_pascal_tf_record.py --label_map_path=/home/lqs/models/research/dataset/pascal_label_map.pbtxt  --data_dir=/home/lqs/models/research/dataset/VOCdevkit --year=VOC2007 --set=val --output_path=/home/lqs/models/research/dataset/tfrecord/pascal_val.record
python3 object_detection/dataset_tools/create_pascal_tf_record.py --label_map_path=/home/lqs/models/research/dataset/pascal_label_map.pbtxt  --data_dir=/home/lqs/models/research/dataset/VOCdevkit --year=VOC2007 --set=train --output_path=/home/lqs/models/research/dataset/tfrecord/pascal_train.record

下载预训练权重

ssd_mobilenet_v2_coco_2018_03_29

放在models\ssd_mobilenet_v2_coco_2018_03_29下

配置.config文件

将object_detection\samples\configs\ssd_mobilenet_v2_coco.config另存为ssd_mobilenet_v2_pascal.config打开内容如下:

修改1:自己数据集class的数目 第9行

num_classes: 8

修改2:修改网络输入大小 43行

image_resizer {
      fixed_shape_resizer {
        height: 512
        width: 512
      }
    }

修改2:训练batch 141行(如果GPU流批当我没说)

batch_size: 8

修改3:预训练权重路径 156行(可注释,从头开始训练)

fine_tune_checkpoint: "/home/lqs/models/ssd_mobilenet_v2_coco_2018_03_29/model.ckpt"

修改5:修改train_input_reader路径 第173行

train_input_reader: {
  tf_record_input_reader {
    input_path: "/home/lqs/models/research/dataset/tfrecord/pascal_train.record"
  }
  label_map_path: "/home/lqs/models/research/dataset/pascal_label_map.pbtxt"
}

修改4:val_input_reader路径 第182行

val_input_reader: {
  tf_record_input_reader {
    input_path: "/home/lqs/models/research/dataset/tfrecord/pascal_val.record"
  }
  label_map_path: "/home/lqs/models/research/dataset/pascal_label_map.pbtxt"
  shuffle: false
  num_readers:1
}​

启动训练

python3 object_detection/model_main.py --pipeline_config_path=/home/lqs/models/research/object_detection/samples/configs/ssd_mobilenet_v2_pascal.config --model_dir=/home/lqs/models/research/dataset/output/model --num_train_steps=50000 --alsologtostderr

训练可视化

tensorboard --logdir=/home/lqs/models/research/dataset/output/model

把终端输出的http://xxxxxx复制到浏览器中打开

固化权重

python3 object_detection/export_inference_graph.py
  --input_type=image_tensor
  --pipeline_config_path=/home/lqs/models/research/object_detection/samples/configs/ssd_mobilenet_v2_pascal.config
  --trained_checkpoint_prefix=/home/lqs/models/research/dataset/output/model/model.ckpt-50000
  --output_directory=/home/lqs/models/research/data/output/export_inference_graph
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值