我的开发环境是
我的目标是实现一个可以将每个cnn过滤器转换为hu矩不变性的层(每个过滤器-> 7维值)
因此,我想使用Opencv的Humoment方法
这是我定义的图层:
class MomentLayer(tf.keras.layers.Layer):
def __init__(self):
super(MomentLayer, self).__init__()
def build(self, input_shape):
self.oshape = input_shape
super(MomentLayer, self).build(input_shape)
def call(self, inputs, **kwargs):
xout = tf.py_function(image_tensor_func, (inputs,), 'float32', name='Cvopt')
xout.set_shape(tf.TensorShape((None, self.oshape[-1] * 7)))
return xout
def compute_output_shape(self, input_shape):
return tf.TensorShape((None, input_shape[-1] * 7))
我的py_function是
def image_tensor_func(img4d):
img4dx = tf.transpose(img4d, [0, 3, 1, 2])
all_data = np.array([])
for img3dx in img4dx:
tmp = np.array([])
for efilter in img3dx:
hu = cv2.HuMoments(cv2.moments(efilter.numpy())).flatten()
if tmp.shape[0] == 0:
tmp = hu
else:
tmp = np.concatenate((tmp, hu), axis=None)
if all_data.shape[0] == 0:
all_data = tmp
else:
all_data = np.vstack((all_data, tmp))
x = tf.convert_to_tensor(all_data, dtype=tf.float32)
return x
最后,我定义了网络
input = tf.keras.layers.Input(shape=(10, 10, 1))
conv1 = tf.keras.layers.Conv2D(filters=3, kernel_size=5, activation=tf.nn.relu)(input)
test_layer = MomentLayer()(conv1)
dense1 = tf.keras.layers.Dense(units=12, activation=tf.nn.relu)(test_layer)
output = tf.keras.layers.Dense(units=10, activation=tf.nn.sigmoid)(dense1)
model = tf.keras.models.Model(inputs=input, outputs=output)
model.compile(optimizer=tf.train.RMSPropOptimizer(0.01),
loss=tf.keras.losses.categorical_crossentropy,
metrics=[tf.keras.metrics.categorical_accuracy])
print(model.summary())
和model.summary()正常工作!
但是当我尝试提供数据时
我遇到错误
tensorflow.python.framework.errors_impl.InvalidArgumentError:转置期望大小为0的向量。但是input(1)是大小为4的向量 [[{{节点培训/ TFOptimizer / gradients / Relu_grad / ReluGrad-0-TransposeNHWCToNCHW-LayoutOptimizer}}]] [Op:StatefulPartitionedCall]
我很确定数据的形状正确。
我想知道tensorflow不能写这样的代码吗?
答案 0 :(得分:0)
您输入的数据由要素和标签组成。因此,您需要确保标签的形状也正确。