1.clone 谷歌官方源码到本地
2.添加Python环境变量
在终端添加(一次性买卖,本终端有效,其他的无效):export PYTHONPATH=$PYTHONPATH:/home/xxx/Downloads/models-master/research/slim
也可以添加在bashrc里面,这样对当前用户都有效
vim ~/.bashrc
export PYTHONPATH=/home/xxx/Downloads/models-master/research/slim:$PYTHONPATH
attention:此处不添加的话,后面会报Python路径的错
File "deeplab/train.py", line 22, in <module>
from deeplab import common
ImportError: No module named deeplab
3.测试一下
#在deeplab/research目录下运行
python deeplab/model_test.py
接下来,开始照猫画虎,训练数据了,根据demo,跑了一遍voc的数据,弄清楚了voc的长什么样,然后把自己的数据整成了voc的格式。
4.生成图像mask。
数据本身提供的是灰度图,自己先把他们整成mask,这两者的区别在于一个看得出分割结果,一个就是漆黑一片。mask的话,其实也就是灰度图映射一下,将其灰度值变成0,1,2,3这样。之前的标注为N分类,自己只需要做二分类,所以就把其他类都变成了background。根据之前train.txt来对文件进行读写。这里要注意,有的txt换行的最后字符为\n,有的为\r\n,要注意区分。
import cv2
files = [line.split('jpg ')[1] for line in open('train.txt')]
#train.txt like this ColorImage/Record008/Camera 6/171206_030615827_Camera_6.jpg Label/Record008/Camera 6/171206_030615827_Camera_6_bin.png
for path in files:
path = path[:-2]
img = cv2.imread(path)
print(img.shape)
base = 'mask'
img[np.where((img!=49).all(axis = 2))] = 0
img[np.where((img==49).all(axis = 2))] = 1
#img[np.where((img==[255,0,0]).all(axis = 2))] =0
#img[np.where((img==[255,0,255]).all(axis = 2))] =1
cv2.imwrite(path[:-8]+'.png',img)
5.生成voctrain.txt vocval.txt为接下来生成tfrecord做准备。
这里需要的格式为Record008/Camera 6/171206_030905729_Camera_6,不需要后缀,且label和image要同名,自己懒得改生成的脚本,所以就按照voc脚本的格式来了。
只要把之前的train.txt截取一部分就好了
def voc_train(text):
files = [line.split(' L')[0] for line in open(text)]
with open('voctrain.txt','w') as file:
for label in files:
file.write(label[11:-4]+'\n')
if __name__ == '__main__':
voc_train('train.txt')
6.生成tfrecord
在4.5步骤之后,就可以愉快的采用提供的voc的脚本来生成tfrecord啦
python build_voc2012_data.py --image_folder="/media/chunyan/DATA/720data/apollo/ColorImage" --semantic_segmentation_folder="/media/chunyan/DATA/720data/apollo/Label" --list_folder="/media/chunyan/DATA/720data/apollo/txt" --image_format="jpg" --output_dir="/home/chunyan/Downloads/models-master/research/deeplab/datasets/apollo/tfrecord"
7.训练模型
首先,对/models/research/deeplab/dataset 下 segmentation_dataset.py进行修改,添加自己数据集的信息在115行后添加
_APOLLO_INFORMATION = DatasetDescriptor(
splits_to_sizes={
'voctrains':4000,
'voctrain':29991
'vocval':300,
},
num_classes =2,
ignore_label =255,
# 在 125行DATASETS_INFORMATION中添加
'apollo':_APOLLO_INFORMATION,
开始训练
python deeplab/train.py \
--logtostderr \
--training_number_of_steps=40000 \
--train_split="voctrains" \
--model_variant="xception_65" \
--atrous_rates=6 \
--atrous_rates=12 \
--atrous_rates=18 \
--output_stride=16 \
--decoder_output_stride=4 \
--train_crop_size=769 \
--train_crop_size=769 \
--train_batch_size=2 \
--dataset="pascal_voc_seg" \
--tf_initial_checkpoint="/home/chunyan/Downloads/models-master/research/deeplab/xception65/model.ckpt" \
--train_logdir="/home/chunyan/Downloads/models-master/research/deeplab/datasets/pascal_voc_seg/log" \
--dataset_dir="/home/chunyan/Downloads/models-master/research/deeplab/datasets/pascal_voc_seg/tfrecord"
这里 把initialize_last_layer改为false,不用最后一层的权重,flags.DEFINE_boolean('initialize_last_layer', False,
'Initialize the last layer.')
batchsize = 8 ,显存不够,所以bn不能动了,要把参数设为False 根据When fine_tune_batch_norm=True, use at least batch size larger than 12 (batch size more than 16 is better). Otherwise, one could use smaller batch size and set fine_tune_batch_norm=False.
7.评估模型:
python deeplab/eval.py \
--logtostderr \
--eval_split="vocval" \
--model_variant="xception_65" \
--atrous_rates=6 \
--atrous_rates=12 \
--atrous_rates=18 \
--output_stride=16 \
--decoder_output_stride=4 \
--eval_crop_size=2710 \
--eval_crop_size=3384 \
--dataset="pascal_voc_seg" \
--checkpoint_dir="/home/chunyan/Downloads/models-master/research/deeplab/datasets/pascal_voc_seg/log" \
--eval_logdir="/home/chunyan/Downloads/models-master/research/deeplab/datasets/pascal_voc_seg/eval"\
--dataset_dir="/home/chunyan/Downloads/models-master/research/deeplab/datasets/pascal_voc_seg/tfrecord"
注意:
--eval_crop_size=2710 这里=后不能有空格,--eval_crop_size= 2710 不然报错 所有的=后面都不能有空格 不然报错。absl.flags._exceptions.IllegalFlagValueError: flag --eval_crop_size=: invalid literal for int() with base 10: ''
跑完后会算出MIOU的值,来评估模型的好坏。
8.可视化分割结果
python deeplab/vis.py \
--logtostderr \
--vis_split="vocval" \
--model_variant="xception_65" \
--atrous_rates=6 \
--atrous_rates=12 \
--atrous_rates=18 \
--output_stride=16 \
--decoder_output_stride=4 \
--vis_crop_size=2710 \
--vis_crop_size=3384 \
--dataset="pascal_voc_seg" \
--checkpoint_dir="/home/chunyan/Downloads/models-master/research/deeplab/datasets/pascal_voc_seg/log" \
--vis_logdir="/home/chunyan/Downloads/models-master/research/deeplab/datasets/pascal_voc_seg/vis"\
--dataset_dir="/home/chunyan/Downloads/models-master/research/deeplab/datasets/pascal_voc_seg/tfrecord"
这样在segmentation_results文件夹下,会生成每张图的原图与彩色分割结果。
9.导出模型:
python deeplab/export_model.py \
--logtostderr \
--checkpoint_path="/home/chunyan/Downloads/models-master/research/deeplab/datasets/pascal_voc_seg/log/model.ckpt-40000" \
--export_path="/home/chunyan/Downloads/models-master/research/deeplab/datasets/pascal_voc_seg/export/frozen_inference_graph.pb" \
--model_variant="xception_65" \
--atrous_rates=6 \
--atrous_rates=12 \
--atrous_rates=18 \
--output_stride=16 \
--decoder_output_stride=4 \
--num_classes=2 \
--crop_size=2710 \
--crop_size=3384 \
--inference_scales=1.0
导出模型,生成frozen_inference_graph.pb以便接下来inference。这里的crop_size我是按照图片大小设置的,尝试了一下,输入不同分辨率的图像,分割效果差距很大,crop_size大小最佳。
10.测试图片,根据demo.ipynb 改了一下,输入一个文件夹的图,输出分割后的图在另一个文件夹,一张图需要4.6S,在1080TI下,还是蛮慢的。
生成的结果:
参数设置:
eval_crop_size = output_stride * k + 1
export_model 的时候crop_size 的参数选择:根据自己的测试,此时的crop_size 应该等于你要输入测试图像的大小,如果比测试图像大,预测出来的效果会很稀疏,不好。如果比测试图像小,直接报错。之前设置成原图的大小,也报错了,然后改成了960,960就ok了。