Source code for medsegpy.modeling.layers.upsampling

# -*- coding: utf-8 -*-

""" Deeplabv3+ model for Keras.
This model is based on TF repo:
https://github.com/tensorflow/models/tree/master/research/deeplab
On Pascal VOC, original model gets to 84.56% mIOU

Now this model is only available for the TensorFlow backend,
due to its reliance on `SeparableConvolution` layers, but Theano will add
this layer soon.

MobileNetv2 backbone is based on this repo:
https://github.com/JonathanCMitchell/mobilenet_v2_keras

# Reference
- [Encoder-Decoder with Atrous Separable Convolution
    for Semantic Image Segmentation](https://arxiv.org/pdf/1802.02611.pdf)
- [Xception: Deep Learning with Depthwise Separable Convolutions]
    (https://arxiv.org/abs/1610.02357)
- [Inverted Residuals and Linear Bottlenecks: Mobile Networks for
    Classification, Detection and Segmentation](https://arxiv.org/abs/1801.04381)
"""
from keras import backend as K
from keras.engine import InputSpec, Layer
from keras.utils import conv_utils


[docs]class BilinearUpsampling(Layer): """Just a simple bilinear upsampling layer. Works only with TF. Args: upsampling: tuple of 2 numbers > 0. The upsampling ratio for h and w output_size: used instead of upsampling arg if passed! """ def __init__(self, upsampling=(2, 2), output_size=None, data_format=None, **kwargs): super(BilinearUpsampling, self).__init__(**kwargs) self.data_format = conv_utils.normalize_data_format(data_format) self.input_spec = InputSpec(ndim=4) if output_size: self.output_size = conv_utils.normalize_tuple(output_size, 2, "output_size") self.upsampling = None else: self.output_size = None self.upsampling = conv_utils.normalize_tuple(upsampling, 2, "upsampling") def compute_output_shape(self, input_shape): if self.upsampling: height = self.upsampling[0] * input_shape[1] if input_shape[1] is not None else None width = self.upsampling[1] * input_shape[2] if input_shape[2] is not None else None else: height = self.output_size[0] width = self.output_size[1] return (input_shape[0], height, width, input_shape[3]) def call(self, inputs): if self.upsampling: return K.tf.image.resize_bilinear( inputs, (inputs.shape[1] * self.upsampling[0], inputs.shape[2] * self.upsampling[1]), align_corners=True, ) else: return K.tf.image.resize_bilinear( inputs, (self.output_size[0], self.output_size[1]), align_corners=True ) def get_config(self): config = { "upsampling": self.upsampling, "output_size": self.output_size, "data_format": self.data_format, } base_config = super(BilinearUpsampling, self).get_config()
return dict(list(base_config.items()) + list(config.items()))