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