deeplabv3开源工程详解(2)—— 使用自己的数据集进行训练、迁移学习

前言

deeplabv3是当前较为常用的语义分割的神经网络,且整个训练工程已经全部开源,使用公布的模型进行测试或基于自己的训练都可以得到一个较好的结果。

deeplabv3开源工程详解(1)—— 开源模型测试自己的图片
deeplabv3开源工程详解(2)—— 使用自己的数据集进行训练、迁移学习
deeplabv3开源工程(3)—— 报错:2 root error(s) found. (0) Invalid argument: padded_shape[0]=168 is not…

1 工程准备

环境

【TITAN XP】+【Ubuntu】+【tensorflow-gpu-1.14】+【cuda10.2】
(使用1.8.0及以上版本,低版本缺少函数,会报错)

下载包
  • 下载工程并解压
    https://github.com/tensorflow/models
    解压后,deeplabv3的工程在路径【./research/deeplab】下。
  • 下载deeplabv3的开源的权重
    https://github.com/tensorflow/models/blob/master/research/deeplab/g3doc/model_zoo.md
    在这个界面可以看到,基于PASCAL VOC数据集训练的模型、基于Cityscapes数据集训练的模型。本篇使用的是前者模型

    在这里插入图片描述
  • 进入 ./research/deeplab 路径下,创建model文件夹,将下载的权重文件解压在该文件夹下。

    在这里插入图片描述
    可以看见每个文件夹下有相同命名的三个文件。
    其中,pb文件用于实际测试;ckpt文件用于预训练模型。

    在这里插入图片描述

2 deeplabv3 训练自己的数据

在下载并解压完工程以及模型后。
需要注意的问题:

  • 确认tensorflow1.8 以上的版本
  • deeplab工程实现的代码在【./model-master/research/deeplab】路径下;但deeplab代码实现时,默认的根目录为【models/research/】。所以脚本的运行,需要在根目录下运行。(也可以在代码中进行修改,本篇博客记录的方式不修改)

2.1 确认工程配置

  • 到【research】路径下,打开终端,激活虚拟环境。
  • 将【./slim】路径导入到PYTHONPATH 环境变量中 export PYTHONPATH=$PYTHONPATH:./slim
  • 在【research】路径下运行./deeplab/model_test.py

    在这里插入图片描述
    运行结束后显示下图,则表示基本配置成功,可以进行训练的配置。

    在这里插入图片描述

2.2 数据集标注

标签的标注,在另外一篇博客 labelme标注软件的使用 || 语义分割数据标注 中记录。
标注的结果是得到了数据集的原始标签,然后需要根据实际情况,编写个小脚本来完成 原始图片和标签的命名的统一。

2.3 数据的整理


2.3.1 数据的目录结构

在【./deeplab/datasets/】路径下创建文件夹【dataset】,进行数据目录的整理(这里仿用PASCAL数据集的目录形式,当然也可以自己命名路径)。

数据的目录组织的形式如下:
其中黑颜色文件夹是要自己创建的路径;红颜色的文件或文件夹,是接下来将要生成的。

+ datasets
 + dataset
  |+ VOC2012
  |  + JPEGImages (存放原始数据)
  |  + SegmentationClass (存放标注后的png图片数据)
  |  + SegmentationClassDeal
  |  + ImageSets
  |    + Segmentation
  |     +train.txt
  |     +val.txt
  |     +trainval.txt
  |+ tfrecord (后面接介绍制作相应文件方法)

  • JPEGImages:存放RGB图像。对应的图像和标签的文件名相同,扩展名为 .jpg 或 .png
  • SegmentationClass:存放着原始标签,用于转化为神经网络训练的class标签
  • SegmentationClassDeal:存放转化后的神经网络训练的class标签(该路径不用创建,运行代码会自动生成)
  • xxx.txt文件:对应图片的不带扩展名的文件名(对于自己的数据集,需要自己生成该文件)

    2007_000032
    2007_000039
    2007_000063
    2007_000068

  • tfrecord:存放着将训练所需的数据标签转化成 tfrecord格式的文件(需要自己创建,当前为空文件夹)。

2.3.2 生成灰度图(制作SegmentationClassDeal下数据)

SegmentationClass文件夹下存放着原始标签:

  • 图片中每一种颜色对应了一个类别。
  • VOC数据集中,该文件夹下图片格式为单通道的png图像。图片是8位彩色图片,使用PIL库保存图片选择模式“P”的效果,它的每个像素用8个bit表示,其对应的彩色值是按照调色板查询出来的。
  • 自己制作的数据集的标签,有可能是3通道的RGB图片(一些标注软件得到的也是8位的彩色图)此处需要注意。

deeplab的class标签:

  • deeplab神经网络的label是用单通道的标注图,也就是灰度图。类别像素标记应为 0,1,2,3…n(共n+1 类,n个目标类+1个背景类)。此外,标注图上忽略类的像素值标记为255。

所以需要将原始标签转化为神经网络训练的class标签:
在【./deeplab/datasets/】路径下自带的 remove_gt_colormap.py脚本适用于将单通道的彩色图转化为灰度图。使用方法如下:

