38

In tensorflow the training from the scratch produced following 6 files:

  1. events.out.tfevents.1503494436.06L7-BRM738
  2. model.ckpt-22480.meta
  3. checkpoint
  4. model.ckpt-22480.data-00000-of-00001
  5. model.ckpt-22480.index
  6. graph.pbtxt

I would like to convert them (or only the needed ones) into one file graph.pb to be able to transfer it to my Android application.

I tried the script freeze_graph.py but it requires as an input already the input.pb file which I do not have. (I have only these 6 files mentioned before). How to proceed to get this one freezed_graph.pb file? I saw several threads but none was working for me.

Rafal
  • 479
  • 1
  • 4
  • 10
  • 1
    See here: https://stackoverflow.com/questions/45433231/freezing-a-cnn-tensorflow-model-into-a-pb-file/45437684#45437684 – Dat Tran Aug 24 '17 at 17:01
  • How did you get `graph.pbtxt`? If it is the graph of your model you can freeze it with `freeze.py`. `.pbtxt`. – velikodniy Aug 24 '17 at 17:36
  • The graph.pbtxt I found in the training logs after finishing the training. It was however saved before the training was finished. Check for it in the previously saved status of the graph. For the training from scratch I used the script: train_image_classifier.py. For training I I used my own pictures (.jpg) which I had to convert to .tfrecord files before using the script build_image_data.py – Rafal Aug 24 '17 at 20:33

4 Answers4

46

You can use this simple script to do that. But you must specify the names of the output nodes.

import tensorflow as tf

meta_path = 'model.ckpt-22480.meta' # Your .meta file
output_node_names = ['output:0']    # Output nodes

with tf.Session() as sess:
    # Restore the graph
    saver = tf.train.import_meta_graph(meta_path)

    # Load weights
    saver.restore(sess,tf.train.latest_checkpoint('path/of/your/.meta/file'))

    # Freeze the graph
    frozen_graph_def = tf.graph_util.convert_variables_to_constants(
        sess,
        sess.graph_def,
        output_node_names)

    # Save the frozen graph
    with open('output_graph.pb', 'wb') as f:
      f.write(frozen_graph_def.SerializeToString())

If you don't know the name of the output node or nodes, there are two ways

  1. You can explore the graph and find the name with Netron or with console summarize_graph utility.

  2. You can use all the nodes as output ones as shown below.

output_node_names = [n.name for n in tf.get_default_graph().as_graph_def().node]

(Note that you have to put this line just before convert_variables_to_constants call.)

But I think it's unusual situation, because if you don't know the output node, you cannot use the graph actually.

