Моя среда разработки
- Windows 10
- Python 3.6.8
- Tensorflow 1.13.1
Моя цель - реализовать слой, который может преобразовывать каждый фильтр cnn в инварианты моментов (каждый фильтр -> 7 значений измерений)
Итак, я хочу использовать метод Humoment в Opencv
Вот мой слой, определенный:
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 () работают нормально!
но когда я пытаюсь передать данные
Я получил ошибку
tenorflow.python.framework.errors_impl.InvalidArgumentError: transpose ожидает вектор размера 0. Но input (1) - это вектор размера 4
[[{{обучение узла / TFOptimizer / градиенты / Relu_grad / ReluGrad-0-TransposeNHWCToNCHW-LayoutOptimizer}}]] [Op: StatefulPartitionedCall]
Я почти уверен, что форма данных правильная.
Интересно, что тензор потока не может написать такой код.