1. 程式人生 > >deeplab v3+訓練自己的資料集

deeplab v3+訓練自己的資料集

資料集的製作及相關程式碼修改

原始碼連結:deeplab v3+
筆者使用的是類似voc2012的資料集,最終的目的是進行語義分割。要想獲得這樣的資料集可以使用labelme進行標註,也可以使用PS進行處理。筆者使用了PS進行標註,生成了灰度圖。
為了方便,使用的資料集形式與官方資料集一致,如下所示:
在這裡插入圖片描述
其中,在SegmentationClass中Segmentation裡存放train.txt,val.txt等檔案,裡面記錄著用作訓練集驗證集的檔名。JPEGImages中存放著所有的資料,SegmentationClass中存放著JPEGImages中資料對應的標籤。tfrecord之後會存放經過處理的資料。train中會存放生成的訓練檔案,eval會存放生成的評估檔案,vis會存放最終對eval的分割結果。
建立好資料夾後,首先要將原始圖片轉變為tensorflow支援的tfrecord格式。這裡對download_and_convert_voc2012.sh檔案的某些語句進行註釋,因為我們不需要下載與解壓voc資料集。如下所示:

# Helper function to download and unpack VOC 2012 dataset.
#download_and_uncompress() {
#  local BASE_URL=${1}
#  local FILENAME=${2}

# if [ ! -f "${FILENAME}" ]; then
#    echo "Downloading ${FILENAME} to ${WORK_DIR}"
#    wget -nd -c "${BASE_URL}/${FILENAME}"
#  fi
#  echo "Uncompressing ${FILENAME}"
#  tar -xf "${FILENAME}"
#}

# Download the images.
#BASE_URL="http://host.robots.ox.ac.uk/pascal/VOC/voc2012/"
#FILENAME="VOCtrainval_11-May-2012.tar"

#download_and_uncompress "${BASE_URL}" "${FILENAME}"

執行download_and_convert_voc2012.sh檔案製作資料集:

# From the tensorflow/models/research/deeplab/datasets directory.
sh download_and_convert_voc2012.sh

在segmentation_dataset.py中修改如下內容為自己資料的train資料量、val資料量及分類數(num_classes),注意,此處的分類數包括背景:

    splits_to_sizes={
        'train': 2358,
 #       'train_aug': 10582,
 #      'trainval': 2913,
        'val': 590,
    },
    num_classes=6,
    ignore_label=255,

為了使用預訓練的權重,更改train.py中的True改為False:

flags.DEFINE_boolean('initialize_last_layer', False,
                     'Initialize the last layer.')

之後按照官方教程進行訓練即可

可能出現問題

1、如果資料集中的圖片大小不一致,在執行eval.py的時候可能出現類似tensorflow.python.framework.errors_impl.InvalidArgumentError: Shape mismatch in tuple component 1. Expected [513,513,3], got [513,616,3] 這樣的錯誤,此時需要根據根據資料集中最大的圖片尺寸修改即可,例如資料集中圖片尺寸最大為624*823,可以設定eval_crop_size為625與825.
2、如果出現類似錯誤:InvalidArgumentError (see above for traceback): assertion failed: [predictions out of bound] [Condition x < y did not hold element-wise:] [x (mean_iou/confusion_matrix/control_dependency_1:0) = ] [0 3 3…] [y (mean_iou/ToInt64_2:0) = ] [150]
在eval.py修改程式碼如下:

   metric_map = {}

    # insert by trobr
    indices = tf.squeeze(tf.where(tf.less_equal(
        labels, dataset.num_classes - 1)), 1)
    labels = tf.cast(tf.gather(labels, indices), tf.int32)
    predictions = tf.gather(predictions, indices)
    # end of insert

    metric_map[predictions_tag] = tf.metrics.mean_iou(
        predictions, labels, dataset.num_classes, weights=weights)