0
votes

All the tensorflow tutorials do a great job, however, they all use preprocessed downloadable datasets that work out of the box. Their tutorial on MNIST is the perfect example.
For a school project, 4 others and I have been assigned to train a CNN on supplied data in the form of PNG images. It's just a directory with 150 images. The labels are contained in the image file names.

The way the codes sits now we are getting an error which I will include below.

We followed the MNIST code found here: https://github.com/tensorflow/tensorflow/blob/r1.3/tensorflow/examples/tutorials/layers/cnn_mnist.py

So we are fairly certain our problem is in how we have processed the image data. We have been trying to get this to work for roughly 3 days. (Many errors that we have worked through, this is just the latest).

Any help or feedback would be greatly appreciated! Also, if anybody has questions about this please comment.

import os

import tensorflow as tf
import numpy as np
#from PIL import Image


# a function
def cnn_model_fn(features,labels,mode):
    """Model function for CNN."""
    # Input Layer
    input_layer = tf.reshape(features['x'], [-1, 128, 128, 3])

    # Convolutional Layer #1
    conv_1 = tf.layers.conv2d(
        inputs=input_layer,
        filters=64,
        kernel_size=[7, 7],
        strides=2,
        padding="same",
        activation=tf.nn.relu)
    conv_2 = tf.layers.conv2d(
        inputs=conv_1,
        filters=128,
        kernel_size=[5, 5],
        padding="same",
        strides = 2,
        activation=tf.nn.relu)
    max_pool_1 = tf.layers.max_pooling2d(
        inputs = conv_2,
        pool_size = 3,
        strides = 1
    )
    conv_3 = tf.layers.conv2d(
        inputs=max_pool_1,
        filters=96,
        kernel_size=[3, 3],
        activation=tf.nn.relu
    )
    max_pool_2 = tf.layers.max_pooling2d(
        inputs = conv_3,
        pool_size = 2,
        strides = 1
    )
    dropout_1 = tf.layers.dropout(
        inputs = max_pool_2,
        rate=0.5
    )
    fully_connected_1 = tf.contrib.layers.fully_connected(
        inputs = dropout_1,
        num_outputs = 1024,

    )
    dropout_2 = tf.layers.dropout(
        inputs = fully_connected_1,
        rate=0.5
    )
    fully_connected_2 = tf.contrib.layers.fully_connected(
        inputs = dropout_2,
        num_outputs = 1024,

    )
    fully_connected_3 = tf.contrib.layers.fully_connected(
        inputs = fully_connected_2,
        num_outputs = 15,

    )
    softmax_layer = tf.contrib.layers.softmax(
        logits = fully_connected_3
    )
#------------------------------------------------------------------------MAIN--------------------------------------------------------------------------------------------------


def getLabels():

    imagelabels_arr = []

    image_files = os.listdir("../assets/CNN-Data/")

    for image in image_files:
        imagelabels_arr.append(image.split('.')[len(image.split('.'))-2])

    return imagelabels_arr


def getTrainImages():

    filenames = []

    image_files = os.listdir("../assets/CNN-Data/")

    for image in image_files:
        filenames.append(image)

    filename_queue = tf.train.string_input_producer(filenames)

    reader = tf.WholeFileReader()
    filename, content = reader.read(filename_queue)
    image = tf.image.decode_png(content, channels=3)
    images = np.asarray(image)
    image = tf.cast(image, tf.float64)
    resize_image = tf.image.resize_images(image, (128, 128))

   # image_batch = tf.train.batch([resize_image], batch_size=10)

    print(resize_image)
    return resize_image


with tf.Session() as sess:

    sess.run(tf.initialize_all_variables())

    classifier = tf.estimator.Estimator(
        model_fn=cnn_model_fn, model_dir="./test")

    train_input_fn = tf.estimator.inputs.numpy_input_fn(
          x={'x':np.array(getTrainImages())},
          y=np.array(getLabels()),
          batch_size=10,
          num_epochs=None,
          shuffle=True)

    classifier.train(
          input_fn=train_input_fn,
          steps=20,
          )

The Error:

Traceback (most recent call last):
  File "CNN.py", line 134, in <module>
    steps=20,
  File "C:\Users\Tyler\Desktop\tensorFlowPratice\flowenv\lib\site-packages\tensorflow\python\estimator\estimator.py", line 241, in train
    loss = self._train_model(input_fn=input_fn, hooks=hooks)
  File "C:\Users\Tyler\Desktop\tensorFlowPratice\flowenv\lib\site-packages\tensorflow\python\estimator\estimator.py", line 628, in _train_model
    input_fn, model_fn_lib.ModeKeys.TRAIN)
  File "C:\Users\Tyler\Desktop\tensorFlowPratice\flowenv\lib\site-packages\tensorflow\python\estimator\estimator.py", line 499, in _get_features_and_labels_from_input_fn
    result = self._call_input_fn(input_fn, mode)
  File "C:\Users\Tyler\Desktop\tensorFlowPratice\flowenv\lib\site-packages\tensorflow\python\estimator\estimator.py", line 585, in _call_input_fn
    return input_fn(**kwargs)
  File "C:\Users\Tyler\Desktop\tensorFlowPratice\flowenv\lib\site-packages\tensorflow\python\estimator\inputs\numpy_io.py", line 109, in input_fn
    if len(set(v.shape[0] for v in ordered_dict_x.values())) != 1:
  File "C:\Users\Tyler\Desktop\tensorFlowPratice\flowenv\lib\site-packages\tensorflow\python\estimator\inputs\numpy_io.py", line 109, in <genexpr>
    if len(set(v.shape[0] for v in ordered_dict_x.values())) != 1:
IndexError: tuple index out of range
2
I don't know much about the Estimator API, but shouldn't cnn_model_fn return something? - jdehesa
Yes, you are right. If we add the return statement the MNIST code is using we get the same error. - Tyler Bell
What does the statement print(resize_image) show? (or is it not running to that point?) Also side notes: 1) it doesn't affect the program, but images = np.asarray(image) does not make sense... image is a TF tensor, not NumPy 2) maybe what you want is image = tf.cast(image / 255.0, tf.float64) ? (to have pixel values in [0, 1]) - jdehesa
It prints "Tensor("Squeeze:0", shape=(128, 128, 3), dtype=float32)" If I comment out the images = np.asarray(image) it prints the same thing. - Tyler Bell
If I use tf.cast(image/ 255.0, tf/float64) I get a TypeError: unsupported operand type(s) for /: 'Tensor' and 'float' - Tyler Bell

2 Answers

0
votes

classifier.train function expects numpy arrays, but not tensors. Hence you need to convert example_batch, label batch by evaluating them with a session, but not wrapping them using np.array() function. (Explanation)

sess.run(tf.initialize_all_variables())

tf.train.start_queue_runners(sess)

classifier = tf.estimator.Estimator(
    model_fn=cnn_model_fn, model_dir="./test")

train_input_fn = tf.estimator.inputs.numpy_input_fn(
      x={'x':getTrainImages().eval()},
      y=getLabels().eval(),
      batch_size=10,
      num_epochs=None,
      shuffle=True)

classifier.train(
      input_fn=train_input_fn,
      steps=20,
      )
-1
votes

I recommended to apply tools on top of tensorflow. You might consider to code it through roNNie, Theano, Keras, Torch or Caffe.