Как объединить 1d массив из функции OpenCV с сглаженным вектором в CNN - PullRequest
2 голосов
/ 11 февраля 2020

Я пытаюсь повысить точность CNN (сверточной нейронной сети), вычисляя некоторые значения c динам, такие как моменты Ху изображений, ИСПОЛЬЗУЯ OpenCV функцию во время фаза обучения, а затем подайте их на полностью связанный слой с вектором сглаживания, как показано на изображении моей модели:

Моя модель

Я хочу вычислить моменты Ху для каждого изображения, ИСПОЛЬЗУЯ OPENCV в наборе данных, а затем после операции сглаживания я хочу объединить значения моментов Ху с вектором жира и передать его в полностью связанный слой.

Это модель, которую я использую (Tensorflow Keras):

@tf.function
def calc_hu(imagex):
  imagex=tf.image.convert_image_dtype(imagex, dtype=tf.uint8)    
  moments = cv2.UMat(cv2.moments(imagex))    
  huMoments = cv2.UMat(cv2.HuMoments(moments))
  for i in range(0, 7):
    huMoments[i] = abs(-1 * math.copysign(1.0, huMoments[i]) * math.log10(abs(huMoments[i])))
  huMoments=huMoments.astype(np.uint8) 
  return huMoments

class HuLayer(tf.keras.layers.Layer):
    def call(self, inputs):          
      return calc_hu(inputs)



layer1 = Conv2D(16, (3, 3),padding="same", activation='relu')(inpx) 
layer2 = Conv2D(32, kernel_size=(3, 3),padding="same", activation='relu')(layer1) 
layer3 = MaxPooling2D(pool_size=(2, 2))(layer2) 
layer4 = Conv2D(64, kernel_size=(5, 5),padding="same", activation='relu')(layer3)
layer5 = Conv2D(128, kernel_size=(5, 5),padding="same", activation='relu')(layer4)
layer6 = MaxPooling2D(pool_size=(2, 2))(layer5) 
layer7 = Dropout(0.5)(layer6) 
layer8 = Flatten()(layer7) 

layer8_ =tf.keras.layers.concatenate([layer8,  HuLayer()(tf.keras.layers.Input(shape=np.asarray([1,2,3,4,5,6,7]).shape))(inpx)])
layer9 = Dense(250, activation='sigmoid')(layer8_) 
layer10 = Dense(10, activation='softmax')(layer9) 

model = Model([inpx], layer10) 



model.compile(optimizer=keras.optimizers.Adadelta(), 
              loss=keras.losses.categorical_crossentropy, 
              metrics=['accuracy']) 





model.fit(x_train, y_train, epochs=10, batch_size=500) 
score = model.evaluate(x_test, y_test, verbose=0) 

Но у меня все еще есть эта ошибка

TypeError: in converted code:

<ipython-input-1-dd21806afc67>:155 call  *
    return calc_hu(inputs)
/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/eager/def_function.py:449 __call__
    self._initialize(args, kwds, add_initializers_to=initializer_map)
<ipython-input-1-dd21806afc67>:143 calc_hu  *
    moments = cv2.UMat(cv2.moments(imagex))
/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/autograph/impl/api.py:396 converted_call
    return py_builtins.overload_of(f)(*args)

TypeError: Expected Ptr<cv::UMat> for argument '%s'

Ожидается, что HuLayer получит изображение размером 28X28 и возвращаемые моменты Ху, которые являются семью значениями, чтобы их можно было объединить со сплющенным вектором

Набор данных, который я использую, представляет собой рукописные цифры MNIST.

1 Ответ

0 голосов
/ 11 февраля 2020

imagex должен быть массивом NumPy.

imagex = imagex.numpy()
moments = cv2.UMat(cv2.moments(imagex))
...