title: How do I export a TensorFlow model as a .tflite file?
body: <p><strong>Background information:</strong></p>
  
  <p>I have written a TensorFlow model very similar to the <a href="https://www.tensorflow.org/get_started/premade_estimators" rel="noreferrer">premade iris classification model</a> provided by TensorFlow. The differences are relatively minor: </p>
  
  <ul>
  <li>I am classifying football exercises, not iris species.</li>
  <li>I have 10 features and one label, not 4 features and one label.</li>
  <li>I have 5 different exercises, as opposed to 3 iris species.</li>
  <li>My trainData contains around 3500 rows, not only 120.</li>
  <li>My testData contains around 330 rows, not only 30.</li>
  <li>I am using a DNN classifier with n_classes=6, not 3.</li>
  </ul>
  
  <p>I now want to export the model as a <code>.tflite</code> file. But according to the <a href="https://www.tensorflow.org/mobile/tflite/devguide" rel="noreferrer">TensorFlow Developer Guide</a>, I need to first export the model to a <code>tf.GraphDef</code> file, then freeze it and only then will I be able to convert it. However, the <a href="https://github.com/tensorflow/models/blob/master/research/slim/README.md" rel="noreferrer">tutorial</a>  provided by TensorFlow to create a <code>.pb</code> file from a custom model only seems to be optimized for image classification models. </p>
  
  <p><strong>Question:</strong></p>
  
  <p>So how do I convert a model like the iris classification example model into a <code>.tflite</code> file? Is there an easier, more direct way to do it, without having to export it to a <code>.pb</code> file, then freeze it and so on? An example based on the iris classification code or a link to a more explicit tutorial would be very useful!</p>
  
  <hr>
  
  <p><strong>Other information:</strong></p>
  
  <ul>
  <li>OS: macOS 10.13.4 High Sierra</li>
  <li>TensorFlow Version: 1.8.0</li>
  <li>Python Version: 3.6.4</li>
  <li>Using PyCharm Community 2018.1.3</li>
  </ul>
  
  <p><strong>Code:</strong></p>
  
  <p>The iris classification code can be cloned by entering the following command:</p>
  
  <p><code>git clone https://github.com/tensorflow/models</code></p>
  
  <p>But in case you don't want to download the whole package, here it is:</p>
  
  <p>This is the classifier file called <strong><code>premade_estimator.py</code></strong>:</p>
  
  <pre><code>    #  Copyright 2016 The TensorFlow Authors. All Rights Reserved.
      #
      #  Licensed under the Apache License, Version 2.0 (the "License");
      #  you may not use this file except in compliance with the License.
      #  You may obtain a copy of the License at
      #
      #  http://www.apache.org/licenses/LICENSE-2.0
      #
      #  Unless required by applicable law or agreed to in writing,                         software
      #  distributed under the License is distributed on an "AS IS" BASIS,
      #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      #  See the License for the specific language governing permissions and
      #  limitations under the License.
      """An Example of a DNNClassifier for the Iris dataset."""
      from __future__ import absolute_import
      from __future__ import division
      from __future__ import print_function
  
      import argparse
      import tensorflow as tf
  
      import iris_data
  
      parser = argparse.ArgumentParser()
      parser.add_argument('--batch_size', default=100, type=int, help='batch size')
      parser.add_argument('--train_steps', default=1000, type=int,
                  help='number of training steps')
  
  
      def main(argv):
          args = parser.parse_args(argv[1:])
  
          # Fetch the data
          (train_x, train_y), (test_x, test_y) = iris_data.load_data()
  
          # Feature columns describe how to use the input.
          my_feature_columns = []
          for key in train_x.keys():
                      my_feature_columns.append(tf.feature_column.numeric_column(key=key))
  
          # Build 2 hidden layer DNN with 10, 10 units respectively.
          classifier = tf.estimator.DNNClassifier(
              feature_columns=my_feature_columns,
              # Two hidden layers of 10 nodes each.
              hidden_units=[10, 10],
              # The model must choose between 3 classes.
              n_classes=3)
  
          # Train the Model.
          classifier.train(
              input_fn=lambda: iris_data.train_input_fn(train_x, train_y,
                                                args.batch_size),
              steps=args.train_steps)
  
          # Evaluate the model.
          eval_result = classifier.evaluate(
              input_fn=lambda: iris_data.eval_input_fn(test_x, test_y,
                                               args.batch_size))
  
          print('\nTest set accuracy:         {accuracy:0.3f}\n'.format(**eval_result))
  
          # Generate predictions from the model
          expected = ['Setosa', 'Versicolor', 'Virginica']
          predict_x = {
              'SepalLength': [5.1, 5.9, 6.9],
              'SepalWidth': [3.3, 3.0, 3.1],
              'PetalLength': [1.7, 4.2, 5.4],
              'PetalWidth': [0.5, 1.5, 2.1],
          }
  
          predictions = classifier.predict(
              input_fn=lambda: iris_data.eval_input_fn(predict_x,
                                                       labels=None,
                                                       batch_size=args.batch_size))
  
          template = '\nPrediction is "{}" ({:.1f}%), expected "{}"'
  
          for pred_dict, expec in zip(predictions, expected):
              class_id = pred_dict['class_ids'][0]
              probability = pred_dict['probabilities'][class_id]
  
              print(template.format(iris_data.SPECIES[class_id],
                            100 * probability, expec))
  
  
      if __name__ == '__main__':
          # tf.logging.set_verbosity(tf.logging.INFO)
          tf.app.run(main)
  </code></pre>
  
  <p>And this is the data file called <strong><code>iris_data.py</code></strong>:</p>
  
  <pre><code>    import pandas as pd
      import tensorflow as tf
  
      TRAIN_URL = "http://download.tensorflow.org/data/iris_training.csv"
      TEST_URL = "http://download.tensorflow.org/data/iris_test.csv"
  
      CSV_COLUMN_NAMES = ['SepalLength', 'SepalWidth',
                          'PetalLength', 'PetalWidth', 'Species']
      SPECIES = ['Setosa', 'Versicolor', 'Virginica']
  
  
      def maybe_download():
          train_path = tf.keras.utils.get_file(TRAIN_URL.split('/')[-1], TRAIN_URL)
          test_path = tf.keras.utils.get_file(TEST_URL.split('/')[-1], TEST_URL)
  
          return train_path, test_path
  
  
      def load_data(y_name='Species'):
          """Returns the iris dataset as (train_x, train_y), (test_x, test_y)."""
          train_path, test_path = maybe_download()
  
          train = pd.read_csv(train_path, names=CSV_COLUMN_NAMES, header=0)
          train_x, train_y = train, train.pop(y_name)
  
          test = pd.read_csv(test_path, names=CSV_COLUMN_NAMES, header=0)
          test_x, test_y = test, test.pop(y_name)
  
          return (train_x, train_y), (test_x, test_y)
  
  
      def train_input_fn(features, labels, batch_size):
          """An input function for training"""
          # Convert the inputs to a Dataset.
          dataset = tf.data.Dataset.from_tensor_slices((dict(features), labels))
  
          # Shuffle, repeat, and batch the examples.
          dataset = dataset.shuffle(1000).repeat().batch(batch_size)
  
          # Return the dataset.
          return dataset
  
  
      def eval_input_fn(features, labels, batch_size):
          """An input function for evaluation or prediction"""
          features = dict(features)
          if labels is None:
              # No labels, use only features.
              inputs = features
          else:
              inputs = (features, labels)
  
          # Convert the inputs to a Dataset.
          dataset = tf.data.Dataset.from_tensor_slices(inputs)
  
          # Batch the examples
          assert batch_size is not None, "batch_size must not be None"
          dataset = dataset.batch(batch_size)
  
          # Return the dataset.
          return dataset
  </code></pre>
  
  <p>** <strong>UPDATE</strong> **</p>
  
  <p>Ok so I have found a seemingly very useful piece of code <a href="https://github.com/tensorflow/tensorflow/blob/master/tensorflow/contrib/lite/toco/g3doc/python_api.md" rel="noreferrer">on this page</a>:</p>
  
  <pre><code>    import tensorflow as tf
  
      img = tf.placeholder(name="img", dtype=tf.float32, shape=(1, 64, 64, 3))
      val = img + tf.constant([1., 2., 3.]) + tf.constant([1., 4., 4.])
      out = tf.identity(val, name="out")
      with tf.Session() as sess:
        tflite_model = tf.contrib.lite.toco_convert(sess.graph_def, [img], [out])
        open("test.tflite", "wb").write(tflite_model)
  </code></pre>
  
  <p>This little guy directly converts a simple model to a TensorFlow Lite Model. Now all I have to do is find a way to adapt this to the iris classification model. Any suggestions?</p>