title: Understanding tf.contrib.lite.TFLiteConverter quantization parameters
body: <p>I'm trying to use UINT8 quantization while converting tensorflow model to tflite model:</p>
  
  <p>If use <code>post_training_quantize = True</code>, model size is x4 lower then original fp32 model, so I assume that model weights are uint8, but when I load model and get input type via <code>interpreter_aligner.get_input_details()[0]['dtype']</code> it's float32. Outputs of the quantized model are about the same as original model.</p>
  
  <pre><code>converter = tf.contrib.lite.TFLiteConverter.from_frozen_graph(
          graph_def_file='tflite-models/tf_model.pb',
          input_arrays=input_node_names,
          output_arrays=output_node_names)
  converter.post_training_quantize = True
  tflite_model = converter.convert()
  </code></pre>
  
  <p>Input/output of converted model:</p>
  
  <pre><code>print(interpreter_aligner.get_input_details())
  print(interpreter_aligner.get_output_details())
  [{'name': 'input_1_1', 'index': 47, 'shape': array([  1, 128, 128,   3], dtype=int32), 'dtype': &lt;class 'numpy.float32'&gt;, 'quantization': (0.0, 0)}]
  [{'name': 'global_average_pooling2d_1_1/Mean', 'index': 45, 'shape': array([  1, 156], dtype=int32), 'dtype': &lt;class 'numpy.float32'&gt;, 'quantization': (0.0, 0)}]
  </code></pre>
  
  <p>Another option is to specify more parameters explicitly:
  Model size is x4 lower then original fp32 model, model input type is uint8, but model outputs are more like garbage.</p>
  
  <pre><code>converter = tf.contrib.lite.TFLiteConverter.from_frozen_graph(
          graph_def_file='tflite-models/tf_model.pb',
          input_arrays=input_node_names,
          output_arrays=output_node_names)
  converter.post_training_quantize = True
  converter.inference_type = tf.contrib.lite.constants.QUANTIZED_UINT8
  converter.quantized_input_stats = {input_node_names[0]: (0.0, 255.0)}  # (mean, stddev)
  converter.default_ranges_stats = (-100, +100)
  tflite_model = converter.convert()
  </code></pre>
  
  <p>Input/output of converted model:</p>
  
  <pre><code>[{'name': 'input_1_1', 'index': 47, 'shape': array([  1, 128, 128,   3], dtype=int32), 'dtype': &lt;class 'numpy.uint8'&gt;, 'quantization': (0.003921568859368563, 0)}]
  [{'name': 'global_average_pooling2d_1_1/Mean', 'index': 45, 'shape': array([  1, 156], dtype=int32), 'dtype': &lt;class 'numpy.uint8'&gt;, 'quantization': (0.7843137383460999, 128)}]
  </code></pre>
  
  <p>So my questions are:</p>
  
  <ol>
  <li>What is happenning when only <code>post_training_quantize = True</code> is set? i.e. why 1st case work fine, but second don't.</li>
  <li>How to estimate mean, std and range parameters for second case?</li>
  <li>Looks like in second case model inference is faster, is it depend on the fact that model input is uint8?</li>
  <li>What means <code>'quantization': (0.0, 0)</code> in 1st case and <code>'quantization': (0.003921568859368563, 0)</code>,<code>'quantization': (0.7843137383460999, 128)</code> in 2nd case?</li>
  <li>What is <code>converter.default_ranges_stats</code> ?</li>
  </ol>
  
  <p><strong>Update:</strong></p>
  
  <p>Answer to question 4 is found <a href="https://stackoverflow.com/q/54830126/1179925">What does &#39;quantization&#39; mean in interpreter.get_input_details()?</a></p>