使用自定义图层和py_function与opencv方法

时间:2019-03-14 12:45:19

标签: python tensorflow keras

我的开发环境是

  • Windows 10
  • Python 3.6.8
  • Tensorflow 1.13.1

我的目标是实现一个可以将每个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不能写这样的代码吗?

1 个答案:

答案 0 :(得分:0)

您输入的数据由要素和标签组成。因此,您需要确保标签的形状也正确。