Ubantu下 用deeplabV3+训练自己的数据集 你可能遇到的所有坑都在这了


1.安装环境 一定要注意版本问题

因为版本对不上,花了好多时间猜正确的版本。

系统:Ubantu16.04

nvidia驱动版本 410.78

驱动更新参考:https://blog.csdn.net/pertain99/article/details/102848725

python 版本 3.5.2

tensorflow-gpu版本 1.14.0

CUDA : 10.0

cudnn: 7.6.5

labelme 3.9

2.安装deeplabV3+项目

官方链接: https://github.com/tensorflow/models

下载后解压 下载解压的文件夹名字叫 /models-master,为了方便,我改了名字为 /models

以下地址中的所有 /models 就是 /models-master

测试安装是否成功 打开终端进入 models/research  执行

export PYTHONPATH=$PYTHONPATH:/path-to/models/research/slim

这个代码每次打开终端都需要执行一次 或者 直接写在 ~/.bashrc里,并 source ~/.bashrc


然后测试安装是否成功 在 models/research 目录下执行

python deeplab/model_test.py

如果成功会显示


失败的话可能是相关包没装齐全,根据提示装相关包就好。一般是ImportError :no modual name "XXX",其他的错误我没遇到。 如果是tensorflow的包没有,那基本是tensorflow版本问题,不是太新就是太旧,按照第一步版本重装就好。

3.制作数据集


3.1 labelme

用的labelme 版本是3.9.0

labelme 版本不对 会出现

attributeerror: module 'labelme.utils' has no attribute 'draw_label'

labelme对图片进行多变形标注后,会出现 图片以及相关的json文件


而deeplabV3+的数据集需要这些json文件 将这些json 文件放在一起。我放在 testdata 文件夹


3.2 json_to_mask

然后是将这些json换成deeplab所需要的mask_label.

用到的代码在:https://blog.csdn.net/u014513323/article/details/81166997

这里需要根据自己的需求改代码,代码不难,容易看懂

这是根据自己需求改的:https://github.com/xixixijie/tensorflow/blob/master/labelme_to_mask.py

会直接生成image和mask文件夹

image放的原图格式 .jpg,mask放的是label图 格式 .png 。

或者参考以下 :https://blog.csdn.net/xjtdw/article/details/94741984


需要的是第一张原图和第二张黑的label图,第三张图是label的可视化,因为第二张全黑不容易知道是否有标签值在里面。

判断label是否正确,可用:https://github.com/xixixijie/tensorflow/blob/master/pilShowMask.py

如图,鼠标在图片对应位置滑动,右下角显示label的id[2,2,2] ,说明这个图片不是全黑,是有label值的,标号错了可以自己修改前面的labelme_to_mask.py。


3.3构建数据集目录

自己创建,官方不自带
放在这个路径下#models/research/deeplab/datasets

-testdata

    + image

    + mask

    + index

        - train.txt

        - trainval.txt

        - val.txt

    + tfrecord

image里放所有原图 ,mask里放label所有标签。 注意,原图名字和label名字要一一对应

index里放的是train.txt val.txt train.txt,靠这些txt文件区分训练集和测试集,可以用这个文件制作:

https://github.com/xixixijie/tensorflow/blob/master/saveFilenameToTxt.py

制作完成后,train.txt里放的是训练集图片的名,不包括路径和扩展名,其他以此类推,vis是测试集。trainval我没用上。

tfrecord文件夹里放的是tfrecord,

打开终端进入/models/research ,在该路径下执行

python deeplab/datasets/build_voc2012_data.py \

      --image_folder="models/research/deeplab/datasets/testdata/image" \

      --semantic_segmentation_folder="/models/research/deeplab/datasets/testdata/mask" \

      --list_folder="/models/research/deeplab/datasets/testdata/index" \

      --image_format="jpg" \

      --label_format="png" \

      --output_dir="models/research/deeplab/datasets/testdata/tfrecord"

build_voc2012_data.py 是官方程序自带的。

