Мне нужен слой, который принимает три тензора в качестве входных данных: два (n, m, k) тензора и один (1) тензор, т.е. одно единственное число. На выходе должен быть тензор (n, m, 2k), который достигается тем, что первые k каналов являются одним изображением, а остальные - другим. Теперь выгода заключается в том, что порядок их слияния - помещаем ли мы изображение одно поверх изображения два или наоборот - должен определяться тем, больше ли третий вход больше 0 или нет.
По моему мнению, это полностью статический c слой без каких-либо обучаемых параметров, поэтому я попытался сделать выбор упорядочения со слоем Lambda следующим образом:
def image_scrambler(inp): #inp = [im1, im2, aux_input]
im1, im2, aux_input = inp[0],inp[1],inp[2]
assert aux_input==1 or aux_input==0
if aux_input==0:
return [im1, im2]
else:
return [im2,im1]
paired_images = Lambda(image_scrambler)([image_input, decoder, aux_input])
Это не работает, потому что это протестует, что слой является Dynami c и должен быть построен с динамическим = True. Когда я пытаюсь это сделать, я получаю RecursionError следующим образом:
---------------------------------------------------------------------------
RecursionError Traceback (most recent call last)
<ipython-input-15-a40adb50e97d> in <module>
7 return [im2,im1]
8 aux_input = Input(shape=(1))
----> 9 paired_images = Lambda(image_scrambler,dynamic=True)([image_input, decoder, aux_input])
c:\users\vilhelm\appdata\local\programs\python\python36\lib\site-packages\tensorflow_core\python\keras\engine\base_layer.py in __call__(self, inputs, *args, **kwargs)
791 # TODO(fchollet): consider py_func as an alternative, which
792 # would enable us to run the underlying graph if needed.
--> 793 outputs = self._symbolic_call(inputs)
794
795 if outputs is None:
c:\users\vilhelm\appdata\local\programs\python\python36\lib\site-packages\tensorflow_core\python\keras\engine\base_layer.py in _symbolic_call(self, inputs)
2126 def _symbolic_call(self, inputs):
2127 input_shapes = nest.map_structure(lambda x: x.shape, inputs)
-> 2128 output_shapes = self.compute_output_shape(input_shapes)
2129
2130 def _make_placeholder_like(shape):
c:\users\vilhelm\appdata\local\programs\python\python36\lib\site-packages\tensorflow_core\python\keras\utils\tf_utils.py in wrapper(instance, input_shape)
304 if input_shape is not None:
305 input_shape = convert_shapes(input_shape, to_tuples=True)
--> 306 output_shape = fn(instance, input_shape)
307 # Return shapes from `fn` as TensorShapes.
308 if output_shape is not None:
c:\users\vilhelm\appdata\local\programs\python\python36\lib\site-packages\tensorflow_core\python\keras\layers\core.py in compute_output_shape(self, input_shape)
808 with context.eager_mode():
809 try:
--> 810 return super(Lambda, self).compute_output_shape(input_shape)
811 except NotImplementedError:
812 raise NotImplementedError(
c:\users\vilhelm\appdata\local\programs\python\python36\lib\site-packages\tensorflow_core\python\keras\engine\base_layer.py in compute_output_shape(self, input_shape)
552 try:
553 if self._expects_training_arg:
--> 554 outputs = self(inputs, training=False)
555 else:
556 outputs = self(inputs)
... last 5 frames repeated, from the frame below ...
c:\users\vilhelm\appdata\local\programs\python\python36\lib\site-packages\tensorflow_core\python\keras\engine\base_layer.py in __call__(self, inputs, *args, **kwargs)
791 # TODO(fchollet): consider py_func as an alternative, which
792 # would enable us to run the underlying graph if needed.
--> 793 outputs = self._symbolic_call(inputs)
794
795 if outputs is None:
RecursionError: maximum recursion depth exceeded while calling a Python object
Так что на самом деле это ничего не говорит мне о том, почему это не сработало, оно просто рухнуло.
I ' я предпочел бы не возиться с созданием класса слоя, унаследованного от Layer, если есть какой-нибудь способ заставить работать менее сложный метод.