2

I am learning about tf.contrib.learn in Tensorflow, and am using a self-made exercise. The exercise is to classify three regions as follows, with x1 and x2 as inputs, and the labels are triangles/circles/crosses: enter image description here

My code is able to fit the data, and evaluate it. However, I cannot seem to get predictions to work. Code is below. Any ideas?

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import sys
import tempfile

from six.moves import urllib

import pandas as pd
import tensorflow as tf
import numpy as np

FLAGS = None

myImportedDatax1_np = np.array([[.1],[.1],[.2],[.2],[.4],[.4],[.5],[.5],[.1],[.1],[.2],[.2]],dtype=float)
myImportedDatax2_np = np.array([[.1],[.2],[.1],[.2],[.1],[.2],[.1],[.2],[.4],[.5],[.4],[.5]],dtype=float)
combined_Imported_Data_x = np.append(myImportedDatax1_np, myImportedDatax2_np, axis=1)
myImportedDatay_np = np.array([[0],[0],[0],[0],[1],[1],[1],[1],[2],[2],[2],[2]],dtype=int)

def build_estimator(model_dir, model_type):
  x1 = tf.contrib.layers.real_valued_column("x1")
  x2 = tf.contrib.layers.real_valued_column("x2")

  wide_columns = [x1, x2]
  m = tf.contrib.learn.LinearClassifier(model_dir=model_dir, feature_columns=wide_columns)
  return m

def input_fn(input_batch, output_batch):
  inputs = {"x1": tf.constant(input_batch[:,0]), "x2": tf.constant(input_batch[:,1])}
  label = tf.constant(output_batch)
  print(inputs)
  print(label)
  print(input_batch)
  # Returns the feature columns and the label.
  return inputs, label

def train_and_eval(model_dir, model_type, train_steps, train_data, test_data):
  model_dir = tempfile.mkdtemp() if not model_dir else model_dir
  print("model directory = %s" % model_dir)
  m = build_estimator(model_dir, model_type)
  m.fit(input_fn=lambda: input_fn(combined_Imported_Data_x, myImportedDatay_np), steps=train_steps)
  results = m.evaluate(input_fn=lambda: input_fn(np.array([[.4, .1],[.4, .2]], dtype=float), np.array([[0], [0]], dtype=int)), steps=1)
  for key in sorted(results):
    print("%s: %s" % (key, results[key]))
  predictions = list(m.predict(input_fn=({"x1": tf.constant([[.1]]),"x2": tf.constant([[.1]])})))
 # print(predictions)

def main(_):
  train_and_eval(FLAGS.model_dir, FLAGS.model_type, FLAGS.train_steps,
                 FLAGS.train_data, FLAGS.test_data)

if __name__ == "__main__":
  parser = argparse.ArgumentParser()
  parser.register("type", "bool", lambda v: v.lower() == "true")
  parser.add_argument(
      "--model_dir",
      type=str,
      default="",
      help="Base directory for output models."
  )
  parser.add_argument(
      "--model_type",
      type=str,
      default="wide_n_deep",
      help="Valid model types: {'wide', 'deep', 'wide_n_deep'}."
  )
  parser.add_argument(
      "--train_steps",
      type=int,
      default=200,
      help="Number of training steps."
  )
  parser.add_argument(
      "--train_data",
      type=str,
      default="",
      help="Path to the training data."
  )
  parser.add_argument(
      "--test_data",
      type=str,
      default="",
      help="Path to the test data."
  )
  FLAGS, unparsed = parser.parse_known_args()
  tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)

1 Answer 1

1

To fix this concrete issue you can add the following input function which is similar to the existing one, except that it returns None as a second element in the tuple

def input_fn_predict():
  inputs = {"x1": tf.constant([0.1]), "x2": tf.constant([0.2])}
  print(inputs)
  return inputs, None

In a next phase you can invoke it with:

predictions = list(m.predict(input_fn=lambda: input_fn_predict()))

And if you comment out your print, then this should work.

Sign up to request clarification or add additional context in comments.

3 Comments

I tried: def input_fn_predict(): inputs = {"x1": tf.constant([[0.2], [0.4], [.5]]), "x2": tf.constant([[0.1], [0.1], [.1]])} return inputs with code: predictions = list(m.predict(input_fn=lambda: input_fn_predict())) It runs without errors. However, the predictions are all "1", which is wrong. I think the model has fitted okay, because the evaluate function behaves as expected.
I updated my answer as there was a copy paste error. Regarding the correctness, when you create the LinearClassifier you do not pass the n_classes parameter, indicating you want a binary classifier, which will not work as you your problem set consists out of three classes by nature.
Works fine now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.