Deeplabv3+安装并运行自己的数据集

论文:https://arxiv.org/pdf/1802.02611.pdf

源码:https://github.com/tensorflow/models/tree/master/research/deeplab

环境:ubuntu16.04 + cuda9.0 + cudnn7.6 + tensorflow-gpu1.11

cuda9.0 + cudnn7.6安装配置可参照:https://blog.csdn.net/wgshun616/article/details/81019182

多个版本cuda安装切换可参照:https://blog.csdn.net/yinxingtianxia/article/details/80462892

// 查看GPU型号
lspci | grep -i nvidia
// 查看NVIDIA驱动版本
sudo dpkg --list | grep nvidia-*
// 查看CUDA版本,需一致
cat /usr/local/cuda/version.txt
nvcc -V
// 查看CUDNN版本
cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2

deeplabv3+依赖库安装参照:https://github.com/tensorflow/models/blob/master/research/deeplab/g3doc/installation.md 

安装tensorflow-gpu时输入:

pip install tensorflow-gpu==1.11

记得在gedit ~/.bashrc配置文件中加入:

export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim

运行网上数据集过程请参照:https://github.com/tensorflow/models/blob/master/research/deeplab/g3doc/pascal.md

运行自己数据集:

1. 建立数据集

先在datasets目录下建立如下目录结构:

+ pascal_voc_seg
  + VOCdevkit
    + VOC2012
      + JPEGImages
      + SegmentationClass
      + ImageSets
        + Main
  + tfrecord
  + exp
    + train_on_train_set
      + train
      + val
      + vis

其中JPEGImages放置原图,SegmentationClass放置标注的分割图(注意标注时类别的像素值设置为0,1,2…,255为ignore_label)。Main中放置train.txt, val.txt, trainval.txt,为训练测试时所使用的数据,只包含数据名去掉后缀

接下来生成tfrecord格式的数据集,修改download_and_convert_voc2012.sh文件:

// 注释60行:
# download_and_uncompress "${BASE_URL}" "${FILENAME}"
// 89行根据自己数据集JPEGImages后缀名修改
  --image_format="jpg" \

 直接在datasets目录下运行:

bash download_and_convert_voc2012.sh

这样就会在tfrecord下生成训练测试所需的数据集。

2. 训练

加载的预训练模型:http://download.tensorflow.org/models/deeplabv3_pascal_train_aug_2018_01_04.tar.gz,读者也可以尝试train from scrach。

运行之前,修改deprecated/segmentation_dataset.py,改成你自己的数据集的量和类别数:

_PASCAL_VOC_SEG_INFORMATION = DatasetDescriptor(
    splits_to_sizes={
        'train': 1464, // 训练数据量
        #'train_aug': 10582,
        'trainval': 2913, // train+val
        'val': 1449, // 测试数据量
    },
    num_classes=21, // 类别数
    ignore_label=255,
)

看到一些博客,预训练时不加载logit层,因为类别数不同,修改train_utils.py的159行:

#exclude_list = ['global_step']
exclude_list = ['global_step','logit']

并且设置

initialize_last_layer=False
last_layers_contain_logits_only=True

博主设置后效果反而不好,读者可自行尝试。

在research下运行:

python deeplab/train.py \
    --logtostderr \
    --training_number_of_steps=30000 \
    --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="361,481" \
    --train_batch_size=4 \
    --dataset="pascal_voc_seg" \
    --tf_initial_checkpoint="./deeplab/datasets/deeplabv3_pascal_train_aug/model.ckpt" \
    --train_logdir="./deeplab/datasets/pascal_voc_seg/exp/train_on_train_set/train" \
    --dataset_dir="./deeplab/datasets/pascal_voc_seg/tfrecord"
    --fine_tune_batch_norm=False

这里说明几点:

1)因为只有一块GPU,train_batch_size设置为4,相应的fine_tune_batch_norm=False(当batchsize大于等于12才为True);数据集尺寸为480×360,train_crop_size设置的原则是减1除以4为整数,设置时第一个值是高,第二个值是宽,这个值大了也可能内存不够,但不小于300,否则会影响ASPP多尺度的效果,读者可根据自己的情况调整。