--image_folder 上一步的image文件夹路径

--semantic_segmentation_folder 上一步的mask路径

--list_folder  index路径

--image_format 原图图片格式,我的是jpg 应该可以是别的格式

--label_format  标签图片格式

--output_dir tfrecord路径

数据集制作完毕

4.训练前代码改动

注册数据集

在/models/research/deeplab/datasets 路径的data_generator.py 第93行:

_MYDATA_INFORMATION = DatasetDescriptor(

splits_to_sizes={

        'train':44,  # num of samples in images/training  train.txt的行数

        'val':27,  # num of samples in images/validation val.txt的行数

    },

    num_classes=6,  # 我的标签是5类(包括background),加上ignore_label总共六类

    ignore_label=255,

)

然后找到 _DATASETS_INFORMATION ,加上mydata....一行

_DATASETS_INFORMATION = {

   'cityscapes': _CITYSCAPES_INFORMATION,

    'pascal_voc_seg': _PASCAL_VOC_SEG_INFORMATION,

    'ade20k': _ADE20K_INFORMATION,

    'mydata': _MYDATA_INFORMATION,    #注册上面的数据集 加粗部分一致,前面的mydata随意取

}

同样在models/research/deeplab/deprecated下的segmentation_dataset.py文件进行同样的操作

train_utils.py

在models/research/deeplab/utils/train_utils.py的213行左右

exclude_list = ['global_step','logits'] #本来只有global_step ,现在加上 logits,表示不加载逻辑层的参数

  if not initialize_last_layer:

    exclude_list.extend(last_layers)

train.py

在models/research/deeplab/train.py里 156行左右

# Set to False if one does not want to re-use the trained classifier weights.

flags.DEFINE_boolean('initialize_last_layer', False, 'Initialize the last layer.') #这个本来是True设置为False

flags.DEFINE_boolean('last_layers_contain_logits_only', True, 'Only consider logits as last layers or not.')#这个设置为True

解释:

input_preprocess.py

models/research/deeplab/input_preprocess.py  128行左右

# Randomly crop the image and label.

if is_trainingand labelis not None:

  processed_image, label = preprocess_utils.random_crop([processed_image, label], crop_height, crop_width)

为这个if加一个else,下面的代码显示得不好,不过在链接里也有

参考链接:https://github.com/tensorflow/models/issues/3695

else:

  rr = tf.minimum(tf.cast(crop_height, tf.float32) / tf.cast(image_height, tf.float32), \

  tf.cast(crop_width, tf.float32) / tf.cast(image_width, tf.float32))

  newh = tf.cast(tf.cast(image_height, tf.float32) * rr, tf.int32)

  neww = tf.cast((tf.cast(image_width, tf.float32) * rr), tf.int32)

  processed_image = tf.image.resize_images(processed_image, (newh, neww), method=tf.image.ResizeMethod.BILINEAR,           align_corners=True)

  processed_image = preprocess_utils.pad_to_bounding_box(processed_image, 0, 0, crop_height, crop_width, mean_pixel)

不加这一段在运行vis.py和eval的时候会报错

类似

InvalidArgumentError (see above for traceback): padded_shape[1]=128 is not divisible by block_shape[1]=12

Invalid argument: padded_shape[1]=69 is not divisible by block_shape[1]=2

这种错基本都是这样解决

5.train vis eval

 打开终端 ,进入 models/research路径

5.1 train.py

执行

python deeplab/train.py \

    --logtostderr \

    --training_number_of_steps=200 \

    --train_split="train" \

    --model_variant="xception_65" \

    --atrous_rates=6 \

    --atrous_rates=12 \

    --atrous_rates=18 \

    --output_stride=16 \

    --decoder_output_stride=4 \

    --train_crop_size=317,385 \

    --train_batch_size=2 \

    --dataset="mydata" \

    --tf_initial_checkpoint='models/research/deeplab/backbone/deeplabv3_cityscapes_train/model.ckpt' \

    --train_logdir='models/research/deeplab/exp/train_on_train_set/train' \

    --dataset_dir='models/research/deeplab/datasets/testdata/tfrecord'

