可变大小的输入不适用于膨胀的卷积层

时间:2019-06-24 20:07:44

标签: tensorflow conv-neural-network

我有一个非常简单的模型,该模型在文本输入(嵌入)上运行一些卷积层,这些输入具有由批处理填充的可变大小。我想添加一些膨胀的层,但是遇到了问题。

运行以下代码时,我可以在第一次运行中输入尺寸,但是将相同的conv图层应用于另一个输入却会出错。

bs = 5
text_len_1 = 772
text_len_2 = 741
embed_size = 300
in_channels = 1

test_in_1 = tf.random.normal((bs, text_len_1, embed_size, in_channels))
test_in_2 = tf.random.normal((bs, text_len_2, embed_size, in_channels))


dilated_convs = [tf.keras.layers.Conv2D(filters=10, kernel_size=(2, embed_size),
                                                    dilation_rate=(dilation, 1),
                                                    padding='valid')
                             for dilation in range(2, 23)]

for conv in dilated_convs:
    res = conv(test_in_1)

for conv in dilated_convs:
    # Fails here, regardless of test_in_1 or 2 is called first
    res = conv(test_in_2) 

起初我以为我只是需要适当地填充输入,但是我似乎找不到如何应做的任何模式,因此为了正确地填充输入,可能只是简单的计算而已,但是好像还有其他事情在发生,因为只要第一个输入就无法使用任何输入进行调用。

编辑:添加了错误和堆栈跟踪

2019-06-25 13:50:33.329503: W tensorflow/core/framework/op_kernel.cc:1546] OP_REQUIRES failed at spacetobatch_op.cc:219 : Invalid argument: padded_shape[0]=741 is not divisible by block_shape[0]=2
Traceback (most recent call last):
  File "/home/name/anaconda3/envs/3.6/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 3296, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-2-59b677f0b758>", line 1, in <module>
    runfile('/home/name/.PyCharm2019.1/config/scratches/dilated_conv_test.py', wdir='/home/name/.PyCharm2019.1/config/scratches')
  File "/snap/pycharm-professional/136/helpers/pydev/_pydev_bundle/pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "/snap/pycharm-professional/136/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/home/name/.PyCharm2019.1/config/scratches/dilated_conv_test.py", line 22, in <module>
    res = conv(test_in_2)
  File "/home/name/anaconda3/envs/3.6/lib/python3.6/site-packages/tensorflow/python/keras/engine/base_layer.py", line 712, in __call__
    outputs = self.call(inputs, *args, **kwargs)
  File "/home/name/anaconda3/envs/3.6/lib/python3.6/site-packages/tensorflow/python/keras/layers/convolutional.py", line 196, in call
    outputs = self._convolution_op(inputs, self.kernel)
  File "/home/name/anaconda3/envs/3.6/lib/python3.6/site-packages/tensorflow/python/ops/nn_ops.py", line 1078, in __call__
    return self.conv_op(inp, filter)
  File "/home/name/anaconda3/envs/3.6/lib/python3.6/site-packages/tensorflow/python/ops/nn_ops.py", line 634, in __call__
    return self.call(inp, filter)
  File "/home/name/anaconda3/envs/3.6/lib/python3.6/site-packages/tensorflow/python/ops/nn_ops.py", line 617, in _with_space_to_batch_call
    input=inp, block_shape=dilation_rate, paddings=paddings)
  File "/home/name/anaconda3/envs/3.6/lib/python3.6/site-packages/tensorflow/python/ops/gen_array_ops.py", line 9246, in space_to_batch_nd
    _six.raise_from(_core._status_to_exception(e.code, message), None)
  File "<string>", line 3, in raise_from
tensorflow.python.framework.errors_impl.InvalidArgumentError: padded_shape[0]=741 is not divisible by block_shape[0]=2 [Op:SpaceToBatchND]

1 个答案:

答案 0 :(得分:1)

