Using TensorFlow/Keras, I want to classify pictures into two classes, selfie and non-selfie.
I have gathered samples into two filesystem folders, one for each category.
I implemented the training below by following the official tutorial for MNIST fashion (which is also a pictures classification problem), after using loading pictures from the filesystem as seen at https://stackoverflow.com/a/52417770/226958.
Unfortunately, I get an error:
1.10.1
Tensor("IteratorGetNext:0", shape=(?, 100, 100, 1), dtype=float32)
Tensor("IteratorGetNext:1", shape=(?,), dtype=int32)
Traceback (most recent call last):
File "run.py", line 50, in <module>
model.fit(images, labels, epochs=1, steps_per_epoch=60000)
File "/home/nico/.local/lib/python2.7/site-packages/tensorflow/python/keras/engine/training.py", line 1278, in fit
validation_split=validation_split)
File "/home/nico/.local/lib/python2.7/site-packages/tensorflow/python/keras/engine/training.py", line 878, in _standardize_user_data
exception_prefix='input')
File "/home/nico/.local/lib/python2.7/site-packages/tensorflow/python/keras/engine/training_utils.py", line 182, in standardize_input_data
'with shape ' + str(data_shape))
ValueError: Error when checking input: expected flatten_input to have 3 dimensions, but got array with shape (None, 100, 100, 1)
Here is the source code:
import tensorflow as tf
print(tf.__version__)
out_shape = tf.convert_to_tensor([100, 100])
batch_size = 2
image_paths, labels = ["selfies-data/1", "selfies-data/2"], [1, 2]
epoch_size = len(image_paths)
image_paths = tf.convert_to_tensor(image_paths, dtype=tf.string)
labels = tf.convert_to_tensor(labels)
# The images loading part is from https://stackoverflow.com/a/52417770/226958
dataset = tf.data.Dataset.from_tensor_slices((image_paths, labels))
dataset = dataset.repeat().shuffle(epoch_size)
def map_fn(path, label):
# path/label represent values for a single example
image = tf.image.decode_jpeg(tf.read_file(path))
# some mapping to constant size - be careful with distorting aspec ratios
image = tf.image.resize_images(image, out_shape)
image = tf.image.rgb_to_grayscale(image)
# color normalization - just an example
image = tf.to_float(image) * (2. / 255) - 1
return image, label
# num_parallel_calls > 1 induces intra-batch shuffling
dataset = dataset.map(map_fn, num_parallel_calls=8)
dataset = dataset.batch(batch_size)
dataset = dataset.prefetch(1)
images, labels = dataset.make_one_shot_iterator().get_next()
# All of the following is from https://www.tensorflow.org/tutorials/keras/basic_classification
from tensorflow import keras
model = keras.Sequential([
keras.layers.Flatten(input_shape=(100, 100)),
keras.layers.Dense(128, activation=tf.nn.relu),
keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer=tf.train.AdamOptimizer(),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
print(images)
print(labels)
model.fit(images, labels, epochs=epoch_size, steps_per_epoch=60000)
While there are similar questions which I have read, I don't see any question with this None
.
How can I adapt Keras to my input, or transform my input so that Keras accepts it?