From 724401e7885f9d14949fc983849aafcc14909243 Mon Sep 17 00:00:00 2001 From: dwSun Date: Thu, 4 Jan 2018 16:28:31 +0800 Subject: [PATCH] initial --- README.md | 174 ++++++++++++++++++ convert_fcn_dataset.py | 99 ++++++++++ dataset.py | 89 +++++++++ requirements.txt | 2 + train.py | 329 ++++++++++++++++++++++++++++++++++ utils.py | 109 +++++++++++ val_1000_annotation.jpg | Bin 0 -> 13675 bytes val_1000_img.jpg | Bin 0 -> 90227 bytes val_1000_prediction.jpg | Bin 0 -> 10933 bytes val_1000_prediction_crfed.jpg | Bin 0 -> 20547 bytes vgg.py | 308 +++++++++++++++++++++++++++++++ 11 files changed, 1110 insertions(+) create mode 100644 README.md create mode 100644 convert_fcn_dataset.py create mode 100644 dataset.py create mode 100644 requirements.txt create mode 100644 train.py create mode 100644 utils.py create mode 100644 val_1000_annotation.jpg create mode 100644 val_1000_img.jpg create mode 100644 val_1000_prediction.jpg create mode 100644 val_1000_prediction_crfed.jpg create mode 100644 vgg.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..1853160 --- /dev/null +++ b/README.md @@ -0,0 +1,174 @@ +# 简介 +本代码为系列课程, 第九周部分的课后作业内容。 +http://edu.csdn.net/lecturer/1427 + +# TinymMind上GPU运行费用较贵,每 CPU 每小时 $0.09,每 GPU 每小时 $0.99,所有作业内容推荐先在本地运行出一定的结果,保证运行正确之后,再上传到TinyMind上运行。初始运行推荐使用CPU运行资源,待所有代码确保没有问题之后,再启动GPU运行。 + +TinyMind上Tensorflow已经有1.4的版本,能比1.3的版本快一点,推荐使用。 + +## 作业内容 + +本作业以week9视频中讲述的FCN为基础,构建一个FCN训练模型,要求学员实现代码中缺失的部分并使用自己的实现跑出比较好的结果。 + + + +### 数据集 +本作业使用Pascal2 VOC2012的数据中,语义分割部分的数据作为作业的数据集。 + +VOC网址:http://host.robots.ox.ac.uk/pascal/VOC/voc2012/ + +本次作业不提供数据集下载,请学员自行到上述网址找到并下载数据,同时请仔细阅读VOC网站对于数据集的描述。 + +VOC数据集目录结构如下: +``` +├── local +│   ├── VOC2006 +│   └── VOC2007 +├── results +│   ├── VOC2006 +│   │   └── Main +│   └── VOC2007 +│   ├── Layout +│   ├── Main +│   └── Segmentation +├── VOC2007 +│   ├── Annotations +│   ├── ImageSets +│   │   ├── Layout +│   │   ├── Main +│   │   └── Segmentation +│   ├── JPEGImages +│   ├── SegmentationClass +│   └── SegmentationObject +├── VOC2012 +│   ├── Annotations +│   ├── ImageSets +│   │   ├── Action +│   │   ├── Layout +│   │   ├── Main +│   │   └── Segmentation +│   ├── JPEGImages +│   ├── SegmentationClass +│   └── SegmentationObject +└── VOCcode +``` + +其中本次作业使用VOC2012目录下的内容。作业数据集划分位于**VOC2012/ImageSets/Segmentation**中,分为train.txt 1464张图片和val.txt1449张图片。 + +语义分割标签位于**VOC2012/SegmentationClass**,注意不是数据集中所有的图片都有语义分类的标签。 +语义分割标签用颜色来标志不同的物体,该数据集中共有20种不同的物体分类,以1~20的数字编号,加上编号为0的背景分类,该数据集中共有21种分类。编号与颜色的对应关系如下: +```py +# class +classes = ['background', 'aeroplane', 'bicycle', 'bird', 'boat', + 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', + 'dog', 'horse', 'motorbike', 'person', 'potted plant', + 'sheep', 'sofa', 'train', 'tv/monitor'] + +# RGB color for each class +colormap = [[0, 0, 0], [128, 0, 0], [0, 128, 0], [128, 128, 0], [0, 0, 128], + [128, 0, 128], [0, 128, 128], [128, 128, 128], [64, 0, 0], [192, 0, 0], + [64, 128, 0], [192, 128, 0], [64, 0, 128], [192, 0, 128], + [64, 128, 128], [192, 128, 128], [0, 64, 0], [128, 64, 0], + [0, 192, 0], [128, 192, 0], [0, 64, 128]] +``` + +对应关系可由**VOCcode/VOClabelcolormap.m**计算得出,作业代码中也有计算对应关系的代码,这里不再详述,请学员自行理解代码。 + +>需要注意,分类中其实还有一个编号为255的分类,其颜色对应[224, 224, 192],这个分类用作边界着色,这里不处理这个分类。 + +### 训练数据准备 +训练数据需要预先打包成tfrecord格式,本步骤在本地完成。 + +打包使用作业代码中的**convert_fcn_dataset.py**脚本进行。脚本内容已经删掉一部分,需要由学员自行补全缺失部分的代码。 + +''' +python3 convert_fcn_dataset.py --data_dir=/path/to/VOCdevkit/VOC2012/ --output_dir=./ +''' + +本步骤最终生成的两个文件**fcn_train.record**,**fcn_val.record**分别在400MB左右,共800MB左右,如果最后的文件大小过大或过小,生成数据的过程可能有问题,请注意检查。 + +>提示:可以参考week8中数据集生成部分的代码来补全这里的代码。 + +### 数据集上传 +请参考week7,week8中的内容,这里不再详述。 + +### 预训练模型 +预训练模型使用tensorflow,modelzoo中的VGG16模型,请学员自行到modelzoo中查找并将该预训练模型放到tinymind上。 + +### 模型 +模型代码以课程视频week9 FCN部分的代码进行了修改,主要是代码整理,添加了数据输入和结果输出的部分。 + +代码参考:https://gitee.com/ai100/quiz-w9-code.git + +在tinymind上新建一个模型,模型设置参考如下模型: + +https://www.tinymind.com/ai100/quiz-w9-fcn + +复制模型后可以看到模型的全部参数。 + +需要注意的是,代码中使用了额外的库,所以在建立模型的时候,需要在依赖项中,填入以下项目: +``` +pydensecrf +opencv-python +``` + +模型参数的解释: + +- checkpoint_path VGG16的预训练模型的目录,这个请根据自己建立的数据集的目录进行设置。 +- output_dir 输出目录,这里使用tinymind上的/output目录即可。 +- dataset_train train数据集的目录,这个请根据自己建立的数据集的目录进行设置。 +- dataset_val val数据集的目录,这个请根据自己建立的数据集的目录进行设置。 +- batch_size BATCH_SIZE,这里使用的是16,建立8X的FCN的时候,可能会OutOfMem,将batch_size调低即可解决。 +- max_steps MAX_STEPS, 这里运行1500步,如果batch_size调整了的话,可以考虑调整一下这里。 +- learning_rate 学习率,这里固定为1e-4, 不推荐做调整。 + +运行过程中,模型每100个step会在/output/train下生成一个checkpoint,每200步会在/output/eval下生成四张验证图片。 + +>FC论文参考 https://arxiv.org/abs/1411.4038 +### 作业内容 +- 学员需要将convert_fcn_dataset.py中的代码补全并生成对应的数据集文件上传到tinymind。 +- 学员需要在作业提供的代码基础上添加8X的FCN实现并进行训练。 + + +### 结果评估 + +数据集: +- 数据集中应包含train和val两个tfrecord文件,大小在400MB左右 +- 数据集中应包含vgg_16.ckpt,大小在528MB + +在tinymind运行log的输出中,可以看到如下内容: +```sh +2018-01-04 11:11:20,088 - DEBUG - train.py:298 - step 1200 Current Loss: 101.153938293 +2018-01-04 11:11:20,088 - DEBUG - train.py:300 - [23.54] imgs/s +2018-01-04 11:11:21,011 - DEBUG - train.py:307 - Model saved in file: ./out/train/model.ckpt-1200 +2018-01-04 11:11:21,018 - DEBUG - train.py:314 - validation generated at step [1200] +2018-01-04 11:11:28,461 - DEBUG - train.py:298 - step 1210 Current Loss: 116.911231995 +2018-01-04 11:11:28,461 - DEBUG - train.py:300 - [19.11] imgs/s +2018-01-04 11:11:35,356 - DEBUG - train.py:298 - step 1220 Current Loss: 90.7060165405 +``` + +训练完成之后,可以在**/output/eval**下面生成验证的图片,其中**val_xx_prediction.jpg**的图片为模型输出的预测结果,内容应可以对应相应的annotation和img。根据验证图片的内容,结果可能会有区别,但是肯定可以看到输出的结果是明显有意义的。 + +效果如下: +原图 + +![原图](val_1000_img.jpg) + +标签 + +![标签](val_1000_annotation.jpg) + +预测 + +![预测](val_1000_prediction.jpg) + +CRF之后的预测 + +![预测](val_1000_prediction_crfed.jpg) + +### 参考内容 + +本地运行训练使用的命令行: +```sh +python train.py --checkpoint_path ./vgg_16.ckpt --output_dir ./output --dataset_train ./fcn_train.record --dataset_val ./fcn_val.record --batch_size 16 --max_steps 2000 +``` diff --git a/convert_fcn_dataset.py b/convert_fcn_dataset.py new file mode 100644 index 0000000..dc51b31 --- /dev/null +++ b/convert_fcn_dataset.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python3 +import logging +import os + +import cv2 +import numpy as np +import tensorflow as tf +from vgg import vgg_16 + + +flags = tf.app.flags +flags.DEFINE_string('data_dir', '', 'Root directory to raw pet dataset.') +flags.DEFINE_string('output_dir', '', 'Path to directory to output TFRecords.') + +FLAGS = flags.FLAGS + +classes = ['background', 'aeroplane', 'bicycle', 'bird', 'boat', + 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', + 'dog', 'horse', 'motorbike', 'person', 'potted plant', + 'sheep', 'sofa', 'train', 'tv/monitor'] +# RGB color for each class +colormap = [[0, 0, 0], [128, 0, 0], [0, 128, 0], [128, 128, 0], [0, 0, 128], + [128, 0, 128], [0, 128, 128], [ + 128, 128, 128], [64, 0, 0], [192, 0, 0], + [64, 128, 0], [192, 128, 0], [64, 0, 128], [192, 0, 128], + [64, 128, 128], [192, 128, 128], [0, 64, 0], [128, 64, 0], + [0, 192, 0], [128, 192, 0], [0, 64, 128]] + + +cm2lbl = np.zeros(256**3) +for i, cm in enumerate(colormap): + cm2lbl[(cm[0] * 256 + cm[1]) * 256 + cm[2]] = i + + +def image2label(im): + data = im.astype('int32') + # cv2.imread. default channel layout is BGR + idx = (data[:, :, 2] * 256 + data[:, :, 1]) * 256 + data[:, :, 0] + return np.array(cm2lbl[idx]) + + +def dict_to_tf_example(data, label): + with open(data, 'rb') as inf: + encoded_data = inf.read() + img_label = cv2.imread(label) + img_mask = image2label(img_label) + encoded_label = img_mask.astype(np.uint8).tobytes() + + height, width = img_label.shape[0], img_label.shape[1] + if height < vgg_16.default_image_size or width < vgg_16.default_image_size: + # 保证最后随机裁剪的尺寸 + return None + + # Your code here, fill the dict + feature_dict = { + 'image/height': None, + 'image/width': None, + 'image/filename': None, + 'image/encoded': None, + 'image/label': None, + 'image/format': None, + } + example = tf.train.Example(features=tf.train.Features(feature=feature_dict)) + return example + + +def create_tf_record(output_filename, file_pars): + # Your code here + pass + + +def read_images_names(root, train=True): + txt_fname = os.path.join(root, 'ImageSets/Segmentation/', 'train.txt' if train else 'val.txt') + + with open(txt_fname, 'r') as f: + images = f.read().split() + + data = [] + label = [] + for fname in images: + data.append('%s/JPEGImages/%s.jpg' % (root, fname)) + label.append('%s/SegmentationClass/%s.png' % (root, fname)) + return zip(data, label) + + +def main(_): + logging.info('Prepare dataset file names') + + train_output_path = os.path.join(FLAGS.output_dir, 'fcn_train.record') + val_output_path = os.path.join(FLAGS.output_dir, 'fcn_val.record') + + train_files = read_images_names(FLAGS.data_dir, True) + val_files = read_images_names(FLAGS.data_dir, False) + create_tf_record(train_output_path, train_files) + create_tf_record(val_output_path, val_files) + + +if __name__ == '__main__': + tf.app.run() diff --git a/dataset.py b/dataset.py new file mode 100644 index 0000000..90f1ed9 --- /dev/null +++ b/dataset.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from __future__ import absolute_import, division, print_function + +import time + +import tensorflow as tf + +from utils import (_B_MEAN, _G_MEAN, _R_MEAN, _mean_image_subtraction) + +# TFRcord文件 +TRAIN_FILE = 'fcn_train.record' +VALIDATION_FILE = 'fcn_val.record' + +# 图片信息 +NUM_CLASSES = 21 + + +def read_and_decode(filename_queue): + reader = tf.TFRecordReader() + _, serialized_example = reader.read(filename_queue) + features = tf.parse_single_example(serialized_example, features={ + 'image/encoded': tf.FixedLenFeature([], tf.string), + 'image/label': tf.FixedLenFeature([], tf.string) + }) + image = tf.image.decode_jpeg(features['image/encoded'], channels=3) + label = tf.decode_raw(features['image/label'], tf.uint8) + shape = tf.shape(image) + label = tf.reshape(label, [shape[0], shape[1], 1]) + + return image, label + + +def inputs(data_set, train=True, batch_size=1, num_epochs=1, upsample_factor_for_whole_net=32): + if not num_epochs: + num_epochs = None + + with tf.name_scope('input') as scope: + filename_queue = tf.train.string_input_producer([data_set], num_epochs=num_epochs) + image, label = read_and_decode(filename_queue) + + # Convert image to float32 before subtracting the + # mean pixel value + image_float = tf.to_float(image, name='ToFloat') + # Subtract the mean pixel value from each pixel + mean_centered_image = _mean_image_subtraction(image_float, [_R_MEAN, _G_MEAN, _B_MEAN]) + + if train: + seed = int(time.time()) + img_corped = tf.random_crop(mean_centered_image, [224, 224, 3], seed=seed) + img_orig_corped = tf.random_crop(image, [224, 224, 3], seed=seed) + lbl_corped = tf.random_crop(label, [224, 224, 1], seed=seed) + + images, origin_images, labels = tf.train.shuffle_batch([img_corped, img_orig_corped, lbl_corped], + batch_size=batch_size, + num_threads=4, + capacity=100 + 3 * batch_size, + min_after_dequeue=100) + else: + original_shape = tf.shape(image_float)[0:2] + + target_input_size_factor = tf.ceil( + tf.div(tf.to_float(original_shape), tf.to_float(upsample_factor_for_whole_net))) + target_input_size = tf.to_int32(tf.multiply(target_input_size_factor, upsample_factor_for_whole_net)) + padding_size = (target_input_size - original_shape) // 2 + + mean_centered_image = tf.image.pad_to_bounding_box(mean_centered_image, + padding_size[0], + padding_size[1], + target_input_size[0], + target_input_size[1]) + + annotation_tensor_paded = tf.image.pad_to_bounding_box(label, + padding_size[0], + padding_size[1], + target_input_size[0], + target_input_size[1]) + + origin_image = tf.image.pad_to_bounding_box(image, + padding_size[0], + padding_size[1], + target_input_size[0], + target_input_size[1]) + images = tf.expand_dims(mean_centered_image, 0) + origin_images = tf.expand_dims(origin_image, 0) + labels = tf.expand_dims(annotation_tensor_paded, 0) + + return images, origin_images, labels diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..42c9155 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +pydensecrf +opencv-python diff --git a/train.py b/train.py new file mode 100644 index 0000000..df5439c --- /dev/null +++ b/train.py @@ -0,0 +1,329 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +import argparse +import os +import time + +import cv2 +import numpy as np +import tensorflow as tf + +import pydensecrf.densecrf as dcrf +import vgg +from dataset import inputs +from pydensecrf.utils import (create_pairwise_bilateral, + create_pairwise_gaussian, unary_from_softmax) +from utils import (bilinear_upsample_weights, grayscale_to_voc_impl) + +import logging + +logging.basicConfig(format='%(asctime)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s', level=logging.DEBUG) + + +def parse_args(check=True): + parser = argparse.ArgumentParser() + parser.add_argument('--checkpoint_path', type=str) + parser.add_argument('--output_dir', type=str) + parser.add_argument('--dataset_train', type=str) + parser.add_argument('--dataset_val', type=str) + parser.add_argument('--batch_size', type=int, default=16) + parser.add_argument('--max_steps', type=int, default=1500) + parser.add_argument('--learning_rate', type=float, default=1e-4) + + FLAGS, unparsed = parser.parse_known_args() + return FLAGS, unparsed + + +FLAGS, unparsed = parse_args() + +slim = tf.contrib.slim + + +tf.reset_default_graph() +is_training_placeholder = tf.placeholder(tf.bool) +batch_size = FLAGS.batch_size + +image_tensor_train, orig_img_tensor_train, annotation_tensor_train = inputs(FLAGS.dataset_train, train=True, batch_size=batch_size, num_epochs=1e4) +image_tensor_val, orig_img_tensor_val, annotation_tensor_val = inputs(FLAGS.dataset_val, train=False) + +image_tensor, orig_img_tensor, annotation_tensor = tf.cond(is_training_placeholder, + true_fn=lambda: (image_tensor_train, orig_img_tensor_train, annotation_tensor_train), + false_fn=lambda: (image_tensor_val, orig_img_tensor_val, annotation_tensor_val)) + +feed_dict_to_use = {is_training_placeholder: True} + +upsample_factor = 16 +number_of_classes = 21 + +log_folder = os.path.join(FLAGS.output_dir, 'train') + +vgg_checkpoint_path = FLAGS.checkpoint_path + +# Creates a variable to hold the global_step. +global_step = tf.Variable(0, trainable=False, name='global_step', dtype=tf.int64) + + +# Define the model that we want to use -- specify to use only two classes at the last layer +with slim.arg_scope(vgg.vgg_arg_scope()): + logits, end_points = vgg.vgg_16(image_tensor, + num_classes=number_of_classes, + is_training=is_training_placeholder, + spatial_squeeze=False, + fc_conv_padding='SAME') + +downsampled_logits_shape = tf.shape(logits) + +img_shape = tf.shape(image_tensor) + +# Calculate the ouput size of the upsampled tensor +# The shape should be batch_size X width X height X num_classes +upsampled_logits_shape = tf.stack([ + downsampled_logits_shape[0], + img_shape[1], + img_shape[2], + downsampled_logits_shape[3] + ]) + + +pool4_feature = end_points['vgg_16/pool4'] +with tf.variable_scope('vgg_16/fc8'): + aux_logits_16s = slim.conv2d(pool4_feature, number_of_classes, [1, 1], + activation_fn=None, + weights_initializer=tf.zeros_initializer, + scope='conv_pool4') + +# Perform the upsampling +upsample_filter_np_x2 = bilinear_upsample_weights(2, # upsample_factor, + number_of_classes) + +upsample_filter_tensor_x2 = tf.Variable(upsample_filter_np_x2, name='vgg_16/fc8/t_conv_x2') + +upsampled_logits = tf.nn.conv2d_transpose(logits, upsample_filter_tensor_x2, + output_shape=tf.shape(aux_logits_16s), + strides=[1, 2, 2, 1], + padding='SAME') + + +upsampled_logits = upsampled_logits + aux_logits_16s + +upsample_filter_np_x16 = bilinear_upsample_weights(upsample_factor, + number_of_classes) + +upsample_filter_tensor_x16 = tf.Variable(upsample_filter_np_x16, name='vgg_16/fc8/t_conv_x16') +upsampled_logits = tf.nn.conv2d_transpose(upsampled_logits, upsample_filter_tensor_x16, + output_shape=upsampled_logits_shape, + strides=[1, upsample_factor, upsample_factor, 1], + padding='SAME') + + +lbl_onehot = tf.one_hot(annotation_tensor, number_of_classes) +cross_entropies = tf.nn.softmax_cross_entropy_with_logits(logits=upsampled_logits, + labels=lbl_onehot) + +cross_entropy_loss = tf.reduce_mean(tf.reduce_sum(cross_entropies, axis=-1)) + + +# Tensor to get the final prediction for each pixel -- pay +# attention that we don't need softmax in this case because +# we only need the final decision. If we also need the respective +# probabilities we will have to apply softmax. +pred = tf.argmax(upsampled_logits, axis=3) + +probabilities = tf.nn.softmax(upsampled_logits) + +# Here we define an optimizer and put all the variables +# that will be created under a namespace of 'adam_vars'. +# This is done so that we can easily access them later. +# Those variables are used by adam optimizer and are not +# related to variables of the vgg model. + +# We also retrieve gradient Tensors for each of our variables +# This way we can later visualize them in tensorboard. +# optimizer.compute_gradients and optimizer.apply_gradients +# is equivalent to running: +# train_step = tf.train.AdamOptimizer(learning_rate=0.0001).minimize(cross_entropy_loss) +with tf.variable_scope("adam_vars"): + optimizer = tf.train.AdamOptimizer(learning_rate=FLAGS.learning_rate) + gradients = optimizer.compute_gradients(loss=cross_entropy_loss) + + for grad_var_pair in gradients: + + current_variable = grad_var_pair[1] + current_gradient = grad_var_pair[0] + + # Relace some characters from the original variable name + # tensorboard doesn't accept ':' symbol + gradient_name_to_save = current_variable.name.replace(":", "_") + + # Let's get histogram of gradients for each layer and + # visualize them later in tensorboard + tf.summary.histogram(gradient_name_to_save, current_gradient) + + train_step = optimizer.apply_gradients(grads_and_vars=gradients, global_step=global_step) + +# Now we define a function that will load the weights from VGG checkpoint +# into our variables when we call it. We exclude the weights from the last layer +# which is responsible for class predictions. We do this because +# we will have different number of classes to predict and we can't +# use the old ones as an initialization. +vgg_except_fc8_weights = slim.get_variables_to_restore(exclude=['vgg_16/fc8', 'adam_vars']) + +# Here we get variables that belong to the last layer of network. +# As we saw, the number of classes that VGG was originally trained on +# is different from ours -- in our case it is only 2 classes. +vgg_fc8_weights = slim.get_variables_to_restore(include=['vgg_16/fc8']) + +adam_optimizer_variables = slim.get_variables_to_restore(include=['adam_vars']) + +# Add summary op for the loss -- to be able to see it in +# tensorboard. +tf.summary.scalar('cross_entropy_loss', cross_entropy_loss) + +# Put all summary ops into one op. Produces string when +# you run it. +merged_summary_op = tf.summary.merge_all() + +# Create the summary writer -- to write all the logs +# into a specified file. This file can be later read +# by tensorboard. +summary_string_writer = tf.summary.FileWriter(log_folder) + +# Create the log folder if doesn't exist yet +if not os.path.exists(log_folder): + os.makedirs(log_folder) + +checkpoint_path = tf.train.latest_checkpoint(log_folder) +continue_train = False +if checkpoint_path: + tf.logging.info( + 'Ignoring --checkpoint_path because a checkpoint already exists in %s' + % log_folder) + variables_to_restore = slim.get_model_variables() + + continue_train = True + +else: + + # Create an OP that performs the initialization of + # values of variables to the values from VGG. + read_vgg_weights_except_fc8_func = slim.assign_from_checkpoint_fn( + vgg_checkpoint_path, + vgg_except_fc8_weights) + + # Initializer for new fc8 weights -- for two classes. + vgg_fc8_weights_initializer = tf.variables_initializer(vgg_fc8_weights) + + # Initializer for adam variables + optimization_variables_initializer = tf.variables_initializer(adam_optimizer_variables) + + +sess_config = tf.ConfigProto() +sess_config.gpu_options.allow_growth = True +sess = tf.Session(config=sess_config) + +init_op = tf.global_variables_initializer() +init_local_op = tf.local_variables_initializer() + +saver = tf.train.Saver(max_to_keep=5) + + +def perform_crf(image, probabilities): + + image = image.squeeze() + softmax = probabilities.squeeze().transpose((2, 0, 1)) + + # The input should be the negative of the logarithm of probability values + # Look up the definition of the softmax_to_unary for more information + unary = unary_from_softmax(softmax) + + # The inputs should be C-continious -- we are using Cython wrapper + unary = np.ascontiguousarray(unary) + + d = dcrf.DenseCRF(image.shape[0] * image.shape[1], number_of_classes) + + d.setUnaryEnergy(unary) + + # This potential penalizes small pieces of segmentation that are + # spatially isolated -- enforces more spatially consistent segmentations + feats = create_pairwise_gaussian(sdims=(10, 10), shape=image.shape[:2]) + + d.addPairwiseEnergy(feats, compat=3, + kernel=dcrf.DIAG_KERNEL, + normalization=dcrf.NORMALIZE_SYMMETRIC) + + # This creates the color-dependent features -- + # because the segmentation that we get from CNN are too coarse + # and we can use local color features to refine them + feats = create_pairwise_bilateral(sdims=(50, 50), schan=(20, 20, 20), + img=image, chdim=2) + + d.addPairwiseEnergy(feats, compat=10, + kernel=dcrf.DIAG_KERNEL, + normalization=dcrf.NORMALIZE_SYMMETRIC) + Q = d.inference(5) + + res = np.argmax(Q, axis=0).reshape((image.shape[0], image.shape[1])) + return res + + +with sess: + # Run the initializers. + sess.run(init_op) + sess.run(init_local_op) + if continue_train: + saver.restore(sess, checkpoint_path) + + logging.debug('checkpoint restored from [{0}]'.format(checkpoint_path)) + else: + sess.run(vgg_fc8_weights_initializer) + sess.run(optimization_variables_initializer) + + read_vgg_weights_except_fc8_func(sess) + logging.debug('value initialized...') + + # start data reader + coord = tf.train.Coordinator() + threads = tf.train.start_queue_runners(coord=coord) + + start = time.time() + for i in range(FLAGS.max_steps): + feed_dict_to_use[is_training_placeholder] = True + + gs, _ = sess.run([global_step, train_step], feed_dict=feed_dict_to_use) + if gs % 10 == 0: + gs, loss, summary_string = sess.run([global_step, cross_entropy_loss, merged_summary_op], feed_dict=feed_dict_to_use) + logging.debug("step {0} Current Loss: {1} ".format(gs, loss)) + end = time.time() + logging.debug("[{0:.2f}] imgs/s".format(10 * batch_size / (end - start))) + start = end + + summary_string_writer.add_summary(summary_string, i) + + if gs % 100 == 0: + save_path = saver.save(sess, os.path.join(log_folder, "model.ckpt"), global_step=gs) + logging.debug("Model saved in file: %s" % save_path) + + if gs % 200 == 0: + eval_folder = os.path.join(FLAGS.output_dir, 'eval') + if not os.path.exists(eval_folder): + os.makedirs(eval_folder) + + logging.debug("validation generated at step [{0}]".format(gs)) + feed_dict_to_use[is_training_placeholder] = False + val_pred, val_orig_image, val_annot, val_poss = sess.run([pred, orig_img_tensor, annotation_tensor, probabilities], + feed_dict=feed_dict_to_use) + + cv2.imwrite(os.path.join(eval_folder, 'val_{0}_img.jpg'.format(gs)), np.squeeze(val_orig_image)) + cv2.imwrite(os.path.join(eval_folder, 'val_{0}_annotation.jpg'.format(gs)), grayscale_to_voc_impl(np.squeeze(val_annot))) + cv2.imwrite(os.path.join(eval_folder, 'val_{0}_prediction.jpg'.format(gs)), grayscale_to_voc_impl(np.squeeze(val_pred))) + + crf_ed = perform_crf(val_orig_image, val_poss) + cv2.imwrite(os.path.join(FLAGS.output_dir, 'eval', 'val_{0}_prediction_crfed.jpg'.format(gs)), grayscale_to_voc_impl(np.squeeze(crf_ed))) + + coord.request_stop() + coord.join(threads) + + save_path = saver.save(sess, os.path.join(log_folder, "model.ckpt"), global_step=gs) + logging.debug("Model saved in file: %s" % save_path) + +summary_string_writer.close() diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..3752646 --- /dev/null +++ b/utils.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import numpy as np +import tensorflow as tf + + +def get_kernel_size(factor): + """ + Find the kernel size given the desired factor of upsampling. + """ + return 2 * factor - factor % 2 + + +def upsample_filt(size): + """ + Make a 2D bilinear kernel suitable for upsampling of the given (h, w) size. + """ + factor = (size + 1) // 2 + if size % 2 == 1: + center = factor - 1 + else: + center = factor - 0.5 + og = np.ogrid[:size, :size] + return (1 - abs(og[0] - center) / factor) * \ + (1 - abs(og[1] - center) / factor) + + +def voc_colormap(N=256): + def bitget(val, idx): return ((val & (1 << idx)) != 0) + + cmap = np.zeros((N, 3), dtype=np.uint8) + for i in range(N): + r = g = b = 0 + c = i + for j in range(8): + r |= (bitget(c, 0) << 7 - j) + g |= (bitget(c, 1) << 7 - j) + b |= (bitget(c, 2) << 7 - j) + c >>= 3 + + cmap[i, :] = [r, g, b] + return cmap + + +VOC_COLORMAP = voc_colormap() + + +def grayscale_to_voc_impl(input): + return np.squeeze(VOC_COLORMAP[input]) + + +def bilinear_upsample_weights(factor, number_of_classes): + """ + Create weights matrix for transposed convolution with bilinear filter + initialization. + """ + + filter_size = get_kernel_size(factor) + + weights = np.zeros((filter_size, + filter_size, + number_of_classes, + number_of_classes), dtype=np.float32) + + upsample_kernel = upsample_filt(filter_size) + + for i in range(number_of_classes): + weights[:, :, i, i] = upsample_kernel + + return weights + + +_R_MEAN = 123.68 +_G_MEAN = 116.78 +_B_MEAN = 103.94 + + +def _mean_image_subtraction(image, means): + """Subtracts the given means from each image channel. + + For example: + means = [123.68, 116.779, 103.939] + image = _mean_image_subtraction(image, means) + + Note that the rank of `image` must be known. + + Args: + image: a tensor of size [height, width, C]. + means: a C-vector of values to subtract from each channel. + + Returns: + the centered image. + + Raises: + ValueError: If the rank of `image` is unknown, if `image` has a rank other + than three or if the number of channels in `image` doesn't match the + number of values in `means`. + """ + if image.get_shape().ndims != 3: + raise ValueError('Input must be of size [height, width, C>0]') + num_channels = image.get_shape().as_list()[-1] + if len(means) != num_channels: + raise ValueError('len(means) must match the number of channels') + + channels = tf.split(axis=2, num_or_size_splits=num_channels, value=image) + for i in range(num_channels): + channels[i] -= means[i] + return tf.concat(axis=2, values=channels) diff --git a/val_1000_annotation.jpg b/val_1000_annotation.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2b746d4c45a98e2754be77cb8e0749c4c51d8c2d GIT binary patch literal 13675 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 q^g7@|<{wX literal 0 HcmV?d00001 diff --git a/val_1000_prediction.jpg b/val_1000_prediction.jpg new file mode 100644 index 0000000000000000000000000000000000000000..46308e8a4cfdaca794061537537a415daefcc9b4 GIT binary patch literal 10933 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 F{1+F&0R;d6 literal 0 HcmV?d00001 diff --git a/val_1000_prediction_crfed.jpg b/val_1000_prediction_crfed.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b941fe5449ad56765c78aa95399cc549276a07af GIT binary patch literal 20547 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 VToX7HnjJ((&mE)9xoiJ#0sy>hGspk{ literal 0 HcmV?d00001 diff --git a/vgg.py b/vgg.py new file mode 100644 index 0000000..4fe5c98 --- /dev/null +++ b/vgg.py @@ -0,0 +1,308 @@ +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contains model definitions for versions of the Oxford VGG network. + +These model definitions were introduced in the following technical report: + + Very Deep Convolutional Networks For Large-Scale Image Recognition + Karen Simonyan and Andrew Zisserman + arXiv technical report, 2015 + PDF: http://arxiv.org/pdf/1409.1556.pdf + ILSVRC 2014 Slides: http://www.robots.ox.ac.uk/~karen/pdf/ILSVRC_2014.pdf + CC-BY-4.0 + +More information can be obtained from the VGG website: +www.robots.ox.ac.uk/~vgg/research/very_deep/ + +Usage: + with slim.arg_scope(vgg.vgg_arg_scope()): + outputs, end_points = vgg.vgg_a(inputs) + + with slim.arg_scope(vgg.vgg_arg_scope()): + outputs, end_points = vgg.vgg_16(inputs) + +@@vgg_a +@@vgg_16 +@@vgg_19 +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import tensorflow as tf + +slim = tf.contrib.slim + + +def vgg_arg_scope(weight_decay=0.0005): + """Defines the VGG arg scope. + + Args: + weight_decay: The l2 regularization coefficient. + + Returns: + An arg_scope. + """ + with slim.arg_scope([slim.conv2d, slim.fully_connected], + activation_fn=tf.nn.relu, + weights_regularizer=slim.l2_regularizer(weight_decay), + biases_initializer=tf.zeros_initializer()): + with slim.arg_scope([slim.conv2d], padding='SAME') as arg_sc: + return arg_sc + + +def vgg_a(inputs, + num_classes=1000, + is_training=True, + dropout_keep_prob=0.5, + spatial_squeeze=True, + scope='vgg_a', + fc_conv_padding='VALID', + global_pool=False): + """Oxford Net VGG 11-Layers version A Example. + + Note: All the fully_connected layers have been transformed to conv2d layers. + To use in classification mode, resize input to 224x224. + + Args: + inputs: a tensor of size [batch_size, height, width, channels]. + num_classes: number of predicted classes. If 0 or None, the logits layer is + omitted and the input features to the logits layer are returned instead. + is_training: whether or not the model is being trained. + dropout_keep_prob: the probability that activations are kept in the dropout + layers during training. + spatial_squeeze: whether or not should squeeze the spatial dimensions of the + outputs. Useful to remove unnecessary dimensions for classification. + scope: Optional scope for the variables. + fc_conv_padding: the type of padding to use for the fully connected layer + that is implemented as a convolutional layer. Use 'SAME' padding if you + are applying the network in a fully convolutional manner and want to + get a prediction map downsampled by a factor of 32 as an output. + Otherwise, the output prediction map will be (input / 32) - 6 in case of + 'VALID' padding. + global_pool: Optional boolean flag. If True, the input to the classification + layer is avgpooled to size 1x1, for any input size. (This is not part + of the original VGG architecture.) + + Returns: + net: the output of the logits layer (if num_classes is a non-zero integer), + or the input to the logits layer (if num_classes is 0 or None). + end_points: a dict of tensors with intermediate activations. + """ + with tf.variable_scope(scope, 'vgg_a', [inputs]) as sc: + end_points_collection = sc.original_name_scope + '_end_points' + # Collect outputs for conv2d, fully_connected and max_pool2d. + with slim.arg_scope([slim.conv2d, slim.max_pool2d], + outputs_collections=end_points_collection): + net = slim.repeat(inputs, 1, slim.conv2d, 64, [3, 3], scope='conv1') + net = slim.max_pool2d(net, [2, 2], scope='pool1') + net = slim.repeat(net, 1, slim.conv2d, 128, [3, 3], scope='conv2') + net = slim.max_pool2d(net, [2, 2], scope='pool2') + net = slim.repeat(net, 2, slim.conv2d, 256, [3, 3], scope='conv3') + net = slim.max_pool2d(net, [2, 2], scope='pool3') + net = slim.repeat(net, 2, slim.conv2d, 512, [3, 3], scope='conv4') + net = slim.max_pool2d(net, [2, 2], scope='pool4') + net = slim.repeat(net, 2, slim.conv2d, 512, [3, 3], scope='conv5') + net = slim.max_pool2d(net, [2, 2], scope='pool5') + + # Use conv2d instead of fully_connected layers. + net = slim.conv2d(net, 4096, [7, 7], padding=fc_conv_padding, scope='fc6') + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout6') + net = slim.conv2d(net, 4096, [1, 1], scope='fc7') + # Convert end_points_collection into a end_point dict. + end_points = slim.utils.convert_collection_to_dict(end_points_collection) + if global_pool: + net = tf.reduce_mean(net, [1, 2], keep_dims=True, name='global_pool') + end_points['global_pool'] = net + if num_classes: + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout7') + net = slim.conv2d(net, num_classes, [1, 1], + activation_fn=None, + normalizer_fn=None, + scope='fc8') + if spatial_squeeze: + net = tf.squeeze(net, [1, 2], name='fc8/squeezed') + end_points[sc.name + '/fc8'] = net + return net, end_points + + +vgg_a.default_image_size = 224 + + +def vgg_16(inputs, + num_classes=1000, + is_training=True, + dropout_keep_prob=0.5, + spatial_squeeze=True, + scope='vgg_16', + fc_conv_padding='VALID', + global_pool=False): + """Oxford Net VGG 16-Layers version D Example. + + Note: All the fully_connected layers have been transformed to conv2d layers. + To use in classification mode, resize input to 224x224. + + Args: + inputs: a tensor of size [batch_size, height, width, channels]. + num_classes: number of predicted classes. If 0 or None, the logits layer is + omitted and the input features to the logits layer are returned instead. + is_training: whether or not the model is being trained. + dropout_keep_prob: the probability that activations are kept in the dropout + layers during training. + spatial_squeeze: whether or not should squeeze the spatial dimensions of the + outputs. Useful to remove unnecessary dimensions for classification. + scope: Optional scope for the variables. + fc_conv_padding: the type of padding to use for the fully connected layer + that is implemented as a convolutional layer. Use 'SAME' padding if you + are applying the network in a fully convolutional manner and want to + get a prediction map downsampled by a factor of 32 as an output. + Otherwise, the output prediction map will be (input / 32) - 6 in case of + 'VALID' padding. + global_pool: Optional boolean flag. If True, the input to the classification + layer is avgpooled to size 1x1, for any input size. (This is not part + of the original VGG architecture.) + + Returns: + net: the output of the logits layer (if num_classes is a non-zero integer), + or the input to the logits layer (if num_classes is 0 or None). + end_points: a dict of tensors with intermediate activations. + """ + with tf.variable_scope(scope, 'vgg_16', [inputs]) as sc: + end_points_collection = sc.original_name_scope + '_end_points' + # Collect outputs for conv2d, fully_connected and max_pool2d. + with slim.arg_scope([slim.conv2d, slim.fully_connected, slim.max_pool2d], + outputs_collections=end_points_collection): + net = slim.repeat(inputs, 2, slim.conv2d, 64, [3, 3], scope='conv1') + net = slim.max_pool2d(net, [2, 2], scope='pool1') + net = slim.repeat(net, 2, slim.conv2d, 128, [3, 3], scope='conv2') + net = slim.max_pool2d(net, [2, 2], scope='pool2') + net = slim.repeat(net, 3, slim.conv2d, 256, [3, 3], scope='conv3') + net = slim.max_pool2d(net, [2, 2], scope='pool3') + net = slim.repeat(net, 3, slim.conv2d, 512, [3, 3], scope='conv4') + net = slim.max_pool2d(net, [2, 2], scope='pool4') + net = slim.repeat(net, 3, slim.conv2d, 512, [3, 3], scope='conv5') + net = slim.max_pool2d(net, [2, 2], scope='pool5') + + # Use conv2d instead of fully_connected layers. + net = slim.conv2d(net, 4096, [7, 7], padding=fc_conv_padding, scope='fc6') + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout6') + net = slim.conv2d(net, 4096, [1, 1], scope='fc7') + # Convert end_points_collection into a end_point dict. + end_points = slim.utils.convert_collection_to_dict(end_points_collection) + if global_pool: + net = tf.reduce_mean(net, [1, 2], keep_dims=True, name='global_pool') + end_points['global_pool'] = net + if num_classes: + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout7') + net = slim.conv2d(net, num_classes, [1, 1], + activation_fn=None, + normalizer_fn=None, + scope='fc8') + if spatial_squeeze and num_classes is not None: + net = tf.squeeze(net, [1, 2], name='fc8/squeezed') + end_points[sc.name + '/fc8'] = net + return net, end_points + + +vgg_16.default_image_size = 224 + + +def vgg_19(inputs, + num_classes=1000, + is_training=True, + dropout_keep_prob=0.5, + spatial_squeeze=True, + scope='vgg_19', + fc_conv_padding='VALID', + global_pool=False): + """Oxford Net VGG 19-Layers version E Example. + + Note: All the fully_connected layers have been transformed to conv2d layers. + To use in classification mode, resize input to 224x224. + + Args: + inputs: a tensor of size [batch_size, height, width, channels]. + num_classes: number of predicted classes. If 0 or None, the logits layer is + omitted and the input features to the logits layer are returned instead. + is_training: whether or not the model is being trained. + dropout_keep_prob: the probability that activations are kept in the dropout + layers during training. + spatial_squeeze: whether or not should squeeze the spatial dimensions of the + outputs. Useful to remove unnecessary dimensions for classification. + scope: Optional scope for the variables. + fc_conv_padding: the type of padding to use for the fully connected layer + that is implemented as a convolutional layer. Use 'SAME' padding if you + are applying the network in a fully convolutional manner and want to + get a prediction map downsampled by a factor of 32 as an output. + Otherwise, the output prediction map will be (input / 32) - 6 in case of + 'VALID' padding. + global_pool: Optional boolean flag. If True, the input to the classification + layer is avgpooled to size 1x1, for any input size. (This is not part + of the original VGG architecture.) + + Returns: + net: the output of the logits layer (if num_classes is a non-zero integer), + or the non-dropped-out input to the logits layer (if num_classes is 0 or + None). + end_points: a dict of tensors with intermediate activations. + """ + with tf.variable_scope(scope, 'vgg_19', [inputs]) as sc: + end_points_collection = sc.original_name_scope + '_end_points' + # Collect outputs for conv2d, fully_connected and max_pool2d. + with slim.arg_scope([slim.conv2d, slim.fully_connected, slim.max_pool2d], + outputs_collections=end_points_collection): + net = slim.repeat(inputs, 2, slim.conv2d, 64, [3, 3], scope='conv1') + net = slim.max_pool2d(net, [2, 2], scope='pool1') + net = slim.repeat(net, 2, slim.conv2d, 128, [3, 3], scope='conv2') + net = slim.max_pool2d(net, [2, 2], scope='pool2') + net = slim.repeat(net, 4, slim.conv2d, 256, [3, 3], scope='conv3') + net = slim.max_pool2d(net, [2, 2], scope='pool3') + net = slim.repeat(net, 4, slim.conv2d, 512, [3, 3], scope='conv4') + net = slim.max_pool2d(net, [2, 2], scope='pool4') + net = slim.repeat(net, 4, slim.conv2d, 512, [3, 3], scope='conv5') + net = slim.max_pool2d(net, [2, 2], scope='pool5') + + # Use conv2d instead of fully_connected layers. + net = slim.conv2d(net, 4096, [7, 7], padding=fc_conv_padding, scope='fc6') + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout6') + net = slim.conv2d(net, 4096, [1, 1], scope='fc7') + # Convert end_points_collection into a end_point dict. + end_points = slim.utils.convert_collection_to_dict(end_points_collection) + if global_pool: + net = tf.reduce_mean(net, [1, 2], keep_dims=True, name='global_pool') + end_points['global_pool'] = net + if num_classes: + net = slim.dropout(net, dropout_keep_prob, is_training=is_training, + scope='dropout7') + net = slim.conv2d(net, num_classes, [1, 1], + activation_fn=None, + normalizer_fn=None, + scope='fc8') + if spatial_squeeze: + net = tf.squeeze(net, [1, 2], name='fc8/squeezed') + end_points[sc.name + '/fc8'] = net + return net, end_points + + +vgg_19.default_image_size = 224 + +# Alias +vgg_d = vgg_16 +vgg_e = vgg_19