# 在 research/deeplab/datasets/ 路径下
python remove_gt_colormap.py   \
    --original_gt_folder="./dataset/VOC2012/SegmentationClass" \
    --output_dir="./dataset/VOC2012/SegmentationClassDeal" 


运行完在【dataset/VOC2012】路径下生成【文件夹 SegmentationClassDeal】,存放这神经网络训练时使用的class标签图片。
下图是PASCAL VOC2012的图片的三种形式,该数据集在part边界处存在“白边”,用作计算位于这些标签的 trimap 里的像素平均IOU。通常自己标注的数据集不会存在这个“白边”,class label 看起来是全黑的。

在这里插入图片描述


2.3.3 生成记录数据名字的txt文件

在制作 tfrecord之前,需要现将数据集分配成 训练数据、验证数据、测试数据。
前两者将相应的数据的名字保存在train.txt、trainval.txt、val.txt。放置文件保存的是对应图片的不带扩展名的文件名。
自己写个小脚本就可完成该txt文件的制作。


2.3.4 生成 tfrecord 文件

对于不大的数据集来说,tensorflow提供了一种高效的数据读取模式,将数据转换成TFRecord 格式。
在路径【./research/deeplab/datasets/】路径下,存在脚本 build_voc2012_data.py,然后在该路径下运行命令:

python ./build_voc2012_data.py \
   --image_folder="./dataset/VOC2012/JPEGImages" \
  --semantic_segmentation_folder="./dataset/VOC2012/SegmentationClassDeal" \
  --list_folder="./dataset/VOC2012/ImageSets/Segmentation" \
  --image_format="jpg" \
  --output_dir="./dataset/tfrecord"
  

可在代码中调节参数 _NUM_SJARDS(默认为4),改变数据分块的数目。运行结束后在【文件夹 tfrecord】下,保存了文件:

在这里插入图片描述

2.4 deeplab 的代码修改


2.4.1 新的数据集的注册

分别在【./research/deeplab/deprecated/segmentation_dataset.py】中 、以及在【./research/deeplab/datasets/data_generator.py 】中, 完成自己的数据集的注册。操作如下:
Ctrl+F 查找到 _DATASETS_INFORMATION,在这里原代码为:

_DATASETS_INFORMATION = {
   'cityscapes': _CITYSCAPES_INFORMATION,
   'pascal_voc_seg': _PASCAL_VOC_SEG_INFORMATION,
   'ade20k': _ADE20K_INFORMATION,
}


这里面注册着三个数据集,我们需要将自己的数据集添加进去:

_MYDATA_INFORMATION = DatasetDescriptor(
   splits_to_sizes={
       'train': 1464,  # 训练集数量
       'val': 1449,  # 测试集数量
   },
   num_classes=21,   # 种类+背景类
   ignore_label=255,   # ignore_label 用来 crop size 做填充的,默认为255
)

_DATASETS_INFORMATION = {
   'cityscapes': _CITYSCAPES_INFORMATION,
   'pascal_voc_seg': _PASCAL_VOC_SEG_INFORMATION,
   'ade20k': _ADE20K_INFORMATION,
   'mydata':_MYDATA_INFORMATION, # 添加自己的数据集
}


2.4.2 权重文件加载的设置

在【./research/deeplab/utils/】路径下的 train_utils.py 脚本中,Ctrl+F 搜索 exclude_list,能看到原代码

exclude_list = ['global_step']
if not initialize_last_layer:
   exclude_list.extend(last_layers)

由于我们需要使用预训练权重训练自己的数据集,标签的类别不同,所以不应该加载 logit层。修改代码如下:

exclude_list = ['global_step', 'logits']
if not initialize_last_layer:
   exclude_list.extend(last_layers)


2.4.3 样本不平衡的处理

如果我们的数据集出现了样本不平衡,也就是图片中每个类别的占比不同。比如:当普遍存在background占比较大,训练的结果预测可能出现经常全黑。
此时就需要修改相应的权重,使得能够正确训练。本篇博客记录与2020年11月,根据当前开源的工程修改方式如下:
在【./research/deeplab/common.py】脚本中,配置参数 label_weights。源码中可见


flags.DEFINE_multi_float(
   'label_weights', None,
   'A list of label weights, each element represents the weight for the label '
   'of its index, for example, label_weights = [0.1, 0.5] means the weight '
   'for label 0 is 0.1 and the weight for label 1 is 0.5. If set as None, all '
   'the labels have the same weight 1.0.')
   

在这里可以给不同的类别配置权重

2.5 工程训练、结果可视化、测试


2.5.1 训练

在运行 train.py 之前,我们需要明确一些设置。
如果要在Deeplab的预训练模型基础上fine-tune自己的数据集,根据不同的情况配置参数:

  • 使用预训练所有的权重,设置 initialize_last_layer=True
  • 不使用预训练的权重,设置 initialize_last_layer=False、last_layer_contain_logits_only=False
  • 使用 除去logits层的所有权重,设置 initialize_last_layer=False、last_layer_contain_logits_only=True

为了方便修改,个人喜欢把修改的部分单独写出来,在脚本 train.py的最后添加:

