0

I have a set called train_images and train_labels from the tensorflow basic image classification guide:

https://www.tensorflow.org/tutorials/keras/classification

I load the dataset with:

fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

the shape of these two list are respectively: (60000, 28, 28) (60000,)

After that I want to use ImageDataGenerator to flip horizontally some images but when I fit the model with my train lists, it returns my an error saying the x shoud be an array of rank 4

I already tried to do

train_images = (np.expand_dims(train_images,0))

so the shape become (1,60000,28,28) (I have to do this to let the model examine a single image) but it doesn't work to fit the model

this is the rest of the code:

aug = ImageDataGenerator(rotation_range=20, horizontal_flip=True)

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28,28)),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(10, activation='softmax')
    ])

model.compile(
    optimizer='adam',
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy']
    )

BS=32
EPOCHS=10
H = model.fit_generator(
    aug.flow(train_images, train_labels, batch_size=BS),
    validation_data=(test_images, test_labels),
    steps_per_epoch=len(train_images) // BS,
    epochs=EPOCHS)

And this is the error generated:

---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-65-e49da92bcb89> in <module>()
      5 #train_images.shape
      6 H = model.fit_generator(
----> 7         aug.flow(train_images, train_labels, batch_size=BS),
      8         validation_data=(test_images, test_labels),
      9         steps_per_epoch=len(train_images) // BS,

1 frames
/usr/local/lib/python3.6/dist-packages/keras_preprocessing/image/numpy_array_iterator.py in __init__(self, x, y, image_data_generator, batch_size, shuffle, sample_weight, seed, data_format, save_to_dir, save_prefix, save_format, subset, dtype)

    115             raise ValueError('Input data in `NumpyArrayIterator` '
    116                              'should have rank 4. You passed an array '
--> 117                              'with shape', self.x.shape)
    118         channels_axis = 3 if data_format == 'channels_last' else 1
    119         if self.x.shape[channels_axis] not in {1, 3, 4}:

ValueError: ('Input data in `NumpyArrayIterator` should have rank 4. You passed an array with shape', (60000, 28, 28))

actually train_images is (N° of images, width, height) what is the 4th axis it is waiting for? how to perform this?

2 Answers2

1

You should convert your images to 4D tensor. Now you have NHW format (batch dimension, height, width). The error says that you should have NHWC format - batch, height, width, channel. So you need to do

train_images = (np.expand_dims(train_images, axis=3))

This will add a channel dimension (of size 1), the resulting shape will be (60000,28,28,1) and it should fix your problem.

Taras Khalymon
  • 614
  • 4
  • 11
  • I did as you suggest but now it gives error on epoch... the error message is: Error when checking input: expected flatten_4_input to have 3 dimensions, but got array with shape (32, 28, 28, 1). why? – Luca Troncone Oct 25 '19 at 11:09
  • Because you have `keras.layers.Flatten(input_shape=(28,28))` and it expects the input shape to be (?, 28, 28), but you pass (?, 28, 28, 1), change the input shape in Flatten to be (28, 28, 1) and it should be fine. – Taras Khalymon Oct 25 '19 at 11:18
  • You need 4D tensor (?, 28, 28, 1) because of ImageDataGenerator. It processes an image as 3D tensor (height, width, channel) and the first batch dimension is used to represent multiple images. So if you use gray-scale images, your last dimension will be 1, if you use 1 image, your first dimension will be 1, but they should be there. Just keep it in mind. – Taras Khalymon Oct 25 '19 at 11:22
1

Channel should be the last dimension of 4D tensor. Therefore instead of train_images = (np.expand_dims(train_images,0)) try with train_images = (np.expand_dims(train_images, -1)). Hope it will help.

Kaushik Roy
  • 1,627
  • 2
  • 11
  • 13