3つのテンソルを入力として受け取るレイヤーが必要です。2つの(n、m、k)テンソルと1つのテンソル、つまり1つの単一の数値です。出力は(n、m、2k)テンソルである必要があります。これは、最初のkチャネルを一方の画像とし、残りをもう一方の画像にすることで実現されます。ここで、問題は、それらをマージする順序(画像1を画像2の上に配置するか、またはその逆)を、3番目の入力が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])
レイヤーが動的であり、dynamic = 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
だから、それは実際にはそれが機能しなかった理由について何も教えてくれません、それはただクラッシュしました。
それほど複雑でないメソッドを機能させる方法があれば、Layerから継承するレイヤークラスを構築することをいじくり回す必要はありません。
「Python関数」ではなく、常に「テンソル関数」を使用してください。
import keras.backend as K
def image_scrambler(inp): #inp = [im1, im2, aux_input]
im1, im2, aux_input = inp[0],inp[1],inp[2]
is_greater = K.greater(aux_input, 0.5)
return K.switch(is_greater, #this is a keras "if"
K.concatenate([img2, img1]), #result if true
K.concatenate([img1, img2])) #result if false
paired_images = Lambda(image_scrambler)([image_input, decoder, aux_input])
アサーションは良い考えではないと思います。モデルではなく、データをチェックするときにこれを行う必要があります。
訓練できないと言っても、どういうわけか訓練できると期待しているのではないでしょうか。の価値を決定するものは何aux_input
ですか?あなたがそれが他の場所で学ばれることを期待するならば、私はそれがうまくいくかどうか疑わしいです。多分それはどこかのS状結腸によって与えられた連続値であるべきです。次に、それが機能する可能性がありますが、if部分は逆伝播を中断します(ただし、中断しません)。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加