我的目标是使用以下代码对具有自定义形状和自定义内核的数组执行Conv2d
:
import tensorflow as tf
import numpy as np
import sys
tf.compat.v1.enable_eager_execution()
# kernel
kernel_array = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 1]])
kernel = tf.keras.initializers.Constant(kernel_array)
print('kernel shape:', kernel_array.shape)
print('kernel:',kernel_array)
# input
input_shape = (3, 3, 4, 1)
x = tf.random.normal(input_shape)
print('x shape:', x.shape)
print('x:',x.numpy())
# output
y = tf.keras.layers.Conv2D(
3, kernel_array.shape, padding="same", strides=(1, 1),
kernel_initializer=kernel,
input_shape=input_shape[1:])(x)
print('y shape:', y.shape)
print('y:',y.numpy())
上面的代码给予我一个这样的错误:
kernel shape: (3, 3)
kernel: [[1 1 1]
[1 1 1]
[1 1 1]]
x shape: (3, 3, 4, 1)
x: [[[[-0.01953345]
[-0.7110965 ]
[ 0.15634525]
[ 0.1707633 ]]
[[-0.70654714]
[ 2.7564087 ]
[ 0.60063267]
[ 2.8321717 ]]
[[ 1.4761941 ]
[ 0.34693545]
[ 0.85550934]
[ 2.2514896 ]]]
[[[ 0.82585895]
[-0.6421492 ]
[ 1.2688193 ]
[-0.9054445 ]]
[[ 1.1591591 ]
[ 0.7465941 ]
[ 1.2531661 ]
[ 2.2717664 ]]
[[-0.48740315]
[-0.42796597]
[ 0.4480274 ]
[-1.1502023 ]]]
[[[-0.7792355 ]
[-0.801604 ]
[ 1.6724508 ]
[ 0.25857568]]
[[ 0.09068593]
[-0.4783198 ]
[-0.02883703]
[-2.1400564 ]]
[[-0.5518157 ]
[-1.4513488 ]
[-0.07611077]
[ 1.4752681 ]]]]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[6], line 19
16 print('x:',x.numpy())
18 # output
---> 19 y = tf.keras.layers.Conv2D(
20 3, kernel_array.shape, padding="same", strides=(1, 1),
21 kernel_initializer=kernel,
22 input_shape=input_shape[1:])(x)
23 print('y shape:', y.shape)
24 print('y:',y.numpy())
File c:\Users\xxxx\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\utils\traceback_utils.py:70, in filter_traceback..error_handler(*args, **kwargs)
67 filtered_tb = _process_traceback_frames(e.__traceback__)
68 # To get the full stack trace, call:
69 # `tf.debugging.disable_traceback_filtering()`
---> 70 raise e.with_traceback(filtered_tb) from None
71 finally:
72 del filtered_tb
File c:\Users\xxxx\AppData\Local\Programs\Python\Python310\lib\site-packages\keras\initializers\initializers.py:265, in Constant.__call__(self, shape, dtype, **kwargs)
261 if layout:
262 return utils.call_with_layout(
263 tf.constant, layout, self.value, shape=shape, dtype=dtype
264 )
--> 265 return tf.constant(self.value, dtype=_get_dtype(dtype), shape=shape)
TypeError: Eager execution of tf.constant with unsupported shape. Tensor [[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]] (converted from [[1 1 1]
[1 1 1]
[1 1 1]]) has 9 elements, but got `shape` (3, 3, 1, 3) with 27 elements).
我不知道错在哪里。我已经尝试改变输入形状,但仍然没有工作了。我错过了什么?
1条答案
按热度按时间sf6xfgos1#
从代码的这一部分:
我们看到,您正在尝试使用形状为
(3, 3)
的内核进行卷积,并使用3个过滤器。这意味着,在您的输出中,您最终将获得3个通道。然而,我们从x.shape
看到输入有1个通道。因此,我们的内核必须处理3x3
窗口中图像的卷积,从1个通道到3个通道。把这些放在一起,这就是为什么我们有(3, 3, 1, 3)
的形状。换句话说,这就是Tensorflow中2D卷积的内核应该是什么样子:
(kernel_x, kernel_y, input_channels, output_channels)
。不妨试着这样想:如果你的内核没有最后3个维度来处理输出通道,那么当你卷积的时候,它是如何从1个通道变成3个通道的呢?唯一的逻辑可能性可能是使用相同的内核3次产生相同的3个通道。但这说不通
所以你可以做一些事情:
1.拥有一个具有正确形状的内核初始化器(考虑内核形状、输入通道和输出通道)
1.更改输出通道数
1.初始化时忽略形状并更改卷积的执行方式:
根据您的最终目标和您希望的运营灵活性,这些解决方案中的每一个都将提供可行的结果。