I use Keras with TensorFlow as a backend to create and train a simple CNN. I am able to save the model and its weights in a .pb file, freeze it and optimize it for inference but when I try to load it into OpenCV 3.4.1 I get the error:
flatten/Shape:Shape(max_pooling2d/MaxPool)
T:0
out_type:[ ]
OpenCV(3.4.1) Error: Unspecified error (Unknown layer type Shape in op flatten/Shape) in populateNet, file /home/dev/opencv-3.4.1/modules/dnn/src/tensorflow/tf_importer.cpp, line 1582
Traceback (most recent call last):
File "test.py", line 67, in <module>
net = cv.dnn.readNetFromTensorflow('graph.pb')
cv2.error: OpenCV(3.4.1) /home/dev/opencv-3.4.1/modules/dnn/src/tensorflow/tf_importer.cpp:1582: error: (-2) Unknown layer type Shape in op flatten/Shape in function populateNet
This is basically the same problem as the other question: How to import TensorFlow model with flatten layer in OpenCV?.
The reason for the error is pretty well explained in this thread.
The proposed workaround is to use directly tf.reshape
instead of using the Keras API.
However I don't know exactly how to do this. I tried to use the functional API and replace:
x = Flatten()(x)
by:
x = tf.reshape(x, [-1, some_value])
but this doesn't work and I get the following error:
Traceback (most recent call last):
File "test.py", line 57, in <module>
tf_out = model.predict(inp)
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/keras/_impl/keras/models.py", line 965, in predict
self.build()
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/keras/_impl/keras/models.py", line 578, in build
self.model = Model(self.inputs, self.outputs[0], name=self.name + '_model')
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/keras/_impl/keras/engine/topology.py", line 678, in __init__
super(Network, self).__init__(inputs, outputs, name=name)
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/layers/network.py", line 341, in __init__
'(thus holding past layer metadata). Found: ' + str(x))
ValueError: Output tensors to a Model must be the output of a TensorFlow `Layer` (thus holding past layer metadata). Found: Tensor("activation_4/Softmax:0", shape=(?, 10), dtype=float32)
Any idea of how I can export a TensorFlow model while still using Keras for most of the work?