velikodniy
  • 854
  • 7
  • 15
  • 8
    Is there a simple way to get the output node names? – Michael Ramos Sep 19 '17 at 16:07
  • I am trying to do the same. Is there a way to find the output node names? – blueether Dec 16 '17 at 21:37
  • You can use [summarize_graph](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/graph_transforms#inspecting-graphs) utility. – velikodniy Dec 18 '17 at 08:01
  • 2
    I get this error, it may be because I'm not sure my output_node_names are correct. `File "/path/to/saver.py", line 1796, in restore raise ValueError("Can't load save_path when it is None.")` – craq Aug 08 '18 at 05:21
  • sure. It's a bit long for a comment, so I put it here: https://pastebin.com/2YLjtMvQ – craq Aug 08 '18 at 22:27
  • 1
    @craq Looks like it cannot find any checkpoint in the current directory (with path name `.`) Try to set the path to your checkpoint explicitely: `saver.restore(sess, 'path/to/model.ckpt')`. – velikodniy Aug 09 '18 at 09:02
  • Correcting the folder definitely helped, and I think it might have been a badly formatted `ckpt` file as well. It turns out I had some other problems with my training. Once I fixed those, this problem goes away. (I'm left with the problem that what I thought were my `output_node_names` are actually `not in graph`. But I'm sure I'll figure that out soon) – craq Aug 10 '18 at 02:48
  • Try: [n.name for n in tf.get_default_graph().as_graph_def().node] – gogasca Sep 19 '18 at 23:32
  • 3
    If anyone comes here and has the same problem I did, aka, when trying to freeze the graph, it will fail with "Attempting to use uninitialized value", just add `init=tf.global_variables_initializer() sess.run(init)` after you Load the Weights. – Eek Nov 06 '18 at 13:56
  • @niza-siwale Thank you for your editing, but your code puts all the nodes into `output_node_names` instead only the output node as suggested by the documentation. – velikodniy Jan 10 '19 at 11:36
  • @velikodniy sorry for that, I was going to rectify my mistake but I forgot. Thanks for help – Niza Siwale Jan 10 '19 at 11:46
  • What is the difference compared to `freeze_graph.py` ? – mrgloom Mar 14 '19 at 09:41
  • What is `tf.train.latest_checkpoint('.')`, it should be replaced with checkpoint dir? – mrgloom Mar 14 '19 at 09:42
  • This is a better way to get the 'trainable' variables and could automate saving the model `vars_train = tf.trainable_variables()` `output_node_names = [var.name.split(":")[0] for var in vars_train]` – Juan Dec 10 '19 at 19:52
  • 1
    @Juan Usually not all the trainable variables are the output nodes you need. Furthermore, the output node may not be a variable at all. For example in the graph for the expression `a * x + 1` the output node is `add`. – velikodniy Dec 11 '19 at 12:02
7

As it may be helpful for others, I also answer here after the answer on github ;-). I think you can try something like this (with the freeze_graph script in tensorflow/python/tools) :

python freeze_graph.py --input_graph=/path/to/graph.pbtxt --input_checkpoint=/path/to/model.ckpt-22480 --input_binary=false --output_graph=/path/to/frozen_graph.pb --output_node_names="the nodes that you want to output e.g. InceptionV3/Predictions/Reshape_1 for Inception V3 "

The important flag here is --input_binary=false as the file graph.pbtxt is in text format. I think it corresponds to the required graph.pb which is the equivalent in binary format.

Concerning the output_node_names, that's really confusing for me as I still have some problems on this part but you can use the summarize_graph script in tensorflow which can take the pb or the pbtxt as an input.

Regards,

Steph

Pratik Khadloya
  • 12,509
  • 11
  • 81
  • 106
Steph
  • 118
  • 7
3

I tried the freezed_graph.py script, but the output_node_name parameter is totally confusing. Job failed.

So I tried the other one: export_inference_graph.py. And it worked as expected!

python -u /tfPath/models/object_detection/export_inference_graph.py \
  --input_type=image_tensor \
  --pipeline_config_path=/your/config/path/ssd_mobilenet_v1_pets.config \
  --trained_checkpoint_prefix=/your/checkpoint/path/model.ckpt-50000 \
  --output_directory=/output/path

The tensorflow installation package I used is from here: https://github.com/tensorflow/models

kennyut
  • 3,671
  • 28
  • 30
  • hi @kennynut what is this `--pipeline_config_path`? what is written in this kind of file, could you give me an example? I've been using tensorflow for a while but have never need to use such a configuration file. – Scott Yang Nov 16 '18 at 07:57
  • The pipeline_config_path provides the basic configuration for the frozen graph to function properly. Say, it normally comes with the default name-pipeline.config--under the default root path of compressed packages among model zoos from google git hub repositories. – Neveroldmilk Jan 02 '19 at 13:54
1

First, use the following code to generate the graph.pb file. with tf.Session() as sess:

    # Restore the graph
    _ = tf.train.import_meta_graph(args.input)

    # save graph file
    g = sess.graph
    gdef = g.as_graph_def()
    tf.train.write_graph(gdef, ".", args.output, True)

then, use summarize graph get the output node name. Finally, use

python freeze_graph.py --input_graph=/path/to/graph.pbtxt --input_checkpoint=/path/to/model.ckpt-22480 --input_binary=false --output_graph=/path/to/frozen_graph.pb --output_node_names="the nodes that you want to output e.g. InceptionV3/Predictions/Reshape_1 for Inception V3 "

to generate the freeze graph.

Matt
  • 1,342
  • 5
  • 12
lgz00gi
  • 11
  • 2