if __name__ == '__main__':

 flags.initialize_last_layer = False  # 添加
 flags.last_layers_contain_logits_only = True  # 添加

 flags.mark_flag_as_required('train_logdir')
 flags.mark_flag_as_required('dataset_dir')
 tf.app.run()


然后就可以使用命令进行训练了。在【./research/】路径下运行


export PYTHONPATH=$PYTHONPATH:./slim  #如果重新打开了终端,确保该条命令执行过

python deeplab/train.py \
 --logtostderr \
 --training_number_of_steps=3000 \
 --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="513,513" \
 --train_batch_size=4 \
 --fine_tune_batch_norm=true \
 --dataset="mydata" \
 --tf_initial_checkpoint="./deeplab/model/deeplabv3_pascal_train_aug/model.ckpt" \
 --train_logdir="./deeplab/train/" \
 --dataset_dir="./deeplab/datasets/dataset/tfrecord/"
 

其中,需要注意的是:

  • train_crop_size:裁剪后的图片大小。
    • 不得小于 [321,321]
    • (crop_size-1)/4 = 整数
    • 将crop_size 设置成 [256,256]时,结果不好。因为ASPP模块的存在,当图片过小时,到 feature map 时没有扩张卷积的范围大。
  • fine_tune_batch_norm:是否要训练BN层的参数。
    • 如果要训练BN层的参数,fine_tune_batch_norm=True、batch_size最好大于12。如果显存不够,可调整crop_size大小(但要不小于[321,321])

2.5.2 可视化

使用VOC数据集简单按照上述方法简单训练了下,然后进行可视化。在【./research/】路径下运行如下命令


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="513,513" \
 --dataset="mydata" \
 --colormap_type="pascal" \
 --checkpoint_dir="./deeplab/train/" \
 --vis_logdir="./deeplab/train/vis/" \
 --dataset_dir="./deeplab/datasets/dataset/tfrecord/"
 

其中

  • colormap_type:可以方便起见,直接设置为“pascal”。如果自己想修改为自定义的颜色显示列表,又或者类别数大于21类,就需要在脚本【./research/deeplab/utils/get_dataset_colormap.py】进行修改。这里选择“pascal”

在【./research/deeplab/train/vis/】路径下显示着结果:

在这里插入图片描述


2.5.3 验证

当我们训练结束后,想要知道对于每类对象的预测效果如何,在【./research】路径下执行如下命令,就可获取到训练后验证集的 每类对象的IOU。


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="513,513" \
   --dataset="mydata" \
   --checkpoint_dir="./deeplab/train/" \
   --eval_logdir="./deeplab/train/eval/" \
   --dataset_dir="./deeplab/datasets/dataset/tfrecord/"


终端输出部分内容:
在这里插入图片描述


2.6 需要注意的问题

  • 1 数据集中分类不均衡

    • 如果出现训练后,进行图片可视化,是全黑的。多半是由于 训练数据中种类不均衡,背景太多,又或者背景权重过大(另外,当训练轮次较少,也会出现预测结果全黑的现象)
  • 2 输入数据大小各异时

    • 需要自己做一个预处理,将所有图片的尺寸进行统一
  • 3 分割类别不宜过多。会导致训练效果不理想。

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
训练DeepLabV3模型使用VOC数据集,您可以按照以下步骤进行操作: 1. 下载VOC数据集:VOC数据集是常用的图像语义分割数据集,包含多个类别的图像及其对应的标签。您可以从VOC官方网站或其他来源下载数据集。 2. 准备数据集:解压下载的VOC数据集,并确保数据集中包含图像文件夹和标签文件夹。每个图像文件应该有一个对应的标签文件,其中每个像素都被标记为其所属的类别。 3. 准备训练代码:DeepLabV3模型的训练代码通常在开源深度学习框架中提供,例如TensorFlow或PyTorch。您可以根据您选择的框架找到相应的代码库。 4. 设置训练参数:根据您的需求,设置训练参数,例如批量大小(batch size)、学习率(learning rate)、迭代次数(epochs)等。这些参数将影响模型的训练过程和性能。 5. 数据预处理:在训练之前,通常需要对输入数据进行一些预处理操作,例如图像的缩放、裁剪、归一化等。此外,还需要将标签数据转换为模型可接受的格式,例如将标签映射为像素级别的分类任务或使用独热编码进行表示。 6. 训练模型:使用准备好的数据集和设置好的训练代码,开始训练DeepLabV3模型。在训练过程中,模型将学习图像的语义分割任务,并根据损失函数和优化算法进行参数更新。 7. 评估和调优:在训练完成后,您可以使用测试集对模型进行评估,并根据评估结果进行调优。常见的评估指标包括像素准确率(pixel accuracy)、平均交并比(mean intersection over union)等。 8. 推理和应用:在模型训练和调优完成后,您可以使用训练好的DeepLabV3模型对新的图像进行语义分割推理,并应用于您的实际应用场景中。 请注意,以上步骤仅为一般指导,具体实现可能因框架、代码库和数据集的不同而有所差异。建议您参考相关框架和代码库的官方文档或示例代码以获得更详细的指导。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值