Skip to content
Snippets Groups Projects
Commit 1d72bb15 authored by Felix Kleinert's avatar Felix Kleinert
Browse files

#56 inital commit for advanced paddings

parent 029ffbb0
Branches
Tags
2 merge requests!59Develop,!46Felix #56 advanced paddings
__author__ = 'Felix Kleinert'
__date__ = '2020-03-02'
import tensorflow as tf
import numpy as np
import keras.backend as K
from keras.layers.convolutional import _ZeroPadding
from keras.legacy import interfaces
from keras.utils import conv_utils
from keras.utils.generic_utils import transpose_shape
from keras.backend.common import normalize_data_format
# class pad_utils:
# @staticmethod
# def get_padding_for_same(kernel_size, strides=1):
# '''
# This methods calculates the padding size to keep input and output dimensions equal for a given kernel size
# (STRIDES HAVE TO BE EQUAL TO ONE!)
# :param kernel_size:
# :return:
# '''
# if strides != 1:
# raise NotImplementedError("Strides other than 1 not implemented!")
# ks = np.array(kernel_size, dtype=np.int64)
# if (d & 0x1 for d in ks):
# pad = ((ks - 1) / 2).astype(np.int64)
# # pad = ((pad[0], pad[0]), (pad[1], pad[1]))
# return pad
# else:
# raise NotImplementedError("even kernel size not implemented")
#
class ReflectionPadding2D(_ZeroPadding):
"""Zero-padding layer for 2D input (e.g. picture).
This layer can add rows and columns of zeros
at the top, bottom, left and right side of an image tensor.
# Arguments
padding: int, or tuple of 2 ints, or tuple of 2 tuples of 2 ints.
- If int: the same symmetric padding
is applied to height and width.
- If tuple of 2 ints:
interpreted as two different
symmetric padding values for height and width:
`(symmetric_height_pad, symmetric_width_pad)`.
- If tuple of 2 tuples of 2 ints:
interpreted as
`((top_pad, bottom_pad), (left_pad, right_pad))`
data_format: A string,
one of `"channels_last"` or `"channels_first"`.
The ordering of the dimensions in the inputs.
`"channels_last"` corresponds to inputs with shape
`(batch, height, width, channels)` while `"channels_first"`
corresponds to inputs with shape
`(batch, channels, height, width)`.
It defaults to the `image_data_format` value found in your
Keras config file at `~/.keras/keras.json`.
If you never set it, then it will be "channels_last".
# Input shape
4D tensor with shape:
- If `data_format` is `"channels_last"`:
`(batch, rows, cols, channels)`
- If `data_format` is `"channels_first"`:
`(batch, channels, rows, cols)`
# Output shape
4D tensor with shape:
- If `data_format` is `"channels_last"`:
`(batch, padded_rows, padded_cols, channels)`
- If `data_format` is `"channels_first"`:
`(batch, channels, padded_rows, padded_cols)`
"""
@interfaces.legacy_zeropadding2d_support
def __init__(self,
padding=(1, 1),
data_format=None,
**kwargs):
if isinstance(padding, int):
normalized_padding = ((padding, padding), (padding, padding))
elif hasattr(padding, '__len__'):
if len(padding) != 2:
raise ValueError('`padding` should have two elements. '
'Found: ' + str(padding))
height_padding = conv_utils.normalize_tuple(padding[0], 2,
'1st entry of padding')
width_padding = conv_utils.normalize_tuple(padding[1], 2,
'2nd entry of padding')
normalized_padding = (height_padding, width_padding)
else:
raise ValueError('`padding` should be either an int, '
'a tuple of 2 ints '
'(symmetric_height_pad, symmetric_width_pad), '
'or a tuple of 2 tuples of 2 ints '
'((top_pad, bottom_pad), (left_pad, right_pad)). '
'Found: ' + str(padding))
super(ReflectionPadding2D, self).__init__(normalized_padding,
data_format,
**kwargs)
@staticmethod
def spatial_2d_padding(x, padding=((1, 1), (1, 1)), data_format=None):
"""Pads the 2nd and 3rd dimensions of a 4D tensor.
# Arguments
x: Tensor or variable.
padding: Tuple of 2 tuples, padding pattern.
data_format: string, `"channels_last"` or `"channels_first"`.
# Returns
A padded 4D tensor.
# Raises
ValueError: if `data_format` is neither `"channels_last"` or `"channels_first"`.
"""
assert len(padding) == 2
assert len(padding[0]) == 2
assert len(padding[1]) == 2
data_format = normalize_data_format(data_format)
pattern = [[0, 0],
list(padding[0]),
list(padding[1]),
[0, 0]]
pattern = transpose_shape(pattern, data_format, spatial_axes=(1, 2))
return pattern
def call(self, inputs, mask=None):
pattern = self.spatial_2d_padding(inputs, padding=self.padding, data_format=self.data_format)
return tf.pad(inputs, pattern, 'REFLECT')
if __name__ == '__main__':
from keras.models import Model
from keras.layers import Conv2D, Flatten, Dense, Input
x = np.array(range(2000)).reshape(-1,10,10,1)
y = x.mean(axis=(1,2))
x_input = Input(shape=x.shape[1:])
x_out = ReflectionPadding2D(padding=(1,1))(x_input)
print(x_out.get_shape())
x_out = Conv2D(10, kernel_size=(3,3), activation='relu')(x_out)
x_out = Flatten()(x_out)
x_out = Dense(1, activation='linear')(x_out)
model = Model(inputs=x_input, outputs=x_out)
model.compile('adam', loss='mse')
model.summary()
hist = model.fit(x, y, epochs=10)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment