OpenCV DNN не работает с керасом DenseNet121 - PullRequest
0 голосов
/ 27 ноября 2018

после http://answers.opencv.org/question/183507/opencv-dnn-import-error-for-keras-pretrained-vgg16-model/ Я пытаюсь заставить densenet работать на DNC openCV, но получаю:

"ошибка: OpenCV (3.4.2) / io / opencv / modules /dnn / src / tenorflow / tf_graph_simplifier.cpp: 712: ошибка: (-2: неопределенная ошибка) Тип данных Tensor не поддерживается в функции 'getTensorContent' "

import numpy as np
from keras import applications
from keras import backend as K
import cv2 as cv
import tensorflow as tf

model = applications.densenet.DenseNet121(input_shape=(224, 224, 3), weights='imagenet', include_top=True)
sess = K.get_session()

print(model.input, model.outputs)
## Tensor("input_1:0", shape=(?, 224, 224, 3), dtype=float32) [<tf.Tensor 'fc1000/Softmax:0' shape=(?, 1000) dtype=float32>]

from tensorflow.python.tools import freeze_graph
from tensorflow.python.tools import optimize_for_inference_lib

MODEL_PATH = 'out'
MODEL_NAME = 'test'
input_node_name = 'input_1'
output_node_name = 'fc1000/Softmax'
!rm -rf {MODEL_PATH}/

tf.train.write_graph(sess.graph_def, MODEL_PATH, f'{MODEL_NAME}_graph.pb', as_text=False)
tf.train.write_graph(sess.graph_def, MODEL_PATH, f'{MODEL_NAME}_graph.pbtxt')
tf.train.Saver().save(sess, f'{MODEL_PATH}/{MODEL_NAME}.chkp')

freeze_graph.freeze_graph(f'{MODEL_PATH}/{MODEL_NAME}_graph.pbtxt',
                          None, False,
                          f'{MODEL_PATH}/{MODEL_NAME}.chkp',
                          output_node_name,
                          "save/restore_all",
                          "save/Const:0",
                          f'{MODEL_PATH}/frozen_{MODEL_NAME}.pb',
                          True, "")

graph_def = tf.GraphDef()
with tf.gfile.Open(f'{MODEL_PATH}/frozen_{MODEL_NAME}.pb', "rb") as f:
    graph_def.ParseFromString(f.read())

output_graph_def = optimize_for_inference_lib.optimize_for_inference(
    graph_def, [input_node_name], [output_node_name], tf.float32.as_datatype_enum)

with tf.gfile.GFile(f'{MODEL_PATH}/opt_{MODEL_NAME}.pb', "wb") as f:
    f.write(output_graph_def.SerializeToString())

# Strip Const nodes.
for i in reversed(range(len(graph_def.node))):
    if graph_def.node[i].op == 'Const':
        del graph_def.node[i]
#     for attr in ['T', 'data_format', 'Tshape', 'N', 'Tidx', 'Tdim',
#                  'use_cudnn_on_gpu', 'Index', 'Tperm', 'is_training',
#                  'Tpaddings']:
#         if attr in graph_def.node[i].attr:
#             del graph_def.node[i].attr[attr]

# Save stripped model.
tf.train.write_graph(graph_def, "", f'{MODEL_PATH}/stripped_{MODEL_NAME}.pbtxt', as_text=True)

net = cv.dnn.readNetFromTensorflow(f'{MODEL_PATH}/opt_{MODEL_NAME}.pb', f'{MODEL_PATH}/stripped_{MODEL_NAME}.pbtxt')
## error: OpenCV(3.4.2) /io/opencv/modules/dnn/src/tensorflow/tf_graph_simplifier.cpp:712: error: (-2:Unspecified error) Tensor's data type is not supported in function 'getTensorContent'

Трудно сказать, какиеузел вызывает это из-за ошибки.Любая идея, пожалуйста?Ура

tensorflow 1.12.0
opencv 3.4.3

1 Ответ

0 голосов
/ 27 ноября 2018

Хотя я все еще не смог заставить optimize_for_inference работать из-за FusedBatchNorm, спасибо за отзывы от @dkurt и https://github.com/keras-team/keras/issues/6775, которые объясняют keras learning_phase. Вы должны установить фазу обучения перед загрузкой модели!

загрузить модель с помощью set_learning_phase (0):

import numpy as np
from keras import applications
from keras import backend as K
import tensorflow as tf

K.set_learning_phase(0)  ##
model = applications.densenet.DenseNet121(input_shape=(224, 224, 3), weights='imagenet', include_top=True)
sess = K.get_session()

print(model.input, model.outputs)
## Tensor("input_1:0", shape=(?, 224, 224, 3), dtype=float32) [<tf.Tensor 'fc1000/Softmax:0' shape=(?, 1000) dtype=float32>]

заморозить ее:

from tensorflow.python.tools import freeze_graph
from tensorflow.python.tools import optimize_for_inference_lib

MODEL_PATH = 'out'
MODEL_NAME = 'test'
input_node_name = 'input_1'
output_node_name = 'fc1000/Softmax'
!rm -rf {MODEL_PATH}/

tf.train.write_graph(sess.graph_def, MODEL_PATH, f'{MODEL_NAME}_graph.pb', as_text=False)
tf.train.write_graph(sess.graph_def, MODEL_PATH, f'{MODEL_NAME}_graph.pbtxt')
tf.train.Saver().save(sess, f'{MODEL_PATH}/{MODEL_NAME}.chkp')

freeze_graph.freeze_graph(f'{MODEL_PATH}/{MODEL_NAME}_graph.pbtxt',
                          None, False,
                          f'{MODEL_PATH}/{MODEL_NAME}.chkp',
                          output_node_name,
                          "save/restore_all",
                          "save/Const:0",
                          f'{MODEL_PATH}/frozen_{MODEL_NAME}.pb',
                          True, "")

затем загрузите его с помощью dnn:

import cv2 as cv
net = cv.dnn.readNetFromTensorflow(f'{MODEL_PATH}/frozen_{MODEL_NAME}.pb')

# Smoke test
inp = np.ones([1, 3, 224, 224]).astype(np.float32)
net.setInput(inp)
dnn_out = net.forward()
print(dnn_out.shape, dnn_out[0,:5])
## (1, 1000) [2.0760612e-04 2.6876197e-04 5.9680151e-05 5.5908626e-05 1.4762023e-04]

Как уже говорилось, я не смог заставить работать optimize_for_inference из-за FusedBatchNorm: WARNING:tensorflow:Didn't find expected Conv2D input to 'conv2_block1_0_bn/FusedBatchNorm_1' opencv-4.0.0/modules/dnn/src/tensorflow/tf_importer.cpp:497: error: (-2:Unspecified error) Input layer not found: conv2_block1_1_bn/FusedBatchNorm_1 in function 'connect' Поэтому, пожалуйста, дайте мне знать, если вы знаете решениедля этого.Спасибо

...