Tensorflow tf.Keras自定义图层输出形状为“无”

Tensorflow tf.Keras自定义图层输出形状为“无”,tensorflow,keras,Tensorflow,Keras,我正在构建一个自定义层,之后添加一个密集层时遇到了输出形状问题。该层的输出形状似乎没有定义,即使我明确地这样做了。以下是再现问题的最基本代码: import tensorflow as tf from tensorflow import keras class fakeLayer(keras.layers.Layer): def __init__(self, **kwargs): super().__init__(**kwargs) def compute_

我正在构建一个自定义层,之后添加一个密集层时遇到了输出形状问题。该层的输出形状似乎没有定义,即使我明确地这样做了。以下是再现问题的最基本代码:

import tensorflow as tf
from tensorflow import keras

class fakeLayer(keras.layers.Layer):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def compute_output_shape(self, input_shape):
        return ((input_shape[0], input_shape[1]* input_shape[2], input_shape[3]))

    def build( self, input_shape):
        super().build(input_shape)

    def call(self, inputs):
        return(tf.reshape(inputs , self.compute_output_shape(tf.shape(inputs))))


inp = keras.layers.Input((32,32,3))
x = keras.layers.Conv2D(16, (3,3))(inp)
x = fakeLayer()(x)
# x = keras.layers.Flatten()(x)
# x = keras.layers.Dense(1)(x)
model = keras.models.Model(inputs= inp, outputs = x)

print(model.summary())
输出以下内容:

WARNING:tensorflow:Entity <bound method fakeLayer.call of <__main__.fakeLayer object at 0x0000021A7370E470>> could not be transformed and will be executed as-is. Please report this to the AutoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: 
WARNING: Entity <bound method fakeLayer.call of <__main__.fakeLayer object at 0x0000021A7370E470>> could not be transformed and will be executed as-is. Please report this to the AutoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: 
Model: "model_9"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_37 (InputLayer)        [(None, 32, 32, 3)]       0         
_________________________________________________________________
conv2d_10 (Conv2D)           (None, 30, 30, 16)        448       
_________________________________________________________________
fake_layer_28 (fakeLayer)    (None, None, None)        0         
=================================================================
Total params: 448
Trainable params: 448
Non-trainable params: 0
_________________________________________________________________
None
警告:tensorflow:实体无法转换,将按原样执行。请向签名组报告。在归档bug时,将详细度设置为10(在Linux上,`export AUTOGRAPH\u verbosity=10`),并附加完整的输出。原因:
警告:实体无法转换,将按原样执行。请向签名组报告。在归档bug时,将详细度设置为10(在Linux上,`export AUTOGRAPH\u verbosity=10`),并附加完整的输出。原因:
型号:“型号9”
_________________________________________________________________
层(类型)输出形状参数
=================================================================
输入_37(输入层)[(无、32、32、3)]0
_________________________________________________________________
conv2d_10(conv2d)(无、30、30、16)448
_________________________________________________________________
假层28(假层)(无,无,无)0
=================================================================
总参数:448
可培训参数:448
不可训练参数:0
_________________________________________________________________
没有一个
我们可以看到model.summary()无法获得层的输出形状

因此,我们在取消对平坦和密集层的注释时会出现此错误:

WARNING:tensorflow:Entity <bound method fakeLayer.call of <__main__.fakeLayer object at 0x0000021A737535C0>> could not be transformed and will be executed as-is. Please report this to the AutoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: 
WARNING: Entity <bound method fakeLayer.call of <__main__.fakeLayer object at 0x0000021A737535C0>> could not be transformed and will be executed as-is. Please report this to the AutoGraph team. When filing the bug, set the verbosity to 10 (on Linux, `export AUTOGRAPH_VERBOSITY=10`) and attach the full output. Cause: 
Traceback (most recent call last):

  File "C:\Users\integration\Documents\Scripts\minimalBug.py", line 31, in <module>
    x = keras.layers.Dense(1)(x)

  File "C:\Users\integration\.conda\envs\py36\lib\site-packages\tensorflow_core\python\keras\engine\base_layer.py", line 817, in __call__
    self._maybe_build(inputs)

  File "C:\Users\integration\.conda\envs\py36\lib\site-packages\tensorflow_core\python\keras\engine\base_layer.py", line 2141, in _maybe_build
    self.build(input_shapes)

  File "C:\Users\integration\.conda\envs\py36\lib\site-packages\tensorflow_core\python\keras\layers\core.py", line 1015, in build
    raise ValueError('The last dimension of the inputs to `Dense` '

ValueError: The last dimension of the inputs to `Dense` should be defined. Found `None`.
警告:tensorflow:实体无法转换,将按原样执行。请向签名组报告。在归档bug时,将详细度设置为10(在Linux上,`export AUTOGRAPH\u verbosity=10`),并附加完整的输出。原因:
警告:实体无法转换,将按原样执行。请向签名组报告。在归档bug时,将详细度设置为10(在Linux上,`export AUTOGRAPH\u verbosity=10`),并附加完整的输出。原因:
回溯(最近一次呼叫最后一次):
文件“C:\Users\integration\Documents\Scripts\minimalBug.py”,第31行,在
x=keras.层密(1)(x)
文件“C:\Users\integration\.conda\envs\py36\lib\site packages\tensorflow\u core\python\keras\engine\base\u layer.py”,第817行,在调用中__
自我构建(输入)
文件“C:\Users\integration\.conda\envs\py36\lib\site packages\tensorflow\u core\python\keras\engine\base\u layer.py”,第2141行,在构建中
自我构建(输入形状)
文件“C:\Users\integration\.conda\envs\py36\lib\site packages\tensorflow\u core\python\keras\layers\core.py”,第1015行,内部版本
raise VALUERROR('输入的最后一个维度为'densite`'
ValueError:应定义'Dense'输入的最后一个维度。找到'None'。

我不知道这是否有区别,但这里有双括号,不知道为什么:

def compute_output_shape(self, input_shape):
    #wrong: return ((input_shape[0], input_shape[1]* input_shape[2], input_shape[3]))
    return (input_shape[0], input_shape[1]* input_shape[2], input_shape[3])
现在,真正的问题在于
调用
,在这里你混合了很多不同的东西

  • tf.shape
    返回一个张量,而不是元组
  • compute\u output\u shape
    返回一个元组
  • 如果给
    计算输出形状
    一个张量,它将返回一个张量元组(千万不要这样做!)
  • tf.reformate
    接受“元组”或“张量”,但不接受张量元组
  • Keras形状是包含
    None
    值的元组,整形接受具有
    -1
    值的元组,而不是
    None
解决方案:

def call(self, inputs):
    keras_shape = keras.backend.int_shape(inputs) #tuple containing None and numbers
    tf_shape_tuple = tuple(-1 if s is None else s for s in keras_shape) #None -> -1

    return tf.reshape(inputs , tf_shape_tuple)
我将使用
tf.shape(x)
来处理
None
shape()的问题:

对于计算输出形状,我首先将输入形状重新定义为:

from tensorflow.python.framework import tensor_shape

def compute_output_shape(self, input_shape):
    input_shape = tensor_shape.TensorShape(input_shape).as_list()
    return (input_shape[0], input_shape[1]* input_shape[2], input_shape[3])
from tensorflow.python.framework import tensor_shape

def compute_output_shape(self, input_shape):
    input_shape = tensor_shape.TensorShape(input_shape).as_list()
    return (input_shape[0], input_shape[1]* input_shape[2], input_shape[3])