Fully Convolutional DenseNet (A.K.A 100 layer tiramisu) for semantic segmentation of images implemented in TensorFlow.

Overview

FC-DenseNet-Tensorflow

This is a re-implementation of the 100 layer tiramisu, technically a fully convolutional DenseNet, in TensorFlow (Tiramisu). The aim of the repository is to break down the working modules of the network, as presented in the paper, for ease of understanding. To facilitate this, the network is defined in a class, with functions for each block in the network. This promotes a modular view, and an understanding of what each component does individually. I tried to make the model code more readable, and this is the main aim of the this repository.

Network Architecture

Submodules

The "submodules" that build up the Tiramisu are explained here. Note: The graphics are just a redrawing of the ones from the original paper.

The Conv Layer:

The "conv layer" is the most atomic unit of the FC-DenseNet, it is the building block of all other modules. The following image shows the conv layer:

In code, it is implemented as:
def conv_layer(self, x, training, filters, name):
    with tf.name_scope(name):
        x = self.batch_norm(x, training, name=name+'_bn')
        x = tf.nn.relu(x, name=name+'_relu')
        x = tf.layers.conv2d(x,
                             filters=filters,
                             kernel_size=[3, 3],
                             strides=[1, 1],
                             padding='SAME',
                             dilation_rate=[1, 1],
                             activation=None,
                             kernel_initializer=tf.contrib.layers.xavier_initializer(),
                             name=name+'_conv3x3')
        x = tf.layers.dropout(x, rate=0.2, training=training, name=name+'_dropout')

As can be seen, each "convolutional" layer is actually a 4 step procedure of batch normalization -> Relu -> 2D-Convolution -> Dropout.

The Dense Block

The dense block is a sequence of convolutions followed by concatenations. The output of a conv layer is concated depth wise with its input, this forms the input to the next layer, and is repeated for all layers in a dense block. For the final output i.e., the output of the Dense Block, all the outputs of each conv layer in the block are concated, as shown:

In code, it is implemented as:

def dense_block(self, x, training, block_nb, name):
    dense_out = []
    with tf.name_scope(name):
        for i in range(self.layers_per_block[block_nb]):
            conv = self.conv_layer(x, training, self.growth_k, name=name+'_layer_'+str(i))
            x = tf.concat([conv, x], axis=3)
            dense_out.append(conv)

        x = tf.concat(dense_out, axis=3)

    return x

How to Run

To run the network on your own dataset, do the following:

  1. Clone this repository.
  2. Open up your terminal and navigate to the cloned repository
  3. Type in the following:
python main.py --mode=train --train_data=path/to/train/data --val_data=path/to/validation/data \
--ckpt=path/to/save/checkpoint/model.ckpt --layers_per_block=4,5,7,10,12,15 \
--batch_size=8 --epochs=10 --growth_k=16 --num_classes=2 --learning_rate=0.001

The "layers_per_block" argument is only specified for the downsample path, upto the final bottleneck dense block, the upsample path is then automatically built by mirroring the downsample path.

Run with trained checkpoint

To run the code with a trained checkpoint file on images, use the infer mode in in the command line options, like so:

python main.py --mode=infer --infer_data=path/to/infer/data --batch_size=4 \
--ckpt=models/model.ckpt-20 --output_folder=outputs

Tests

The python files ending with "*_test.py" are unit test files, if you make changes or have just cloned the repo, it is a good idea to run them once in your favorite Python IDE, they should let you know if your changes break anything. Currently, the test coverage is not that high, I plan to keep adding more in the future.

TODOs:

  1. Add some more functionality in the code.
  2. Add more detail into this readme.
  3. Save model graph.
  4. Rework command line arguments.
  5. Update with some examples of performance once trained.
  6. Increase test coverage.
  7. Save loss summaries for Tensorboard.
