title: How to correctly encode labels with tensorflow's one-hot encoding?
body: <p>I've been trying to learn Tensorflow with python 3.6 and decided on building a facial recognition program using data from the University of Essex's face data base (<a href="http://cswww.essex.ac.uk/mv/allfaces/index.html" rel="nofollow noreferrer">http://cswww.essex.ac.uk/mv/allfaces/index.html</a>). So far I've been following Tensorflow's MNIST Expert guide, but when I start testing, my accuracy is 0 for every epoch, so I know something is wrong. I feel most shaky on how I'm handling the labels, so I figure that's where the problem is.</p>
  
  <p>The labels in the dataset are either numeric IDs, like 987323, or someone's name, like "fordj". My idea to deal with this was to create a "pre-encoding" <strong>encode_labels</strong> function, which gives each unique label in the test and training sets their own unique integer value. I checked to make sure each unique label in the test and train sets have the same unique value. It also returns a dictionary so that I can easily map back to the original label from the encoded version. If I <strong>don't</strong> do this step and pass the labels as I retrieve them (i.e "fordj"), I get an error saying </p>
  
  <blockquote>
    <p>UnimplementedError (see above for traceback): Cast string to int32 is not supported
         [[Node: Cast = CastDstT=DT_INT32, SrcT=DT_STRING, _device="/job:localhost/replica:0/task:0/device:CPU:0"]]</p>
  </blockquote>
  
  <p>The way I'm interpreting this is that since many of the labels are people's names, tensorflow can't convert a label like "fordj" to a tf.int32. The code to grab labels and paths is here:</p>
  
  <pre><code>def get_paths_and_labels(path):
      """ image_paths  :  list of relative image paths
          labels       :  mix of alphanumeric characters """
      image_paths = [path + image for image in os.listdir(path)]
      labels = [i.split(".")[-3] for i in image_paths]
      labels = [i.split("/")[-1] for i in labels]
      return image_paths, labels
  
  def encode_labels(train_labels, test_labels):
      """ Assigns a numeric value to each label since some are subject's names """
      found_labels = []
      index = 0
      mapping = {}
      for i in train_labels:
          if i in found_labels:
              continue
          mapping[i] = index
          index += 1
          found_labels.append(i)
      return [mapping[i] for i in train_labels], [mapping[i] for i in test_labels], mapping
  </code></pre>
  
  <p>Here is how I assign my training and testing labels. I then want to use tensorflow's one-hot encoder to encode them again for me.</p>
  
  <pre><code>def main():
      # Grabs the labels and each image's relative path 
      train_image_paths, train_labels = get_paths_and_labels(TRAIN_PATH)
      # Smallish dataset so I can read it all into memory
      train_images = [cv2.imread(image) for image in train_image_paths]
  
      test_image_paths, test_labels = get_paths_and_labels(TEST_PATH)
      test_images = [cv2.imread(image) for image in test_image_paths]
  
      num_classes = len(set(train_labels))
  
      # Placeholders
      x = tf.placeholder(tf.float32, shape=[None, IMAGE_SIZE[0] * IMAGE_SIZE[1]])
      y_ = tf.placeholder(tf.float32, shape=[None, num_classes])
      x_image = tf.reshape(x, [-1, IMAGE_SIZE[0], IMAGE_SIZE[1], 1])
  
      # One-hot labels
      train_labels, test_labels, mapping = encode_labels(train_labels, test_labels)
  
      train_labels = tf.one_hot(indices=tf.cast(train_labels, tf.int32), depth=num_classes)
      test_labels = tf.one_hot(indices=tf.cast(test_labels, tf.int32), depth=num_classes)
  </code></pre>
  
  <p>I'm sure I'm doing something wrong. I know sklearn has a LabelEncoder, though I haven't tried it out yet. Thanks for any advice on this, all help is appreciated!</p>