title: Error: "logits and labels must have the same shape ((?, 1) vs (?,))" - in Keras model to Estimator
body: <p>I am new to ML and trying out Keras models. I wanted to learn about Keras model to <code>tf.Estimator</code> and hence pieced together code from various examples. The code has three key parts - first part creates <code>TFRecord</code> files by reading a set of images from folder, second part reads from the <code>TFRecord</code> files and provides to <code>input_fn</code>, third part is the Keras model with VGG16 and a simple fully-connected layer. </p>
  
  <p>While the first two parts of code work properly, I am getting this error - </p>
  
  <pre><code>'ValueError: logits and labels must have the same shape ((?, 1) vs (?,))' 
  </code></pre>
  
  <p>while training. As referenced in another similar question's answer, I tried <code>expand-dim</code> and even reshape of my <code>labels</code> to <code>(?, 1)</code>, but that gave me some other error. </p>
  
  <p>I am not sure what is wrong with this code and reason for </p>
  
  <pre><code>'ValueError: logits and labels must have the same shape ((?, 1) vs (?,))'. 
  </code></pre>
  
  <p>Please help identify the mistake and suggest a solution. Thanks in advance. I have copy-pasted my code from notebook below.</p>
  
  <hr>
  
  <pre><code>**Cell1 contents**
  
  from random import shuffle
  import glob
  import sys
  import cv2
  import numpy as np
  #import skimage.io as io
  import tensorflow as tf
  
  def _int64_feature(value):
      return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
  def _bytes_feature(value):
      return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))
  
  def load_image(addr):
      # read an image and resize to (224, 224)
      # cv2 load images as BGR, convert it to RGB
      img = cv2.imread(addr)
      if img is None:
          return None
      img = cv2.resize(img, (224, 224), interpolation=cv2.INTER_CUBIC)
      img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
      return img
  
  def createDataRecord(out_filename, addrs, labels):
      # open the TFRecords file
      #writer = tf.python_io.TFRecordWriter(out_filename)
      options = tf.python_io.TFRecordOptions(tf.python_io.TFRecordCompressionType.GZIP)
      writer = tf.python_io.TFRecordWriter(out_filename, options=options)
  
      for i in range(len(addrs)):
          # print how many images are saved every 1000 images
          if not i % 1000:
              print('Train data: {}/{}'.format(i, len(addrs)))
              sys.stdout.flush()
          # Load the image
          img = load_image(addrs[i])
  
          label = labels[i]
  
          if img is None:
              continue
  
          # Create a feature
          feature = {
              'image': _bytes_feature(img.tostring()),
              'label': _int64_feature(label)
          }
          # Create an example protocol buffer
          example = tf.train.Example(features=tf.train.Features(feature=feature))
  
          # Serialize to string and write on the file
          writer.write(example.SerializeToString())
  
      writer.close()
      sys.stdout.flush()
  
  **Cell2 contents**
  
  cat_dog_train_path = 'dataset-mix/*/*.jpg'
  # read addresses and labels from the 'train' folder
  addrs = glob.glob(cat_dog_train_path)
  labels = [0 if 'A' in addr else 1 for addr in addrs]  # 0 = A, 1 = B
  
  # to shuffle data
  c = list(zip(addrs, labels))
  shuffle(c)
  addrs, labels = zip(*c)
  
  #print("addrs: " + str(addrs))
  #print("labels: " + str(labels))
  
  # Divide the data into 60% train, 20% validation, and 20% test
  train_addrs = addrs[0:int(0.6*len(addrs))]
  train_labels = labels[0:int(0.6*len(labels))]
  val_addrs = addrs[int(0.6*len(addrs)):int(0.8*len(addrs))]
  val_labels = labels[int(0.6*len(addrs)):int(0.8*len(addrs))]
  test_addrs = addrs[int(0.8*len(addrs)):]
  test_labels = labels[int(0.8*len(labels)):]
  
  print("train_addrs: " + str(train_addrs))
  print("train_labels: " + str(train_labels))
  
  createDataRecord('train-zipped.tfrecords', train_addrs, train_labels)
  createDataRecord('val-zipped.tfrecords', val_addrs, val_labels)
  createDataRecord('test-zipped.tfrecords', test_addrs, test_labels)
  
  ------
  **second part**
  **Cell3 contents**
  
  import tensorflow as tf
  import cv2
  import sys
  import numpy as np
  
  sess = tf.Session()
  sess.run(tf.global_variables_initializer())
  
  def parser(record):
      keys_to_features = {
          "image": tf.FixedLenFeature([], tf.string),
          "label": tf.FixedLenFeature([], tf.int64)
      }
  
      parsed = tf.parse_single_example(record, keys_to_features)
      image = tf.decode_raw(parsed["image"], tf.uint8)
      image = tf.cast(image, tf.float32)
      image = tf.reshape(image, shape=[224, 224, 3])
      label = tf.cast(parsed["label"], tf.int32)
  
      #return {'image': image}, label
      print("image.shape: " + str(np.shape(image)))
      print("label.shape before: " + str(np.shape(label)) + "; label: " + str(label))
  
      #label = np.array(label)
      #print("label.shape after making np.array: " + str(np.shape(label)))
      #label = np.expand_dims(label, axis=1)
      #label = np.reshape(label, (-1, 1))
      print("labels1.shape after expand_dims" + str(np.shape(label)))
  
      return {'vgg16_input': image}, label
  
  
  def input_fn(filenames=["train-zipped.tfrecords"]):
  
    #To create a TFRecordDataset to read the compressed files:
    dataset = tf.data.TFRecordDataset(filenames=filenames, compression_type='GZIP', num_parallel_reads=40)
  
    dataset = dataset.apply(
        tf.contrib.data.shuffle_and_repeat(1024, 1)
    )
    dataset = dataset.apply(
        tf.contrib.data.map_and_batch(parser, 32)
    )
    #dataset = dataset.map(parser, num_parallel_calls=12)
    #dataset = dataset.batch(batch_size=1000)
  
    #print("dataset: " + str(dataset.make_one_shot_iterator().get_next()))
  
    dataset = dataset.prefetch(buffer_size=2)
  
    return dataset
  
  
  def train_input_fn():
      return input_fn(filenames=["train-zipped.tfrecords", "test-zipped.tfrecords"])
  
  def val_input_fn():
      return input_fn(filenames=["val-zipped.tfrecords"])
  
  dat_set = train_input_fn()
  item1 = dat_set.make_one_shot_iterator().get_next()[1]
  res = sess.run(item1)
  print("dataset: " + str(np.shape(res)))
  
  #train_dataset = train_input_fn("train-zipped.tfrecords", "test-zipped.tfrecords")
  #val_dataset = val_input_fn("val-zipped.tfrecords")
  
  #print("classes: {0};\n shapes: {1};\n types: {2}\n".format(train_dataset.output_classes, 
  #            train_dataset.output_shapes, train_dataset.output_types))
  
  -----------
  **third part**
  **Cell4 contents**
  
  def make_keras_estimator(): 
      from tensorflow.python.keras.applications.vgg16 import VGG16
      from tensorflow.python.keras import models
      from tensorflow.python.keras import layers
      import os
  
      conv_base = VGG16(weights='imagenet',
                    include_top=False,
                    input_shape=(224, 224, 3))
      conv_base.trainable = False
  
      model = models.Sequential()
      model.add(conv_base)
      model.add(layers.Flatten())
      model.add(layers.Dense(256, activation='relu'))
      model.add(layers.Dense(1, activation='sigmoid'))
  
      model.compile(loss='binary_crossentropy',
                    optimizer=tf.keras.optimizers.RMSprop(lr=2e-5),
                    metrics=['acc'])
  
      model_dir = os.path.join(os.getcwd(), "model-keras-mix")
      os.makedirs(model_dir, exist_ok=True)
      print("model_dir: ",model_dir)
      model.summary()
  
      print("input_names" + str(model.input_names ))
  
      model_est = tf.keras.estimator.model_to_estimator(keras_model=model,
                                                          model_dir=model_dir)
      return model_est
  
  **Cell5 contents**
  model_keras = make_keras_estimator()
  
  train_spec = tf.estimator.TrainSpec(input_fn=train_input_fn, max_steps=10)
  eval_spec = tf.estimator.EvalSpec(input_fn=val_input_fn)
  
  import time
  start_time = time.time()
  tf.estimator.train_and_evaluate(model_keras, train_spec, eval_spec)
  print("--- %s seconds ---" % (time.time() - start_time))
  </code></pre>