tensorflow: Freezing + fake quantization of graph

System information

  • Have I written custom code (as opposed to using a stock example script provided in TensorFlow): Custom code
  • OS Platform and Distribution (e.g., Linux Ubuntu 16.04): Linux Ubuntu 16.04
  • TensorFlow installed from (source or binary): Source (v1.8) / binary (v1.9)
  • TensorFlow version (use command below): v1.8.0-0-g93bc2e2072 1.8.0 AND v1.9.0-0-g25c197e023 1.9.0
  • Python version: 3.6
  • Bazel version (if compiling from source):
  • GCC/Compiler version (if compiling from source): (result of gcc -v) gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
  • CUDA/cuDNN version: Not used
  • GPU model and memory: Not used
  • Exact command to reproduce: Code given below

Describe the problem

Problem described here, but didn’t have any luck; essentially, I cannot freeze a graph which has been fake quantized using tf.contrib.quantize.create_training_graph(). I have a sample below (there may be a better way to add a freezing operation at the end of the graph quantization test script).

The code shown spits out the following error (or variants dependent on architecture):

ValueError: Input 0 of node import/weights_quant/AssignMinLast was passed float from import/weights_quant/min:0 incompatible with expected float_ref

I may be doing something wrong - this arises regardless of which order I apply the creation of training/eval graphs and which of the 3 methods I use for freezing the graph. I also tried the fixes here to no avail.

Source code / logs

import tensorflow as tf


def conv_simple(_input):
    _input_r = tf.reshape(_input, shape=[-1, 28, 28, 1])
    _conv1 = tf.nn.conv2d(_input_r, tf.Variable(tf.random_normal([3, 3, 1, 64], stddev=0.1)), strides=[1, 1, 1, 1],
                          padding='SAME')
    _conv2 = tf.nn.bias_add(_conv1, tf.Variable(tf.random_normal([64], stddev=0.1)))
    _conv3 = tf.nn.relu(_conv2)
    _pool = tf.nn.max_pool(_conv3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
    _dense = tf.reshape(_pool, [-1, 14 * 14 * 64])
    _out = tf.add(tf.matmul(_dense, tf.Variable(tf.random_normal([14 * 14 * 64, 10], stddev=0.1))),
                  tf.Variable(tf.random_normal([10], stddev=0.1)), name='Output')
    out = {
        'input_r': _input_r, 'conv1': _conv1, 'conv2': _conv2, 'conv3': _conv3
        , 'pool': _pool, 'dense': _dense, 'out': _out
    }
    return out


# tf Graph input
x = tf.placeholder(tf.float32, [None, 784], name='X')
_pred = conv_simple(x)['out']

tf.contrib.quantize.create_training_graph()

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())

    # FREEZE GRAPH
    output_graph_def = sess.graph.as_graph_def()
    input_names = ["X"]
    output_names = ["Output"]
    LOG_DIR = '/some/path/to/log/dir/'

    output_graph_def = tf.graph_util.convert_variables_to_constants(
        sess,  # The session is used to retrieve the weights
        output_graph_def,  # The graph_def is used to retrieve the nodes
        output_names  # The output node names are used to select the useful nodes,
    )

    g = tf.import_graph_def(output_graph_def)

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 38

Most upvoted comments

The problem is, you cannot apply create_eval_graph to the graph on which you already called create_training_graph. To solve this, I save variables after training with fake quantization using tf.train.Saver.save. Then I simply create a new graph from scratch, call create_eval_graph and finally restore the variables using tf.train.Saver.restore. Remeber to call execute tf.global_variables_initializer() after both create_training_graph and create_eval_graph.