2)模型选择model_variant可根据自己情况自行选择,支持resnet, xception, mobilenet,不同模型可能decoder_output_stride可能有所不同,读者可自行阅读源码设置。

3)上面的参数均是可以调整的,包括训练步数,基网络output_stride,ASPP使用的空洞卷积rate等等,读者可自行阅读论文找到最合适的设置方式。

4)训练时学习率的衰减有两种方式,可选择线性poly和指数step,在train.py的77行:

flags.DEFINE_enum('learning_policy', 'poly', ['poly', 'step'],
                  'Learning rate policy for training.')

80-97行这几个关于学习率的参数与这两种方式的学习率计算公式有关:

# Use 0.007 when training on PASCAL augmented training set, train_aug. When
# fine-tuning on PASCAL trainval set, use learning rate=0.0001.
flags.DEFINE_float('base_learning_rate', .0001,
                   'The base learning rate for model training.')

flags.DEFINE_float('learning_rate_decay_factor', 0.1,
                   'The rate to decay the base learning rate.')

flags.DEFINE_integer('learning_rate_decay_step', 2000,
                     'Decay the base learning rate at a fixed step.')

flags.DEFINE_float('learning_power', 0.9,
                   'The power value used in the poly learning policy.')

flags.DEFINE_integer('training_number_of_steps', 30000,
                     'The number of steps used for training')

flags.DEFINE_float('momentum', 0.9, 'The momentum value to use')

学习率计算公式在utils/train_utils.py的230行有说明:

(1) The learning policy for "step" is computed as follows:
    current_learning_rate = base_learning_rate *
      learning_rate_decay_factor ^ (global_step / learning_rate_decay_step)
  See tf.train.exponential_decay for details.
  (2) The learning policy for "poly" is computed as follows:
    current_learning_rate = base_learning_rate *
      (1 - global_step / training_number_of_steps) ^ learning_power

基本上线性衰减关注训练总步数train_number_of_steps和learning_power,指数衰减关注learning_rate_decay_factor和learning_rate_decay_step,global_step表示当前的步数。

5) 关于数据均衡,因为不同类别样本像素个数不一样,可能存在样本不均衡的情况,可在损失函数里给不同类别不同的权重,在train_utils.py的85行:

not_ignore_mask = tf.to_float(tf.not_equal(scaled_labels, ignore_label)) * loss_weight

默认设置的时只要不是ignore_label(255),权重就是loss_weight(1)。因为看到一些博客有修改这个地方,但我修改后效果反而变差了。。。读者可自行尝试。

6)训练时,可运行:

tensorboard --logdir exp/train_on_train_set // 定位到你的train_on_train_set目录 

在tensorboard中查看训练情况。

3. 测试评价

运行:

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 \
    --train_crop_size="361,481" \
    --dataset="pascal_voc_seg" \
    --checkpoint_dir="./deeplab/datasets/pascal_voc_seg/exp/train_on_train_set/train" \
    --eval_logdir="./deeplab/datasets/pascal_voc_seg/exp/train_on_train_set/eval" \
    --dataset_dir="./deeplab/datasets/pascal_voc_seg/tfrecord"

注意修改eval.py中第78行max_number_of_evaluations=1,否则它会一直循环等待训练生成的新的model.ckpt进行评价。

另外eval.py不会在终端输出miou等评价指标(当然可以在tensorboard中看到),在eval.py的155行创建一个新的会话输出miou值:

miou, update_op = tf.metrics.mean_iou( predictions, labels, dataset.num_of_classes,               
                  weights=weights)
tf.summary.scalar(predictions_tag, miou)

// 新加入的代码
print_miou = tf.Print(miou,[miou],'miou is:')
tf.summary,scalar('print_miou',print_miou)

summary_op = tf.summary.merge_all()

读者可自行加入像素准确率等评价指标。

4. vis可视化

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 \
    --train_crop_size="361,481" \
    --dataset="pascal_voc_seg" \
    --checkpoint_dir="./deeplab/datasets/pascal_voc_seg/exp/train_on_train_set/train" \
    --vis_logdir="./deeplab/datasets/pascal_voc_seg/exp/train_on_train_set/vis" \
    --dataset_dir="./deeplab/datasets/pascal_voc_seg/tfrecord"

同样设置max_number_of_evaluations=1。

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值