Comments
  • the iou always equals to 0.5 when I use my dataset to train the model

    the iou always equals to 0.5 when I use my dataset to train the model

    Thank you for your work. I have the problem that the iou always equals to 0.5 when I use my dataset to train the model. I am looking forward to your answers.

    opened by yangyang9706 6
  • Cant read Inputfiles

    Cant read Inputfiles

    I've set the default Path, in the main.py script, to my Dataset Folder:

    parser.add_argument("--train_data", default="./dataset/img", help="Directory for training images")

    My folder sctruture inside the project looks like this:

    • dataset
      • img
        • images
        • masks

    When i call the main.py script without arguments, i get the error: TypeError: Input 'filename' of 'ReadFile' Op has type float32 that does not match expected type of string.

    opened by michaelwachter 4
  • Infer fail due to model shape not match

    Infer fail due to model shape not match

    I'm trying to run train & infer. However I encounter error while infer

    InvalidArgumentError (see above for traceback): Assign requires shapes of both tensors to match. lhs shape= [1,1,48,2] rhs shape= [1,1,80,2]
    	 [[Node: save/Assign_87 = Assign[T=DT_FLOAT, _class=["loc:@prediction/last_conv1x1/kernel"], use_locking=true, validate_shape=true, _device="/job:localhost/replica:0/task:0/device:CPU:0"](prediction/last_conv1x1/kernel, save/RestoreV2_87)]]
    

    Could you provide some advise, Thanks

    opened by shouyinz 3
  • about the upsampling

    about the upsampling

    hey I am building the FC-dense net. in the paper. The upsampling path is only using the output of the last dense block but in your code print("Building upsample path...")

    for i, block_nb in enumerate(range(self.nb_blocks - 1, 0, -1)):
        x = self.transition_up(x, x.get_shape()[-1], 'trans_up_' + str(block_nb))
        x = tf.concat([x, concats[len(concats) - i - 1]], axis=3, name='up_concat_' + str(block_nb))
        print(x.get_shape())
        x = self.dense_block(x, training, block_nb, 'up_dense_block_' + str(block_nb))
    

    here x is the last skip list tensor--->concats[4] maybe you should write this: x=dense before the for loop,so that x will be the output of the dense block thanks.

    opened by Fengmoon93 3
  • Some minor bugs.

    Some minor bugs.

    • weight init In the original paper, he initialization is used instead of xavier, this would translate to using: tf.contrib.layers.variance_scaling_initializer
    • max pooling In the original paper, the transition down should be a 2x2 max pool that is non-overlapping. Checking the original Lasagne code it seems they use a 2x2 max pool with a window of 2x2 and stride of 2x2. Wasn't sure if your current 4x4 window as intentional.

    Great work on this btw, very readable!

    opened by Ouwen 2
  • two bugs?

    two bugs?

    I found two issues in the process of running the codes.

    1. Model.py (line#: 66), it should be 'def batch_norm(self, x, training, name)'?

    2. Model.py (line#: 229), it should be 'x = self.dense_block(x, training, block_nb - 1, 'up_dense_block_' + str(block_nb))' ?

    opened by zem007 2
  • HI~Can i ask about this error?

    HI~Can i ask about this error?

    i didnt change any word in model.py

    Traceback (most recent call last): File "main.py", line 44, in main() File "main.py", line 38, in main FLAGS.batch_size, FLAGS.epochs, FLAGS.learning_rate) File "/home/user/CHI_FCN/FC-DenseNet-TensorFlow-master/model.py", line 347, in train total_train_cost / train_step, total_val_cost / val_step)) UnboundLocalError: local variable 'train_step' referenced before assignment

    opened by CHIJUI0128 1
  • normalize_data problem why image/255 and mask/255 when training

    normalize_data problem why image/255 and mask/255 when training

    before training, why should image/255 and mask/255 my mask's each pixel is an index in [0,classnumber] if mask/255 they will all be 0 (class:background) when i use pascal VOC 2012 dataset
    one more thing why use 30 in parse resize normaliza and shuffle thanks a lot

    opened by sdjsngs 1
  •  Could not create cudnn handle: CUDNN_STATUS_NOT_INITIALIZED  and  Possibly insufficient driver version: 384.81.0 Segmentation fault (core dumped)

    Could not create cudnn handle: CUDNN_STATUS_NOT_INITIALIZED and Possibly insufficient driver version: 384.81.0 Segmentation fault (core dumped)

    when i run the order : python main.py --mode=train --train_data=/mnt/saners-extend/FC-DenseNet-TensorFlow/data/train --val_data=/mnt/saners-extend/FC-DenseNet-TensorFlow/data/val --layers_per_block=4,5,7,10,12,15 --batch_size=2 --epochs=10 --growth_k=16 --num_classes=2 --learning_rate=0.001

    it shows that: /home/anaconda3/lib/python3.6/site-packages/h5py/init.py:36: FutureWarning: Conversion of the second argument of issubdtype from float to np.floating is deprecated. In future, it will be treated as np.float64 == np.dtype(float).type. from ._conv import register_converters as _register_converters First Convolution Out: (?, 256, 256, 48) Downsample Out: (?, 128, 128, 112) Downsample Out: (?, 64, 64, 192) Downsample Out: (?, 32, 32, 304) Downsample Out: (?, 16, 16, 464) Downsample Out: (?, 8, 8, 656) Bottleneck Block: (?, 8, 8, 240) Upsample after concat: (?, 16, 16, 896) Upsample after concat: (?, 32, 32, 704) Upsample after concat: (?, 64, 64, 496) Upsample after concat: (?, 128, 128, 352) Upsample after concat: (?, 256, 256, 224) Mask Prediction: (?, 256, 256, 2) 2018-10-25 15:54:14.641467: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA 2018-10-25 15:54:14.781306: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:897] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero 2018-10-25 15:54:14.781714: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1405] Found device 0 with properties: name: Tesla P100-PCIE-12GB major: 6 minor: 0 memoryClockRate(GHz): 1.3285 pciBusID: 0000:05:01.0 totalMemory: 11.91GiB freeMemory: 2.58GiB 2018-10-25 15:54:14.781753: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1484] Adding visible gpu devices: 0 2018-10-25 15:54:15.190540: I tensorflow/core/common_runtime/gpu/gpu_device.cc:965] Device interconnect StreamExecutor with strength 1 edge matrix: 2018-10-25 15:54:15.190615: I tensorflow/core/common_runtime/gpu/gpu_device.cc:971] 0 2018-10-25 15:54:15.190628: I tensorflow/core/common_runtime/gpu/gpu_device.cc:984] 0: N 2018-10-25 15:54:15.190885: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1097] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 2277 MB memory) -> physical GPU (device: 0, name: Tesla P100-PCIE-12GB, pci bus id: 0000:05:01.0, compute capability: 6.0) 2018-10-25 15:55:52.442988: E tensorflow/stream_executor/cuda/cuda_dnn.cc:352] Could not create cudnn handle: CUDNN_STATUS_NOT_INITIALIZED 2018-10-25 15:55:52.443130: E tensorflow/stream_executor/cuda/cuda_dnn.cc:360] Possibly insufficient driver version: 384.81.0 Segmentation fault (core dumped)

    my environment is cuda9.0, cudnn7.0,tensorflow 1.10.1,anyone can give some advice ? thanks very much

    opened by sanersbug 1
  • Why not change the training mode to 'False' in the line # 339?

    Why not change the training mode to 'False' in the line # 339?

    Hi, thanks for your sharing. I learned a lot! I am little confused for the training mode in the Model.py (line#: 339). To get the dice for the validation set, we should change the training mode from 'True' to 'False', is that right? Because we we have trained the weights by the training set, and we should not train any weights by the validation set.

    I am a new learner. I will be very grateful if you reply me. Thanks a lot!

    opened by zem007 1
  • Pictures in output are all black

    Pictures in output are all black

    after training,model will save three ckpt files, .index .meta and .data, how can I run infer?I run the
    python main.py --ckpt=models/model.ckpt-4 but the pictures in output are all black. And there is no errors and warnings.

    opened by summerrr 1
Owner
Hasnain Raza
Hasnain Raza
Quickly comparing your image classification models with the state-of-the-art models (such as DenseNet, ResNet, ...)

Image Classification Project Killer in PyTorch This repo is designed for those who want to start their experiments two days before the deadline and ki

null 349 Dec 8, 2022
A PyTorch implementation of DenseNet.

A PyTorch Implementation of DenseNet This is a PyTorch implementation of the DenseNet-BC architecture as described in the paper Densely Connected Conv

Brandon Amos 771 Dec 15, 2022
DenseNet Implementation in Keras with ImageNet Pretrained Models

DenseNet-Keras with ImageNet Pretrained Models This is an Keras implementation of DenseNet with ImageNet pretrained weights. The weights are converted

Felix Yu 568 Oct 31, 2022
A PyTorch implementation for V-Net: Fully Convolutional Neural Networks for Volumetric Medical Image Segmentation

A PyTorch implementation of V-Net Vnet is a PyTorch implementation of the paper V-Net: Fully Convolutional Neural Networks for Volumetric Medical Imag

Matthew Macy 606 Dec 21, 2022
Tensorflow 2.x implementation of Panoramic BlitzNet for object detection and semantic segmentation on indoor panoramic images.

Deep neural network for object detection and semantic segmentation on indoor panoramic images. The implementation is based on the papers:

Alejandro de Nova Guerrero 9 Nov 24, 2022
An image base contains 490 images for learning (400 cars and 90 boats), and another 21 images for testingAn image base contains 490 images for learning (400 cars and 90 boats), and another 21 images for testing

SVM Données Une base d’images contient 490 images pour l’apprentissage (400 voitures et 90 bateaux), et encore 21 images pour fait des tests. Prétrait

Achraf Rahouti 3 Nov 30, 2021
Recall Loss for Semantic Segmentation (This repo implements the paper: Recall Loss for Semantic Segmentation)

Recall Loss for Semantic Segmentation (This repo implements the paper: Recall Loss for Semantic Segmentation) Download Synthia dataset The model uses

null 32 Sep 21, 2022
AutoDeeplab / auto-deeplab / AutoML for semantic segmentation, implemented in Pytorch

AutoML for Image Semantic Segmentation Currently this repo contains the only working open-source implementation of Auto-Deeplab which, by the way out-

AI Necromancer 299 Dec 17, 2022
Multi-layer convolutional LSTM with Pytorch

Convolution_LSTM_pytorch Thanks for your attention. I haven't got time to maintain this repo for a long time. I recommend this repo which provides an

Zijie Zhuang 734 Jan 3, 2023
Multi-layer convolutional LSTM with Pytorch

Convolution_LSTM_pytorch Thanks for your attention. I haven't got time to maintain this repo for a long time. I recommend this repo which provides an

Zijie Zhuang 733 Dec 30, 2022
Implemented fully documented Particle Swarm Optimization algorithm (basic model with few advanced features) using Python programming language

Implemented fully documented Particle Swarm Optimization (PSO) algorithm in Python which includes a basic model along with few advanced features such as updating inertia weight, cognitive, social learning coefficients and maximum velocity of the particle.

null 9 Nov 29, 2022
A collection of 100 Deep Learning images and visualizations

A collection of Deep Learning images and visualizations. The project has been developed by the AI Summer team and currently contains almost 100 images.

AI Summer 65 Sep 12, 2022
EigenGAN Tensorflow, EigenGAN: Layer-Wise Eigen-Learning for GANs

Gender Bangs Body Side Pose (Yaw) Lighting Smile Face Shape Lipstick Color Painting Style Pose (Yaw) Pose (Pitch) Zoom & Rotate Flush & Eye Color Mout

Zhenliang He 321 Dec 1, 2022
End-to-End Object Detection with Fully Convolutional Network

This project provides an implementation for "End-to-End Object Detection with Fully Convolutional Network" on PyTorch.

null 472 Dec 22, 2022
The official PyTorch implementation of the paper: *Xili Dai, Xiaojun Yuan, Haigang Gong, Yi Ma. "Fully Convolutional Line Parsing." *.

F-Clip — Fully Convolutional Line Parsing This repository contains the official PyTorch implementation of the paper: *Xili Dai, Xiaojun Yuan, Haigang

Xili Dai 115 Dec 28, 2022
Dewarping Document Image By Displacement Flow Estimation with Fully Convolutional Network.

Dewarping Document Image By Displacement Flow Estimation with Fully Convolutional Network

null 111 Dec 27, 2022
Another pytorch implementation of FCN (Fully Convolutional Networks)

FCN-pytorch-easiest Trying to be the easiest FCN pytorch implementation and just in a get and use fashion Here I use a handbag semantic segmentation f

Y. Dong 158 Dec 21, 2022
Dewarping Document Image By Displacement Flow Estimation with Fully Convolutional Network

Dewarping Document Image By Displacement Flow Estimation with Fully Convolutional Network

null 39 Aug 2, 2021
PyTorch Implementation of Fully Convolutional Networks. (Training code to reproduce the original result is available.)

pytorch-fcn PyTorch implementation of Fully Convolutional Networks. Requirements pytorch >= 0.2.0 torchvision >= 0.1.8 fcn >= 6.1.5 Pillow scipy tqdm

Kentaro Wada 1.6k Jan 7, 2023