Reputation: 580
I am trying to train an AlexNet CNN model by following the steps in the tutorial from the TensorFlow guide site .However, the tutorial makes use of the below code to load in the training data
mnist = tf.contrib.learn.datasets.load_dataset("mnist")
train_data = mnist.train.images # Returns np.array
train_labels = np.asarray(mnist.train.labels, dtype=np.int32)
eval_data = mnist.test.images # Returns np.array
eval_labels = np.asarray(mnist.test.labels, dtype=np.int32)
For me, I wrote a script to write my dataset examples into a TFRecord file, and then during training, try to read these record back and feed it into the alexnet network. See code below:
#FUNCTION TO GET ALL DATASET DATA
def _read_multiple_images(filenames, perform_shuffle=False, repeat_count=1,
batch_size=1, available_record=39209, num_of_epochs=1):
def _read_one_image(serialized):
#Specify the fatures you want to extract
features = {'image/shape': tf.FixedLenFeature([], tf.string),
'image/class/label': tf.FixedLenFeature([], tf.int64),
'image/class/text': tf.FixedLenFeature([], tf.string),
'image/filename': tf.FixedLenFeature([], tf.string),
'image/encoded': tf.FixedLenFeature([], tf.string)}
parsed_example = tf.parse_single_example(serialized,
features=features)
#Finese extracted data
image_raw = tf.decode_raw(parsed_example['image/encoded'], tf.uint8)
shape = tf.decode_raw(parsed_example['image/shape'], tf.int32)
label = tf.cast(parsed_example['image/class/label'], dtype=tf.int32)
reshaped_img = tf.reshape(image_raw, shape)
casted_img = tf.cast(reshaped_img, tf.float32)
label_tensor= [label]
image_tensor = [casted_img]
return label_tensor, image_tensor
complete_labels = np.array([])
complete_images = np.array([])
dataset = tf.data.TFRecordDataset(filenames=filenames)
dataset = dataset.map(_read_one_image)
dataset = dataset.repeat(repeat_count) #Repeats dataset this # times
dataset = dataset.batch(batch_size) #Batch size to use
iterator = dataset.make_initializable_iterator()
labels_tensor, images_tensor = iterator.get_next() #Get batch data
no_of_rounds = int(math.ceil(available_record/batch_size));
#Create tf session, get nest set of batches, and evelauate them in batches
sess = tf.Session()
count=1
for _ in range(num_of_epochs):
sess.run(iterator.initializer)
while True:
try:
evaluated_label, evaluated_image = sess.run([labels_tensor,
images_tensor])
#convert evaluated tensors to np array
label_np_array = np.asarray(evaluated_label, dtype=np.uint8)
image_np_array = np.asarray(evaluated_image, dtype=np.uint8)
#squeeze np array to make dimesnsions appropriate
squeezed_label_np_array = label_np_array.squeeze()
squeezed_image_np_array = image_np_array.squeeze()
#add current batch to total
complete_labels = np.append(complete_labels, squeezed_label_np_array)
complete_images = np.append(complete_images, squeezed_image_np_array)
except tf.errors.OutOfRangeError:
print("End of Dataset Reached")
break
count=count+1
sess.close()
return complete_labels, complete_images
My main issue is that, while tring to recoverer all the 39209 images in my dataset (227x227x3) as np array so I can feed to my TF estimator. My computer runs out of memory.
train_input_fn = tf.estimator.inputs.numpy_input_fn(x={"x":
complete_images},y=complete_labels,batch_size=100,num_epochs=1,
shuffle=True)
dataset_classifier.train(input_fn=train_input_fn,num_epochs=1,hooks=
[logging_hook])
Is there a way I can get my images and labels out of my TF record in batches and feed it to my TF.Estimator in batches rather than having to need to load it all into an np array as specified in this tutorial
Upvotes: 0
Views: 1461
Reputation: 126154
If you can access your data as a tf.data.Dataset
, there is no need to convert it to a NumPy array before passing it to an Estimator
. You can simply build the Dataset
directly in your input function, with something like the following:
def train_input_fn():
dataset = tf.data.TFRecordDataset(filenames=filenames)
dataset = dataset.map(_read_one_image)
dataset = dataset.repeat(1) # Because `num_epochs=1`.
dataset = dataset.batch(100) # Because `batch_size=1`.
dataset = dataset.prefetch(1) # To improve performance by overlapping execution.
iterator = dataset.make_one_shot_iterator() # NOTE: Use a "one-shot" iterator.
labels_tensor, images_tensor = iterator.get_next()
return {"x": images_tensor}, labels_tensor
dataset_classifier.train(
input_fn=train_input_fn, num_epochs=1, hooks=[logging_hook])
This should be much more efficient than building a NumPy array, because it avoids having to materialize the whole dataset in memory at once. You can also use performance enhancements like Dataset.prefetch()
and the parallel version of Dataset.map()
to improve the training speed.
Upvotes: 3