使⽤deeplabv3+训练⾃⼰的数据集经验总结简介
deeplabv3+是现今性能最好的语义分割模型之⼀,本⽂介绍如何在window环境下安装并运⾏deeplabv3+。本⽂将详细介绍deeplabv3+的环境配置,训练⾃⼰的数据,参数调试等内容。
Update:
2018-8-22 环境搭建,数据集预处理,训练⾃⼰的数据
Todo:
✔环境介绍 Anaconda,使⽤gitbash运⾏ .sh ⽂件
deeplabv3+简介
✔代码下载,本地测试
✔处理⾃⼰的数据集
内部的⼀些微调,及各项参数的⽤处
结果
1、环境介绍
本地⼯作站实验环境:
系统:windows 7
GPU:Geforce TITAN X × 2
CUDA:9.0 + CUDNN7.5
Tendorflow:1.9.0-gpu (使⽤1.8.0及以上版本,亲测1.4.0缺少函数,会报错)
上述环境安装的具体步骤可参考:
1.1 如何使⽤ Git Bash 运⾏.sh脚本
由于deeplab官⽅github仓库clone下来的代码中使⽤了shell脚本进⾏⾃动化训练、评估、格式化等操作,然⽽这些脚本应当是在linux系统下运⾏的。由于我的机器Ubuntu14.04系统的环境配置不好,⽆奈只能想⽅法在Windows上运⾏。为了能在windows系统上运⾏shell脚本,这⾥强烈推荐Git Bash。它是Git(没错,就是那个代码管理系统)软件的⼀个⼦程序,感觉⽐windows⾃带的cmd和powershell要好⽤!
可以直接从,然后正常安装,完毕后在任何⽂件夹的空⽩处⿏标右键,点击 Git Bash Here 选项,就可以在当前右键的路径下打开⼀个 Git
Bash 控制台,长这个样⼦
以⼀个名 shell_script.sh 为例,在脚本所在⽂件夹下打开 Git Bash,然后键⼊ ./shell_script.sh  就可以
运⾏了。虽然deeplab中的.sh 脚本能够在Git Bash中运⾏,但是⼀些语句⽆效的,需要做其他修改,下⾯会提到。在运⾏之前,我还遇到了⼀个⼩问题,就是⼯作站原本就有python环境,如果不修改默认 python  路径,容易发⽣ import  问题(纯净环境配置后是否有这样的问题未知,总之添加⼀下环境变量就好了),安装Anacoda后需要将默认的 python  路径改成Anaconda的 python  路径。在⽤户变量中的 PATH  变量中添加 C:\ProgramData\Anaconda3\Scripts  和 C:\ProgramData\Anaconda\Library\bin  两个路径,此处只是举例,具体路径请按照真实的安装路径添加!!环境变量设置具体可参考
1.2 Windows 环境安装 tf-model
先给出 tf-model  的Github地址:
deeplab  的源码就在 research  ⽂件夹中。在 deeplab/g3doc/installation.md  中提到,安装deeplab需要将 research/slim  路径加⼊ PYTHONPATH  中去,官⽅给出的⽅法是在每次运⾏之前都执⾏,但仅在linux系统中起作⽤在cmd和powershell中会报错,亲测虽然Git Bash中不报错但仍然⽆效(这⾥我也不懂原理)。
windows 系统下的解决⽅案为:在py脚本中动态添加地址
将 deeplab  ⽂件夹下的 train.py 、 eval.py , vis.py , export_model.py  这四个脚本的开头加语句,没错四个⽂件都要加(必须加在 import deeplab  语句之前)。
1.3 本地测试
export PYTHONPATH =$PYTHONPATH :`pwd`:`pwd`/slim
import  sys
sys.path.append(r'D:\Code\tf-models\research')
sys.path.append(r'D:\Code\tf-models\research\slim')  # 以上两处的路径请按照真实的路径添加
环境配置完成之后,在 deeplab 路径下打开Git Bash,运⾏ ./local_test.sh 脚本进⾏环境测试。如果机器不够好(显存或内存不够),可以试试 ./local_test_mobilenetv2.sh 测试,是⼀个⼩模型,在我的 8G 内存笔记本上,⽤CPU版本的tensorflow也能跑通。
./local_test.sh
如果本地测试运⾏正常,那么恭喜你,环境的配置已经完成!下⼀步,也是最重要的⼀步,处理⾃⼰的数据集,使其符合 deeplab 的规范。
2、数据改造
后续99%的bug都源于前期没处理好的数据。 ——沃兹基硕德
⾃⼰的数据,格式肯定是五花⼋门,为了能在deeplab上训练,⼀定要重视数据预处理过程(深刻的教训)!
简单来说,需要把数据预处理成规定的格式和尺⼨范围(因为我测试的时候,太⼤尺⼨的图像导致耗尽OOM,吐槽⼀下我的原始数据集真的稀烂),⽣成包含⽂件名的⽂本⽂件,最后以规定的⽬录形式组织起来。
数据的⽬录组织形式应当这样:
+ Database  # ⾃⼰的数据集名称
+ JPEGImages
+ SegmentationClass
+ ImageSets
+ Segmentation
-
-
-
+ tfrecord
其中:
JPGImages ⽂件夹存放RGB图像;SegmentationClass 存放转换为class的标签,格式为单通道的png图像。对应的图像和标签的⽂件名相同!!扩展名分别为.jpg和.png
ImageSets/Segmentation 存放有图像⽂件名的 .txt ⽂件,这⾥我按⽂件名将数据分为 train, val, trainval; tfrecord 存放转换的tfrecord 格式的数据。
.txt ⽂件中的内容应当为对应图像的⽂件名,不带扩展名:
filename1
filename2
filename3
.....
2.1 去colormap,转换为class形式的标签
原始的 label 图像是有着⾊的,每⼀种颜⾊对应了⼀个类别,这⾥就需要提供⼀个颜⾊到类别的映射——这样每个像素点的值就转换为对应类别的 int 值。
值得⼀提的是, deeplab/datasets 中⾃带的 remove_gt_colormap.py 脚本仅适⽤于带有 colormap 的单通道png图像。这种类型的数据感觉⽐较少见,在MATLAB中读取会发现,读⼊的数据包含两个矩阵,⼀个代表图像灰度值,⼀个代表灰度值对应的RGB值。
(PASCAL VOC数据集的标签就是这种形式,之前没有见过,推测应该是能压缩数据?)与⼀般RGB图像不⼀样。请事先检查数据,如果是这种类型的png图像,则可以使⽤⾃带的 remove_gt_colormap.py 脚本进⾏转换。
具体如何转换,还是要结合实际,⽆论⽤什么⽅法将 colored label 转换为 class label。⽐如加上背景共有151类,那就分别标记为0~150。
2.2 图像压缩
由于我原始数据集不是很好,图像的尺⼨从200到6000多不等,虽说训练时不会有问题(有选项进⾏缩放),但是测试时太⼤的图像导致⽤光显存。(我使⽤数据集有151个类别,TITAN X 11GB的显存都爆了…)
于是对原始数据进⾏压缩还是必要的(此处存疑,写本⽂时发现测试有 reshape 配置选项,暂未研究透彻),我的处理⽅法是将图像按原⽐例缩放,使 max{width, height} <= 512。这⾥附上我的调整图像⼤⼩的代码,⽐较粗糙,献丑了:
import os
from PIL import Image
image_dir = 'JPEGImages/'# 输⼊RGB图像⽂件夹
label_dir = 'SegmentationClassRaw/'# 输⼊label图像⽂件
image_output_dir = 'JPEGImages_resized/'# 输出RGB图像⽂件夹
label_output_dir = 'SegmentationClassRaw_resized/'# 输出label图像⽂件夹
if not ists(image_output_dir):
os.mkdir(image_output_dir)
if not ists(label_output_dir):
os.mkdir(label_output_dir)
image_format = '.jpg'
label_format = '.png'
image_names = open('ImageSets/', 'r').readlines()
image_names = list(map(lambda x: x.strip(), image_names))
backup_file = open('', 'w')      # 图像原始尺⼨记录下来,备份
for name in image_names:
# Open an image file and print the size
image = Image.open(image_dir+name+image_format)
label = Image.open(label_dir+name+label_format).convert('L')
# Check image size
assert image.size == label.size
# Check image mode
de == 'RGB'
pascal是系统软件吗
print('>> Now checking image file: %s', name+image_format)
print('  Origin size: ', image.size)
width, height = image.size
# Log the original size of the image
backup_file.write('%d,%d\n' % (width, height))
# Resize a image if it's too large
if width > 512or height > 512:
print('  ')
scale = 512.0 / max(image.size)
resized_w = int(width*scale)
resized_h = int(height*scale)
image = size((resized_w, resized_h), Image.BILINEAR)
label = size((resized_w, resized_h), Image.NEAREST)
# Save new image and label
image.save(image_output_dir+name+image_format)
label.save(label_output_dir+name+label_format)
print('  Done.')
else:
# Save new image and label
image.save(image_output_dir+name+image_format)
label.save(label_output_dir+name+label_format)
print('  Pass.')
backup_file.close()
2.3 转换为TFRecord格式

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。