Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Codes/Deeplab_network/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2017 Zhengyang Wang

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
154 changes: 154 additions & 0 deletions Codes/Deeplab_network/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# Deeplab v2 ResNet for Semantic Image Segmentation

This is an (re-)implementation of [DeepLab v2 (ResNet-101)](http://liangchiehchen.com/projects/DeepLabv2_resnet.html) in TensorFlow for semantic image segmentation on the [PASCAL VOC 2012 dataset](http://host.robots.ox.ac.uk/pascal/VOC/). We refer to [DrSleep's implementation](https://github.com/DrSleep/tensorflow-deeplab-resnet) (Many thanks!). We do not use tf-to-caffe packages like kaffe so you only need TensorFlow 1.3.0+ to run this code.

The deeplab pre-trained ResNet-101 ckpt files (pre-trained on MSCOCO) are provided by DrSleep -- [here](https://drive.google.com/drive/folders/0B_rootXHuswsZ0E4Mjh1ZU5xZVU). Thanks again!

Created by [Zhengyang Wang](http://www.eecs.wsu.edu/~zwang6/) and [Shuiwang Ji](http://www.eecs.wsu.edu/~sji/) at Washington State University.

## Update

**12/13/2017**:

* Now the test code will output the mIoU as well as the IoU for each class.

**12/12/2017**:

* Add 'predict' function, you can use '--option=predict' to save your outputs now (both the true prediction where each pixel is between 0 and 20 and the visual one where each class has its own color).

* Add multi-scale training, testing and predicting. Check main_msc.py and model_msc.py and use them just as main.py and model.py.

* Add plot_training_curve.py to use the log.txt to make plots of training curve.

* Now this is a 'full' (re-)implementation of [DeepLab v2 (ResNet-101)](http://liangchiehchen.com/projects/DeepLabv2_resnet.html) in TensorFlow. Thank you for the support. You are welcome to report your settings and results as well as any bug!

**11/09/2017**:

* The new version enables using original ImageNet pre-trained ResNet models (without pre-training on MSCOCO). You may change arguments ('encoder_name' and 'pretrain_file') in main.py to use corresponding pre-trained models. The original pre-trained ResNet-101 ckpt files are provided by tensorflow officially -- [res101](http://download.tensorflow.org/models/resnet_v1_101_2016_08_28.tar.gz) and [res50](http://download.tensorflow.org/models/resnet_v1_50_2016_08_28.tar.gz).

* To help those who want to use this model on the CityScapes dataset, I shared the corresponding txt files and the python file which generates them. Note that you need to use tools [here](https://github.com/mcordts/cityscapesScripts) to generate labels with trainID first. Hope it would be helpful. Do not forget to change IMG_MEAN in model.py and other settings in main.py.

* 'is_training' argument is removed and 'self._batch_norm' changes. Basically, for a small batch size, it is better to keep the statistics of the BN layers (running means and variances) frozen, and to not update the values provided by the pre-trained model by setting 'is_training=False'. Note that is_training=False still updates BN parameters gamma (scale) and beta (offset) if they are presented in var_list of the optimiser definition. Set 'trainable=False' in BN fuctions to remove them from trainable_variables.

* Add 'phase' argument in network.py for future development. 'phase=True' means training. It is mainly for controlling batch normalization (if any) in the non-pre-trained part.
```
Example: If you have a batch normalization layer in the decoder, you should use

outputs = self._batch_norm(inputs, name='g_bn1', is_training=self.phase, activation_fn=tf.nn.relu, trainable=True)
```
* Some changes to make the code more readable and easy to modify for future research.

* I plan to add 'predict' function to enable saving predicted results for offline evaluation, post-processing, etc.

## System requirement

#### Programming language
```
Python 3.5
```
#### Python Packages
```
tensorflow-gpu 1.3.0
```
## Configure the network

All network hyperparameters are configured in main.py.

#### Training
```
num_steps: how many iterations to train

save_interval: how many steps to save the model

random_seed: random seed for tensorflow

weight_decay: l2 regularization parameter

learning_rate: initial learning rate

power: parameter for poly learning rate

momentum: momentum

encoder_name: name of pre-trained model, res101, res50 or deeplab

pretrain_file: the initial pre-trained model file for transfer learning

data_list: training data list file

grad_update_every (msc only): accumulate the gradients for how many steps before updating weights. Note that in the msc case, this is actually the true training batch size.
```
#### Testing/Validation
```
valid_step: checkpoint number for testing/validation

valid_num_steps: = number of testing/validation samples

valid_data_list: testing/validation data list file
```
#### Data
```
data_dir: data directory

batch_size: training batch size

input height: height of input image

input width: width of input image

num_classes: number of classes

ignore_label: label pixel value that should be ignored

random_scale: whether to perform random scaling data-augmentation

random_mirror: whether to perform random left-right flipping data-augmentation
```
#### Log
```
modeldir: where to store saved models

logfile: where to store training log

logdir: where to store log for tensorboard
```
## Training and Testing

#### Start training

After configuring the network, we can start to train. Run
```
python main.py
```
The training of Deeplab v2 ResNet will start.

#### Training process visualization

We employ tensorboard for visualization.

```
tensorboard --logdir=log --port=6006
```

You may visualize the graph of the model and (training images + groud truth labels + predicted labels).

To visualize the training loss curve, write your own script to make use of the training log.

#### Testing and prediction

Select a checkpoint to test/validate your model in terms of pixel accuracy and mean IoU.

Fill the valid_step in main.py with the checkpoint you want to test. Change valid_num_steps and valid_data_list accordingly. Run

```
python main.py --option=test
```

The final output includes pixel accuracy and mean IoU.

Run

```
python main.py --option=predict
```
The outputs will be saved in the 'output' folder.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
137 changes: 137 additions & 0 deletions Codes/Deeplab_network/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import argparse
import os
import tensorflow as tf
from model import Model



"""
This script defines hyperparameters.
"""



def configure(test_data_list_, out_dir_, test_step_, test_num_steps_, modeldir_, data_dir_, num_steps_,
save_interval_, learning_rate_, pretrain_file_, data_list_, batch_size_, input_height_, input_width_,
num_classes_, print_color_, log_dir_, log_file_,encoder_name_):
flags = tf.app.flags

# training
flags.DEFINE_integer('num_steps', num_steps_, 'maximum number of iterations')
flags.DEFINE_integer('save_interval', save_interval_, 'number of iterations for saving and visualization')
flags.DEFINE_integer('random_seed', 1234, 'random seed')
flags.DEFINE_float('weight_decay', 0.0005, 'weight decay rate')
flags.DEFINE_float('learning_rate', learning_rate_, 'learning rate')
flags.DEFINE_float('power', 0.9, 'hyperparameter for poly learning rate')
flags.DEFINE_float('momentum', 0.9, 'momentum')
flags.DEFINE_string('encoder_name', encoder_name_, 'name of pre-trained model, res101, res50 or deeplab')
flags.DEFINE_string('pretrain_file', pretrain_file_, 'pre-trained model filename corresponding to encoder_name')
flags.DEFINE_string('data_list', data_list_, 'training data list filename')

# validation
flags.DEFINE_integer('valid_step', 217000, 'checkpoint number for validation')
flags.DEFINE_integer('valid_num_steps', 81605, '= number of validation samples')
flags.DEFINE_string('valid_data_list', './dataAugment/val.txt', 'validation data list filename')

# prediction / saving outputs for testing or validation
flags.DEFINE_string('out_dir', out_dir_, 'directory for saving outputs')
flags.DEFINE_integer('test_step', test_step_, 'checkpoint number for testing/validation')
flags.DEFINE_integer('test_num_steps', test_num_steps_, '= number of testing/validation samples')
flags.DEFINE_string('test_data_list', test_data_list_, 'testing/validation data list filename')
flags.DEFINE_boolean('visual', False, 'whether to save predictions for visualization')

# data
flags.DEFINE_string('data_dir', data_dir_, 'data directory')
flags.DEFINE_integer('batch_size', batch_size_, 'training batch size')
flags.DEFINE_integer('input_height', input_height_, 'input image height')
flags.DEFINE_integer('input_width', input_width_, 'input image width')
flags.DEFINE_integer('num_classes', num_classes_, 'number of classes')
flags.DEFINE_integer('ignore_label', 255, 'label pixel value that should be ignored')
flags.DEFINE_boolean('random_scale', False, 'whether to perform random scaling data-augmentation')
flags.DEFINE_boolean('random_mirror', False, 'whether to perform random left-right flipping data-augmentation')

# log
flags.DEFINE_string('modeldir', modeldir_, 'model directory')
flags.DEFINE_string('logfile', log_file_, 'training log filename')
flags.DEFINE_string('logdir', log_dir_, 'training log directory')

# text color
flags.DEFINE_string('print_color', print_color_, 'color of printed outputs')



flags.FLAGS.__dict__['__parsed'] = False
return flags.FLAGS

def main(_):
if args.option not in ['train', 'test', 'predict']:
print('invalid option: ', args.option)
print("Please input a option: train, test, or predict")
else:
# Set up tf session and initialize variables.
# config = tf.ConfigProto()
# config.gpu_options.allow_growth = True
# sess = tf.Session(config=config)
sess = tf.Session()
# Run
model = Model(sess, configure(test_data_list_=args.test_data_list, out_dir_=args.out_dir, test_step_=args.test_step,
test_num_steps_=args.test_num_steps, modeldir_=args.modeldir, data_dir_=args.data_dir,
num_steps_=args.num_steps, save_interval_=args.save_interval, learning_rate_=args.learning_rate,
pretrain_file_=args.pretrain_file, data_list_=args.data_list, batch_size_=args.batch_size,
input_height_=args.input_height, input_width_=args.input_width, num_classes_=args.num_classes,
print_color_=args.print_color, log_dir_=args.log_dir, log_file_=args.log_file, encoder_name_=args.encoder_name))
getattr(model, args.option)()


if __name__ == '__main__':
parser = argparse.ArgumentParser()

parser.add_argument('--option', dest='option', type=str, default='train',
help='actions: train, test, or predict')
parser.add_argument('--test_data_list', dest='test_data_list', type=str, default='./dataset/test.txt',
help='testing/validation data list filename')
parser.add_argument('--out_dir', dest='out_dir', type=str, default='output',
help='directory for saving testing outputs')
parser.add_argument('--test_step', dest='test_step', type=int, default=350000,
help='checkpoint number for testing/validation')
parser.add_argument('--test_num_steps', dest='test_num_steps', type=int, default=81605,
help='number of testing/validation samples')
parser.add_argument('--modeldir', dest='modeldir', type=str, default='modelAugment',
help='model directory')
parser.add_argument('--data_dir', dest='data_dir', type=str, default='/hdd/wsi_fun/ImageAugCustom/AugmentationOutput',
help='data directory')
parser.add_argument('--gpu', dest='gpu', type=str, default='0',
help='specify which GPU to use')
parser.add_argument('--num_steps', dest='num_steps', type=int, default=100000,
help='maximum number of iterations')
parser.add_argument('--save_interval', dest='save_interval', type=int, default=15000,
help='number of iterations for saving and visualization')
parser.add_argument('--learning_rate', dest='learning_rate', type=float, default=2.5e-4,
help='learning rate')
parser.add_argument('--pretrain_file', dest='pretrain_file', type=str, default='deeplab_resnet.ckpt',
help='pre-trained model filename corresponding to encoder_name')
parser.add_argument('--data_list', dest='data_list', type=str, default='./dataAugment/train.txt',
help='training data list filename')
parser.add_argument('--batch_size', dest='batch_size', type=int, default=15,
help='training batch size')
parser.add_argument('--input_height', dest='input_height', type=int, default=256,
help='input image height')
parser.add_argument('--input_width', dest='input_width', type=int, default=256,
help='input image width')
parser.add_argument('--num_classes', dest='num_classes', type=int, default=2,
help='number of classes in images')
parser.add_argument('--log_dir', dest='log_dir', type=str, default="log",
help='directory for saving log files')
parser.add_argument('--log_file', dest='log_file', type=str, default="log.txt",
help='Default logfile name')
parser.add_argument('--print_color', dest='print_color', type=str, default="\033[0;37;40m",
help='color of printed text')
parser.add_argument('--encoder_name', dest='encoder_name', type=str, default=" ",
help='color of printed text')


args = parser.parse_args()

# Choose which gpu or cpu to use
os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu
tf.app.run()
82 changes: 82 additions & 0 deletions Codes/Deeplab_network/main.py~
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import argparse
import os
import tensorflow as tf
from model import Model



"""
This script defines hyperparameters.
"""



def configure():
flags = tf.app.flags

# training
flags.DEFINE_integer('num_steps', 250000, 'maximum number of iterations')
flags.DEFINE_integer('save_interval', 5000, 'number of iterations for saving and visualization')
flags.DEFINE_integer('random_seed', 1234, 'random seed')
flags.DEFINE_float('weight_decay', 0.0005, 'weight decay rate')
flags.DEFINE_float('learning_rate', 2.5e-4, 'learning rate')
flags.DEFINE_float('power', 0.9, 'hyperparameter for poly learning rate')
flags.DEFINE_float('momentum', 0.9, 'momentum')
flags.DEFINE_string('encoder_name', 'deeplab', 'name of pre-trained model, res101, res50 or deeplab')
flags.DEFINE_string('pretrain_file', 'model3/', 'pre-trained model filename corresponding to encoder_name')
flags.DEFINE_string('data_list', './dataset/train.txt', 'training data list filename')

# validation
flags.DEFINE_integer('valid_step', 200000, 'checkpoint number for validation')
flags.DEFINE_integer('valid_num_steps', 32659, '= number of validation samples')
flags.DEFINE_string('valid_data_list', './dataset/val.txt', 'validation data list filename')

# prediction / saving outputs for testing or validation
flags.DEFINE_string('out_dir', 'output', 'directory for saving outputs')
flags.DEFINE_integer('test_step', 60000, 'checkpoint number for testing/validation')
flags.DEFINE_integer('test_num_steps', 48209, '= number of testing/validation samples')
flags.DEFINE_string('test_data_list', './dataset/test.txt', 'testing/validation data list filename')
flags.DEFINE_boolean('visual', True, 'whether to save predictions for visualization')

# data
flags.DEFINE_string('data_dir', '/hdd/wsi_fun/wsi_data/wsi_blocks/', 'data directory')
flags.DEFINE_integer('batch_size', 15, 'training batch size')
flags.DEFINE_integer('input_height', 256, 'input image height')
flags.DEFINE_integer('input_width', 256, 'input image width')
flags.DEFINE_integer('num_classes', 2, 'number of classes')
flags.DEFINE_integer('ignore_label', 254, 'label pixel value that should be ignored')
flags.DEFINE_boolean('random_scale', True, 'whether to perform random scaling data-augmentation')
flags.DEFINE_boolean('random_mirror', True, 'whether to perform random left-right flipping data-augmentation')

# log
flags.DEFINE_string('modeldir', 'model3', 'model directory')
flags.DEFINE_string('logfile', 'log.txt', 'training log filename')
flags.DEFINE_string('logdir', 'log', 'training log directory')

flags.FLAGS.__dict__['__parsed'] = False
return flags.FLAGS

def main(_):
parser = argparse.ArgumentParser()
parser.add_argument('--option', dest='option', type=str, default='train',
help='actions: train, test, or predict')
args = parser.parse_args()

if args.option not in ['train', 'test', 'predict']:
print('invalid option: ', args.option)
print("Please input a option: train, test, or predict")
else:
# Set up tf session and initialize variables.
# config = tf.ConfigProto()
# config.gpu_options.allow_growth = True
# sess = tf.Session(config=config)
sess = tf.Session()
# Run
model = Model(sess, configure())
getattr(model, args.option)()


if __name__ == '__main__':
# Choose which gpu or cpu to use
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
tf.app.run()
Loading