--training_number_of_steps=200  这里是训练步数,自己设置训练多少次

--model_variant="xception_65" 选择backbone 有别的,但我没看。

--train_crop_size=317,385   设置图片裁剪大小,( height,width)这里尽可能大可以提高准度

这里要说的是我的训练集图片大小不一,没有进行统一尺寸修改。图片最小的尺寸是316×384  我都加了1,因为别的博客里说是要

(height/width - 1)/ 4 要是整数。

--train_batch_size=2  内存不够可以将这个调小。

--dataset="mydata"  这个mydata是上面注册数据集时取的名字

--tf_initial_checkpoint 初始权重,就是官方预训练过的权重 路径

在这里下载,选择xception_65_imagenet:https://github.com/tensorflow/models/blob/master/research/deeplab/g3doc/model_zoo.md


解压在任意位置,路径对的上就行。


--train_logdir 训练出来的文件的保存路径,自己创建,/exp/train_on_train_set/train 这三个文件夹都是我参考别人博客创建的。

--dataset_dir 这个就是上面tfrecord的路径

其他没解释的

不出错的话是


错误记录:

Invalid argument: Nan in summary histogram for: image_pooling/BatchNorm/moving_variance_1

这个问题出现在我把batch_size设置成1,解决方案为设置为2,参考链接:

https://blog.csdn.net/qq_41046851/article/details/90552364

解释在:

https://blog.csdn.net/v1_vivian/article/details/77991894

官方解决方法是增加loss的范围,可是没说怎么加

https://github.com/tensorflow/models/issues/5050


5.2 vis.py

这个用于查看训练结果

python deeplab/vis.py \

  --logtostderr \

  --vis_split="val" \

  --model_variant="xception_65" \

  --atrous_rates=6 \

  --atrous_rates=12 \

  --atrous_rates=18 \

  --output_stride=16 \

  --decoder_output_stride=4 \

  --vis_crop_size=317,384 \

  --dataset="mydata" \

  --checkpoint_dir='models/research/deeplab/exp/train_on_train_set/train' \

  --vis_logdir="models/research/deeplab/exp/train_on_train_set/vis" \

  --dataset_dir="models/research/deeplab/datasets/testdata/tfrecord"

--vis_crop_size 这里决定输出的label预测图大小,可以设置为数据库里最大的图片。

--checkpoint_dir 这个路径就是上面训练指令的--train_logdir  表示你要用训练好的权重

--vis_logdir 训练结果图片要存的位置,自己创建。

如果不出错,会显示


在--vis_logdir 路径下会看到分割结果的图片。

5.3 eval.py

python deeplab/eval.py \

  --logtostderr \

  --eval_split="val" \

  --model_variant="xception_65" \

  --atrous_rates=6 \

  --atrous_rates=12 \

  --atrous_rates=18 \

  --output_stride=16 \

  --decoder_output_stride=4 \

  --eval_crop_size=317,365 \

  --dataset="mydata" \

  --checkpoint_dir="models/research/deeplab/exp/train_on_train_set/train" \

  --eval_logdir="models/research/deeplab/exp/train_on_train_set/eval" \

  --dataset_dir="models/research/deeplab/datasets/testdata/tfrecord" \

--eval_crop_size 一样

--eval_logdir 输出文件路径,自己创建

正常输出 官方版本版本不一样可能有些差距。

我暂时就做到这里了,剩下的步骤可以参考别的博客。



参考链接:

deeplab_v3 实现 制作并训练自己的数据集——个人采坑

(超详细很完整)tensorflow下利用deeplabv3+对自己的数据进行训练

Deeplab V3+训练自己数据集全过程

官方讨论区

推荐网课 白勇老师的教程

最后这个不是打广告,只是有很多没有遇到的bug要是真的没法解决,不如买个网课,去问一下老师,老师很快就回复我了,还给了qq交流。

80不贵解君愁。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容