Ask Your Question

readNetFromTensorflow fails on retrained NN

asked 2017-10-04 11:57:49 -0600

Robb gravatar image

updated 2017-10-04 11:59:02 -0600

Hi, I hope someone can help me.

My plan is to train a CNN in Tensorflow and use it in a app that uses OpenCV3.3 . For testing purposes i used the retrain script delivered with Tensorflow and expanded it (Inception V3) with the Flowers. (their Tutorial I trained two models with it (one mobile the other just a normal one)

The resulting graph can be used in Tensorflow, but it fails to load in Opencv (Python, OpencCv 3.3, Win 7 64 ). The script does not create any Checkpoints so i can't freeze the graph (is it Frozen and can ich check this?) But i used the optimize_for_intereference to remove jpeg decoding.

When i try to load those graphs in OpenCV it throws the following errors:

mobile version:

"...tensorflow\tf_importer.cpp:465: error: (-2) More than one input is Const op in function cv::dnn::experimental_dnn_v1::`anonymous-namespace'::TFImporter::getConstBlob"

non mobile:

"tensorflow\tf_importer.cpp:447: error: (-2) Input layer not found: conv/batchnorm in function cv::dnn::experimental_dnn_v1::`anonymous-namespace'::TFImporter::connect"

Thanks for any help in advance ;-)

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted

answered 2017-10-04 14:51:56 -0600

dkurt gravatar image

Hi, @Robb! It's a quite easy:

Let's retrained graph is called graph.pb. Call tool to remove an Identity nodes, some training-only nodes, make some fusion (conv+bn):

python ~/tensorflow/tensorflow/python/tools/ \
  --input graph.pb \
  --output opt_graph.pb \
  --frozen_graph True \
  --input_names DecodeJpeg/contents \
  --output_names final_result

Before: image description After: image description

Then remove PlaceholderWithDefault node and preprocessing subgraph by

~/tensorflow/bazel-bin/tensorflow/tools/graph_transforms/transform_graph \
  --in_graph=opt_graph.pb \
  --out_graph=final_graph.pb \
  --inputs=Mul \
  --outputs=final_result \
  --transforms="remove_nodes(op=PlaceholderWithDefault) strip_unused_nodes(type=float, shape=\"1,299,299,3\") sort_by_execution_order"

PlaceholderWithDefault PlaceholderWithDefault

preprocessing subgraph preprocessing subgraph


import cv2 as cv
import numpy as np

net = cv.dnn.readNetFromTensorflow('final_graph.pb')
inp = np.random.standard_normal([299, 299, 3]).astype(np.float32)
out = net.forward()

Thank you for the interest in OpenCV! All images are done using TensorBoard.

edit flag offensive delete link more


@dkurt This solution remove batchnorm, would it affect the inference results? May you help me solve this problem, thanks

tham gravatar imagetham ( 2017-10-04 19:15:03 -0600 )edit

@tham, it fuses convolution weights with batch normalization multipliers. I don't think that tool are called optimize_for_inferene would break the inference.

dkurt gravatar imagedkurt ( 2017-10-04 23:25:38 -0600 )edit

First thanks for the detailed answer. I hope this will solve my problems but i can't use bazel to build anything on my machine (windows 7) it always throws errors. I think i will have to solve those problems first.

Robb gravatar imageRobb ( 2017-10-06 07:07:01 -0600 )edit

@Robb, May be that can help you in this case

dkurt gravatar imagedkurt ( 2017-10-06 11:42:02 -0600 )edit

@dkurt Thanks for your answer. I also did the retraining exercise via , and then followed your directions above, but I can't seem to make the DNN module read the retrained MobileNet after I did the suggestions in your answer though... I still get the error "More than one input is Const op in function". Do you have any other tips for deciding which nodes need to be deleted in order to get OpenCV to read the graph? I am using the Java version of OpenCV.

tomdke gravatar imagetomdke ( 2017-10-06 15:49:57 -0600 )edit

@tomdke, try to follow guides at or at the header of this PR.

dkurt gravatar imagedkurt ( 2017-10-07 01:23:08 -0600 )edit

@dkurt I could load the retrained graph after doing everything exactly as described, but it seems to be empty? It is not returning any results for any input anymore.

Robb gravatar imageRobb ( 2017-11-01 05:02:43 -0600 )edit

@Robb, you mean net.empty() is True or out is None or every bounding box at out has less confidence than threshold? Have you tried to run the same graph in TensorFlow?

dkurt gravatar imagedkurt ( 2017-11-01 08:36:32 -0600 )edit

@dkurt Not in tf yet, i only tried to load it there (was loaded) in OpenCv, in python, it throws on net.Forward() = error \opencv-3.3.0\modules\dnn\src\layers\reshape_layer.cpp:86: error: (-215) total(srcShape, srcRange.start, srcRange.end) == maskTotal in function cv::dnn::computeShapeByReshapeMask maybe that is a information that helps you help me ;-)

Robb gravatar imageRobb ( 2017-11-01 08:52:05 -0600 )edit

@Robb, The sample at answer works correctly or produces the same error?

dkurt gravatar imagedkurt ( 2017-11-01 08:56:33 -0600 )edit
Login/Signup to Answer

Question Tools


Asked: 2017-10-04 11:57:49 -0600

Seen: 499 times

Last updated: Oct 04 '17