MIftikharK
MIftikharK

Reputation: 67

Training custom dataset in TensorFlow gives error

I want to perform image classification on my custom dataset with TensorFlow. I have imported my own dataset but stuck at the training step (not sure if it imports the complete dataset or a single batch of 50 images although list contains all file names).

Dataset Info: image resolution = 88*128 (single channel), batch size = 50.

Here is the list of operations I want to perform:

  1. Import complete dataset (change in code if it only creates a batch of 50 images)
  2. Train the model using my own dataset (train Images and test Images)
  3. Proper way of creating batches.

Here is the complete code, so far:

import tensorflow as tf
import os


def init_weights(shape):
    init_random_dist = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(init_random_dist)

def init_bias(shape):
    init_bias_vals = tf.constant(0.1, shape=shape)
    return tf.Variable(init_bias_vals)


def conv2d(x, W):
    return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')


def max_pool_2by2(x):
    return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                          strides=[1, 2, 2, 1], padding='SAME')


def convolutional_layer(input_x, shape):
    W = init_weights(shape)
    b = init_bias([shape[3]])

    return tf.nn.relu(conv2d(input_x, W) + b)


def normal_full_layer(input_layer, size):
    input_size = int(input_layer.get_shape()[1])
    W = init_weights([input_size, size])
    b = init_bias([size])

    return tf.matmul(input_layer, W) + b


def get_labels(path):
    return os.listdir(path)


def files_list(path):
    return [val for sublist in [[os.path.join(j) for j in i[2]] for i in os.walk(path)] for val in sublist]


def image_tensors(filesQueue): 
    reader = tf.WholeFileReader()
    filename, content = reader.read(filesQueue)
    image = tf.image.decode_jpeg(content, channels=1)
    image = tf.cast(image, tf.float32)
    resized_image = tf.image.resize_images(image, [88, 128])

    return resized_image


path = './data/train'
trainLabels = get_labels(path)
trainingFiles = files_list(path)

trainQueue = tf.train.string_input_producer(trainingFiles)
trainBatch = tf.train.batch([image_tensors(trainQueue)], batch_size=50)
# ^^^^^^^^ a complete dataset or only a single batch? How to check?

path = './data/test'
testLabels = get_labels(path)
testingFiles = files_list(path)

testQueue = tf.train.string_input_producer(testingFiles)
testBatch = tf.train.batch([image_tensors(testQueue)], batch_size=50)
# ^^^^^^^ same here

x = tf.placeholder(tf.float32,shape=[88, 128])
y_true = tf.placeholder(tf.float32,shape=[None,len(trainLabels)])

x_image = tf.reshape(x,[-1,88,128,1])

convo_1 = convolutional_layer(x_image,shape=[6,6,1,32])
convo_1_pooling = max_pool_2by2(convo_1)

convo_2 = convolutional_layer(convo_1_pooling,shape=[6,6,32,64])
convo_2_pooling = max_pool_2by2(convo_2)


convo_2_flat = tf.reshape(convo_2_pooling,[-1,22*32*64])
full_layer_one = tf.nn.relu(normal_full_layer(convo_2_flat,1024))

hold_prob = tf.placeholder(tf.float32)
full_one_dropout = tf.nn.dropout(full_layer_one,keep_prob=hold_prob)


y_pred = normal_full_layer(full_one_dropout,10)

cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y_true,logits=y_pred))

optimizer = tf.train.AdamOptimizer(learning_rate=0.0001)
train = optimizer.minimize(cross_entropy)

init = tf.global_variables_initializer()



steps = 4000

with tf.Session() as sess:
    sess.run(init)
    for i in range(steps):
        batch_x , batch_y = tf.train.batch(trainBatch, batch_size=50)
        #                                  ^^^^^^^^^^^ Error
        sess.run(train,feed_dict={x:batch_x,y_true:batch_y,hold_prob:0.5})

        if i%400 == 0:
            print('Currently on step {}'.format(i))
            print('Accuracy is:')

            matches = tf.equal(tf.argmax(y_pred,1),tf.argmax(y_true,1))
            acc = tf.reduce_mean(tf.cast(matches,tf.float32))
            print(sess.run(acc,feed_dict={x:testBatch,y_true:testLabels,hold_prob:1.0}))
            #                             ^^^^^^^^^^^^ Test Images?
            print('\n')

This is the error I get:

TypeError                                 Traceback (most recent call last)
<ipython-input-24-5d0dac5724cd> in <module>()
      5     sess.run(init)
      6     for i in range(steps):
----> 7         batch_x , batch_y = tf.train.batch([trainBatch], batch_size=50)
      8         sess.run(train,feed_dict={x:batch_x,y_true:batch_y,hold_prob:0.5})
      9 

c:\users\TF_User\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\framework\ops.py in __iter__(self)
    503       TypeError: when invoked.
    504     """
--> 505     raise TypeError("'Tensor' object is not iterable.")
    506 
    507   def __bool__(self):

TypeError: 'Tensor' object is not iterable.

It seems like casting wrong type instead of Tensor or a List but can't figure out. Kindly, correct the issue and help me above listed issues.

Upvotes: 0

Views: 532

Answers (1)

Grr
Grr

Reputation: 16079

It looks like you are using an unnecessary second call of tf.train.batch.

Generally you would do something like:

...     
images, labels = tf.train.batch([images, labels], batch_size=50)

with tf.Session() as sess:
    sess.run(init)
    for i in range(steps):
        sess.run(train, feed_dict={x:images,y_true:labels,hold_prob:0.5})
...

I think that TensorFlow: does tf.train.batch automatically load the next batch when the batch has finished training? should give you a better understanding of what tf.train.batch is doing and how it is used. Also the documentation on Reading Data should help too.

Upvotes: 1

Related Questions