我运行了您的代码,该错误在tensorflow 1.x版中仍然存在,但是在升级到tensorflow 2.x版时消失了。您能否升级到2.x版本并尝试。

下面是运行详细信息。

运行1- Tensorflow版本1.x

%tensorflow_version 1.x
import tensorflow as tf

bs = 5
text_len_1 = 772
text_len_2 = 741
embed_size = 300
in_channels = 1

test_in_1 = tf.random.normal((bs, text_len_1, embed_size, in_channels))
test_in_2 = tf.random.normal((bs, text_len_2, embed_size, in_channels))

dilated_convs = [tf.keras.layers.Conv2D(filters=10, kernel_size=(2, embed_size),
                                                    dilation_rate=(dilation, 1),
                                                    padding='same')
                             for dilation in range(2, 23)]

print(dilated_convs)
for conv in dilated_convs:
    res = conv(test_in_1)

for conv in dilated_convs:
    # Fails here, regardless of test_in_1 or 2 is called first
    res = conv(test_in_2) 

print("I ran Succesfully")

输出-

TensorFlow 1.x selected.
[<tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe3db797160>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa30e48>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa542b0>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa546d8>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa54b00>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa54f28>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa58390>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa587b8>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa58be0>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa5f048>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa5f470>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa5f898>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa5fcc0>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa62128>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa62550>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa62978>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39fa62da0>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39f9e8208>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39f9e8630>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39f9e8a58>, <tensorflow.python.keras.layers.convolutional.Conv2D object at 0x7fe39f9e8e80>]
WARNING:tensorflow:From /tensorflow-1.15.2/python3.6/tensorflow_core/python/ops/resource_variable_ops.py:1630: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.
---------------------------------------------------------------------------
InvalidArgumentError                      Traceback (most recent call last)
/tensorflow-1.15.2/python3.6/tensorflow_core/python/framework/ops.py in _create_c_op(graph, node_def, inputs, control_inputs)
   1606   try:
-> 1607     c_op = c_api.TF_FinishOperation(op_desc)
   1608   except errors.InvalidArgumentError as e:

InvalidArgumentError: Dimension size must be evenly divisible by 2 but is 743 for 'conv2d_21/SpaceToBatchND' (op: 'SpaceToBatchND') with input shapes: [5,741,300,1], [2], [2,2] and with computed input tensors: input[1] = <2 1>, input[2] = <[1 1][149 150]>.

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
12 frames
/tensorflow-1.15.2/python3.6/tensorflow_core/python/framework/ops.py in _create_c_op(graph, node_def, inputs, control_inputs)
   1608   except errors.InvalidArgumentError as e:
   1609     # Convert to ValueError for backwards compatibility.
-> 1610     raise ValueError(str(e))
   1611 
   1612   return c_op

ValueError: Dimension size must be evenly divisible by 2 but is 743 for 'conv2d_21/SpaceToBatchND' (op: 'SpaceToBatchND') with input shapes: [5,741,300,1], [2], [2,2] and with computed input tensors: input[1] = <2 1>, input[2] = <[1 1][149 150]>.

运行2- Tensorflow版本2.x

%tensorflow_version 2.x
import tensorflow as tf

bs = 5
text_len_1 = 772
text_len_2 = 741
embed_size = 300
in_channels = 1

test_in_1 = tf.random.normal((bs, text_len_1, embed_size, in_channels))
test_in_2 = tf.random.normal((bs, text_len_2, embed_size, in_channels))

dilated_convs = [tf.keras.layers.Conv2D(filters=10, kernel_size=(2, embed_size),
                                                    dilation_rate=(dilation, 1),
                                                    padding='same')
                             for dilation in range(2, 23)]

for conv in dilated_convs:
    res = conv(test_in_1)

for conv in dilated_convs:
    # Fails here, regardless of test_in_1 or 2 is called first
    res = conv(test_in_2) 

print("I ran Succesfully")

输出-

I ran Succesfully