title: How to transform keras model to tensorflow .pb and .pbtxt without issues?
body: <p>I'm working on the tutorial <a href="https://www.pyimagesearch.com/2019/03/11/liveness-detection-with-opencv/" rel="nofollow noreferrer">https://www.pyimagesearch.com/2019/03/11/liveness-detection-with-opencv/</a>. This tutorial works perfectly, i would like to convert keras model to tensorflow model with .pb and .pbtxt files.
  I have search on numerous tutorial how to convert keras model to .pb and pb.txt in Python.
  I have founded a function "freeze_session" who can convert in theses files.
  Neverless, when i tried to import theses files with OpenCV, it triggers severals errors.</p>
  
  <p>I have receive this error when i have imported files pb and pbtxt the first time :</p>
  
  <blockquote>
    <p>error: (-215:Assertion failed) const_layers.insert(std::make_pair(name, li)).second in function 'cv::dnn::dnn4_v20190122::`anonymous-namespace'::addConstNodes'</p>
  </blockquote>
  
  <p>I have founded in forums, they say that we must set the learning phase to test with value 0 with this line code before exported graph:</p>
  
  <p><code>K.set_learning_phase(0)</code></p>
  
  <p>After this I have succeed to import TensorFlow with only pb files :</p>
  
  <p><code>cvNet = cv.dnn.readNetFromTensorflow('./model/tf_model.pb')</code></p>
  
  <p>After these a new error is trigger when I want test the TensorFlow neural network with :</p>
  
  <pre><code>blob2 = cv2.dnn.blobFromImage(cv2.resize(face, (32, 32)), 1.0)
  
  cvNet.setInput(blob2)
  detections2 = cvNet.forward()
  </code></pre>
  
  <p>The error:</p>
  
  <blockquote>
    <p>detections2 = cvNet.forward() cv2.error: OpenCV(4.1.0)
    C:\projects\opencv-python\opencv\modules\dnn\src\dnn.cpp:524: error:
    (-2:Unspecified error) Can't create layer "flatten_1/Shape" of type
    "Shape" in function 'cv::dnn:
    :dnn4_v20190122::LayerData::getLayerInstance'</p>
  </blockquote>
  
  <p>I have see on several forums that we must remove nodes and optimized graph but it doesn't works for me : </p>
  
  <p><a href="https://answers.opencv.org/question/183507/opencv-dnn-import-error-for-keras-pretrained-vgg16-model/" rel="nofollow noreferrer">https://answers.opencv.org/question/183507/opencv-dnn-import-error-for-keras-pretrained-vgg16-model/</a></p>
  
  <p>I fact, i can't import model with two files, the importation works uniquely with the pb file but doesn't works with detection.</p>
  
  <p>How I can do this conversion easily ?
  Why sometimes user import with only pb file and some times with pb and pbtxt ?</p>
  
  <pre><code>import tensorflow as tf
  
  def freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True):
      """
      Freezes the state of a session into a pruned computation graph.
  
      Creates a new computation graph where variable nodes are replaced by
      constants taking their current value in the session. The new graph will be
      pruned so subgraphs that are not necessary to compute the requested
      outputs are removed.
      @param session The TensorFlow session to be frozen.
      @param keep_var_names A list of variable names that should not be frozen,
                            or None to freeze all the variables in the graph.
      @param output_names Names of the relevant graph outputs.
      @param clear_devices Remove the device directives from the graph for better portability.
      @return The frozen graph definition.
      """
      from tensorflow.python.framework.graph_util import convert_variables_to_constants
      graph = session.graph
      with graph.as_default():
          freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or []))
          output_names = output_names or []
          output_names += [v.op.name for v in tf.global_variables()]
          # Graph -&gt; GraphDef ProtoBuf
          input_graph_def = graph.as_graph_def()
          if clear_devices:
              for node in input_graph_def.node:
                  node.device = ""
          frozen_graph = convert_variables_to_constants(session, input_graph_def,
                                                        output_names, freeze_var_names)
          return frozen_graph
  
  from keras import backend as K
  
  K.set_learning_phase(0)  # all new operations will be in test mode from now on
  
  sess = K.get_session()
  
  model = load_model("liveness2.model")
  
  frozen_graph = freeze_session(K.get_session(), output_names=[out.op.name for out in model.outputs])
  
  # inputs:  ['conv2d_1_input']
  print('inputs: ', [input.op.name for input in model.inputs])
  
  # outputs:  ['activation_6/Softmax']
  print('outputs: ', [output.op.name for output in model.outputs])
  
  
  tf.train.write_graph(frozen_graph, "model", "tf_model.pb", as_text=False)
  tf.train.write_graph(frozen_graph, "model", "tf_model.pbtxt", as_text=True)
  
  net = cv2.dnn.readNetFromTensorflow("model/tf_model.pb");
  </code></pre>
  
  <blockquote>
    <p>detections2 = cvNet.forward() cv2.error: OpenCV(4.1.0)
    C:\projects\opencv-python\opencv\modules\dnn\src\dnn.cpp:524: error:
    (-2:Unspecified error) Can't create layer "flatten_1/Shape" of type
    "Shape" in function
    'cv::dnn::dnn4_v20190122::LayerData::getLayerInstance'</p>
  </blockquote>