Python 如何按照第三个参数确定的顺序构建合并两个图像的层

Python 如何按照第三个参数确定的顺序构建合并两个图像的层,python,keras,neural-network,keras-layer,Python,Keras,Neural Network,Keras Layer,我想要一个以三个张量作为输入的层:两个(n,m,k)张量和一个(1)张量,即一个数字。输出应该是一个(n,m,2k)张量,通过简单地让前k个通道是一个图像,其余的是另一个图像来实现。现在,关键是我们合并它们的顺序——我们是把图像一放在图像二的上面,还是把图像二放在上面——应该由第三个输入是否大于0来决定 根据我的想法,这是一个完全静态的层,没有任何可训练的参数,因此我尝试使用Lambda层进行排序选择,如下所示: def image_scrambler(inp): #inp = [im1, im

我想要一个以三个张量作为输入的层:两个(n,m,k)张量和一个(1)张量,即一个数字。输出应该是一个(n,m,2k)张量,通过简单地让前k个通道是一个图像,其余的是另一个图像来实现。现在,关键是我们合并它们的顺序——我们是把图像一放在图像二的上面,还是把图像二放在上面——应该由第三个输入是否大于0来决定

根据我的想法,这是一个完全静态的层,没有任何可训练的参数,因此我尝试使用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])
---------------------------------------------------------------------------
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
这不起作用,因为它抗议层是动态的,需要使用dynamic=True构建。当我尝试这样做时,我得到一个递归错误,如下所示:

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])
---------------------------------------------------------------------------
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
---------------------------------------------------------------------------
递归错误回溯(最近一次调用上次)
在里面
7返回[im2,im1]
8辅助输入=输入(形状=(1))
---->9对图像=λ(图像加扰器,动态=真)([图像输入,解码器,辅助输入])
c:\users\vilhelm\appdata\local\programs\python\36\lib\site packages\tensorflow\u core\python\keras\engine\base\u layer.py in\uuuuuuu调用(self,input,*args,**kwargs)
791πtodoo(fCultLe):考虑Pyth-Func作为一种选择,
792#将使我们能够在需要时运行底层图形。
-->793输出=自符号调用(输入)
794
795如果输出为无:
c:\users\vilhelm\appdata\local\programs\python\36\lib\site packages\tensorflow\u core\python\keras\engine\base\u layer.py in\u symbolic\u call(self,inputs)
2126 def_符号_调用(自身,输入):
2127 input_shapes=nest.map_结构(lambda x:x.shape,inputs)
->2128输出形状=自身。计算输出形状(输入形状)
2129
2130 def_make_占位符_like(形状):
c:\users\vilhelm\appdata\local\programs\python\36\lib\site packages\tensorflow\u core\python\keras\utils\tf\u utils.py在包装器中(实例,输入\u形状)
304如果输入_形状不是无:
305输入形状=转换形状(输入形状,到元组=真)
-->306输出形状=fn(实例,输入形状)
307#将'fn'中的形状返回为张量形状。
308如果输出_形不是无:
c:\users\vilhelm\appdata\local\programs\python\36\lib\site packages\tensorflow\u core\python\keras\layers\core.py in compute\u output\u shape(self,input\u shape)
808与context.eager_mode()一起使用:
809尝试:
-->810返回超级(Lambda,self)。计算输出形状(输入形状)
811除未实施错误外:
812升起未执行错误(
c:\users\vilhelm\appdata\local\programs\python\36\lib\site packages\tensorflow\u core\python\keras\engine\base\u layer.py in compute\u output\u shape(self,input\u shape)
552尝试:
553如果自认为需要培训,则:
-->554输出=自身(输入,培训=错误)
555其他:
556输出=自身(输入)
…从下面的帧开始,重复最后5帧。。。
c:\users\vilhelm\appdata\local\programs\python\36\lib\site packages\tensorflow\u core\python\keras\engine\base\u layer.py in\uuuuuuu调用(self,input,*args,**kwargs)
791πtodoo(fCultLe):考虑Pyth-Func作为一种选择,
792#将使我们能够在需要时运行底层图形。
-->793输出=自符号调用(输入)
794
795如果输出为无:
RecursionError:调用Python对象时超出了最大递归深度
所以这并没有告诉我为什么它不工作,它只是崩溃了

如果有任何方法可以让不太复杂的方法发挥作用,我宁愿不必在层中构建层类。

始终使用“张量函数”而不是“Python函数”:

我认为断言不是一个好主意,您应该在检查数据时这样做,而不是在模型中


虽然你说它不可训练,但你可能希望它能以某种方式训练?是什么决定了
aux_input
的值是什么?如果你希望它能在其他地方学习,我怀疑它是否会起作用。也许它应该是某个地方一个sigmoid给出的连续值。然后它“可能”有机会工作,尽管if部分会中断(但不会中断)反向传播。

aux_输入是输入数据的一部分,因此不需要学习。事实上,这一层上下都不会有可训练的参数,所以我认为训练应该不会有问题?似乎没问题。但是如果没有训练参数,无论是在上面还是下面……模型是否有任何可训练的参数?不,没有e有时是上面的可训练参数,有时是下面的可训练参数,但决不能同时训练两者。因此,首先我训练上面的东西,保持下面的层固定,然后固定上面的东西,训练下面的东西,来回切换直到完成。显然,这两部分的损失函数不同。