diff --git a/src/model_modules/advanced_paddings.py b/src/model_modules/advanced_paddings.py index 1d48dfc0a87c05183fc5b8b7755f48efaf7b5428..c24085ffae1939b8bc95eae0e500ef2d07f917ad 100644 --- a/src/model_modules/advanced_paddings.py +++ b/src/model_modules/advanced_paddings.py @@ -6,6 +6,7 @@ import numpy as np import keras.backend as K from keras.layers.convolutional import _ZeroPadding +from keras.layers import ZeroPadding2D from keras.legacy import interfaces from keras.utils import conv_utils from keras.utils.generic_utils import transpose_shape @@ -109,6 +110,42 @@ class PadUtils: return normalized_padding +class Padding2D: + ''' + This class combines the implemented padding methods. You can call this method by defining a specific padding type. + The __call__ method will return the corresponding Padding layer. + ''' + def __init__(self, padding_type): + self.padding_type = padding_type + self.allowed_paddings = { + 'RefPad2D': ReflectionPadding2D, 'ReflectionPadding2D': ReflectionPadding2D, + 'SymPad2D': SymmetricPadding2D, 'SymmetricPadding2D': SymmetricPadding2D, + 'ZeroPad2D': ZeroPadding2D, 'ZeroPadding2D': ZeroPadding2D + } + + def _check_and_get_padding(self): + if isinstance(self.padding_type, str): + try: + pad2d = self.allowed_paddings[self.padding_type] + except KeyError as einfo: + raise NotImplementedError( + f"`{einfo}' is not implemented as padding. " + "Use one of those: i) `RefPad2D', ii) `SymPad2D', iii) `ZeroPad2D'") + else: + if self.padding_type in self.allowed_paddings.values(): + pad2d = self.padding_type + else: + raise TypeError(f"`{self.padding_type.__name__}' is not a valid padding layer type. " + "Use one of those: " + "i) ReflectionPadding2D, ii) SymmetricPadding2D, iii) ZeroPadding2D") + return pad2d + + def __call__(self, *args, **kwargs): + return self._check_and_get_padding()(*args, **kwargs) + + + + class ReflectionPadding2D(_ZeroPadding): """ Reflection padding layer for 2D input. This custum padding layer is built on keras' zero padding layers. Doc is copy @@ -258,6 +295,7 @@ if __name__ == '__main__': kernel_1 = (3, 3) kernel_2 = (5, 5) + kernel_3 = (3,3) x = np.array(range(2000)).reshape(-1, 10, 10, 1) y = x.mean(axis=(1, 2)) @@ -269,6 +307,10 @@ if __name__ == '__main__': pad2 = PadUtils.get_padding_for_same(kernel_size=kernel_2) x_out = SymmetricPadding2D(padding=pad2, name="SymPAD")(x_out) x_out = Conv2D(2, kernel_size=kernel_2, activation='relu')(x_out) + + pad3 = PadUtils.get_padding_for_same(kernel_size=kernel_3) + x_out = Padding2D('RefPad2D')(padding=pad3, name="Padding2D_RefPad")(x_out) + x_out = Conv2D(2, kernel_size=kernel_3, activation='relu')(x_out) x_out = Flatten()(x_out) x_out = Dense(1, activation='linear')(x_out) diff --git a/src/model_modules/inception_model.py b/src/model_modules/inception_model.py index 1cb7656335495f0261abb434e4a203cb4e63887e..6467b3245ad097af6ef17e596f85264eef383d7a 100644 --- a/src/model_modules/inception_model.py +++ b/src/model_modules/inception_model.py @@ -5,7 +5,7 @@ import logging import keras import keras.layers as layers -from src.model_modules.advanced_paddings import PadUtils, ReflectionPadding2D, SymmetricPadding2D +from src.model_modules.advanced_paddings import PadUtils, ReflectionPadding2D, SymmetricPadding2D, Padding2D class InceptionModelBase: @@ -75,7 +75,10 @@ class InceptionModelBase: name=f'Block_{self.number_of_blocks}{self.block_part_name()}_1x1')(input_x) tower = self.act(tower, activation, **act_settings) - tower = self.padding_layer(padding)(padding=padding_size, + # tower = self.padding_layer(padding)(padding=padding_size, + # name=f'Block_{self.number_of_blocks}{self.block_part_name()}_Pad' + # )(tower) + tower = Padding2D(padding)(padding=padding_size, name=f'Block_{self.number_of_blocks}{self.block_part_name()}_Pad' )(tower) @@ -108,28 +111,28 @@ class InceptionModelBase: else: return act_name.__name__ - @staticmethod - def padding_layer(padding): - allowed_paddings = { - 'RefPad2D': ReflectionPadding2D, 'ReflectionPadding2D': ReflectionPadding2D, - 'SymPad2D': SymmetricPadding2D, 'SymmetricPadding2D': SymmetricPadding2D, - 'ZeroPad2D': keras.layers.ZeroPadding2D, 'ZeroPadding2D': keras.layers.ZeroPadding2D - } - if isinstance(padding, str): - try: - pad2d = allowed_paddings[padding] - except KeyError as einfo: - raise NotImplementedError( - f"`{einfo}' is not implemented as padding. " - "Use one of those: i) `RefPad2D', ii) `SymPad2D', iii) `ZeroPad2D'") - else: - if padding in allowed_paddings.values(): - pad2d = padding - else: - raise TypeError(f"`{padding.__name__}' is not a valid padding layer type. " - "Use one of those: " - "i) ReflectionPadding2D, ii) SymmetricPadding2D, iii) ZeroPadding2D") - return pad2d + # @staticmethod + # def padding_layer(padding): + # allowed_paddings = { + # 'RefPad2D': ReflectionPadding2D, 'ReflectionPadding2D': ReflectionPadding2D, + # 'SymPad2D': SymmetricPadding2D, 'SymmetricPadding2D': SymmetricPadding2D, + # 'ZeroPad2D': keras.layers.ZeroPadding2D, 'ZeroPadding2D': keras.layers.ZeroPadding2D + # } + # if isinstance(padding, str): + # try: + # pad2d = allowed_paddings[padding] + # except KeyError as einfo: + # raise NotImplementedError( + # f"`{einfo}' is not implemented as padding. " + # "Use one of those: i) `RefPad2D', ii) `SymPad2D', iii) `ZeroPad2D'") + # else: + # if padding in allowed_paddings.values(): + # pad2d = padding + # else: + # raise TypeError(f"`{padding.__name__}' is not a valid padding layer type. " + # "Use one of those: " + # "i) ReflectionPadding2D, ii) SymmetricPadding2D, iii) ZeroPadding2D") + # return pad2d def create_pool_tower(self, input_x, pool_kernel, tower_filter, activation='relu', max_pooling=True, **kwargs): """ @@ -156,7 +159,8 @@ class InceptionModelBase: block_type = "AvgPool" pooling = layers.AveragePooling2D - tower = self.padding_layer(padding)(padding=padding_size, name=block_name+'Pad')(input_x) + # tower = self.padding_layer(padding)(padding=padding_size, name=block_name+'Pad')(input_x) + tower = Padding2D(padding)(padding=padding_size, name=block_name+'Pad')(input_x) tower = pooling(pool_kernel, strides=(1, 1), padding='valid', name=block_name+block_type)(tower) # convolution block @@ -262,7 +266,7 @@ if __name__ == '__main__': 'padding': 'SymPad2D'}, 'tower_3': {'reduction_filter': 64, 'tower_filter': 64, - 'tower_kernel': (1, 1), + 'tower_kernel': (7, 7), 'activation': ELU, 'padding': ReflectionPadding2D} } diff --git a/src/model_modules/model_class.py b/src/model_modules/model_class.py index 84f98690754a5d21a579270f4357636db692747d..7796ea4fbb529d4eaaa819f28804b034db596dfd 100644 --- a/src/model_modules/model_class.py +++ b/src/model_modules/model_class.py @@ -10,7 +10,7 @@ from typing import Any, Callable import keras from src.model_modules.inception_model import InceptionModelBase from src.model_modules.flatten import flatten_tail -import src.model_modules.advanced_paddings as adv_pad +from src.model_modules.advanced_paddings import PadUtils, Padding2D class AbstractModelClass(ABC): @@ -443,10 +443,10 @@ class MyPaperModel(AbstractModelClass): X_input = keras.layers.Input( shape=(self.window_history_size + 1, 1, self.channels)) # add 1 to window_size to include current time step t0 - pad_size = adv_pad.PadUtils.get_padding_for_same(first_kernel) + pad_size = PadUtils.get_padding_for_same(first_kernel) # X_in = adv_pad.SymmetricPadding2D(padding=pad_size)(X_input) # X_in = inception_model.padding_layer("SymPad2D")(padding=pad_size, name="SymPad")(X_input) # adv_pad.SymmetricPadding2D(padding=pad_size)(X_input) - X_in = inception_model.padding_layer("SymPad2D")(padding=pad_size, name="SymPad")(X_input) + X_in = Padding2D("SymPad2D")(padding=pad_size, name="SymPad")(X_input) X_in = keras.layers.Conv2D(filters=first_filters, kernel_size=first_kernel, kernel_regularizer=self.regularizer,