I am going to make some GAN-Model Tester using tf.keras with MNIST hand-writed digits dataset. Because my model is going to be used in 128x128 images, I resized MNIST dataset to 128x128x1. but, the program makes some errors, that I never seen.
(x_train, _), (_, _) = mnist.load_data()
x_train = (x_train.astype(np.float32) - 127.5) / 127.5
x_train = tf.image.resize_images(x_train, [128, 128])
idx = np.random.randint(0, x_train.shape[0], batch_size) # picks some data, count is batch_size=32.
imgs = x_train[idx] # This line made errors
The last line made two errors:
tensorflow.python.framework.errors_impl.InvalidArgumentError: Shape must be rank 1 but is rank 2 for 'strided_slice_1' (op: 'StridedSlice') with input shapes: [60000,128,128,1], [1,32], [1,32], [1].
and,
ValueError: Shape must be rank 1 but is rank 2 for 'strided_slice_1' (op: 'StridedSlice') with input shapes: [60000,128,128,1], [1,32], [1,32], [1].
I think the number '32' means batch_size(=32).
I tried to find about this error, but I couldn't find like this error.
I don't have any ideas to solve this problems (because I started to use keras a week ago, before I used pytorch).
You have more issue with your code above, but the primer cause of error is that tensorflow doesn't support the numpy type advanced slicing. Actually the error message is because tensorflow try to align your input array in his strided-slices:
An example for the strided-slices:
foo[5:,:,:3] on a 7x8x9 tensor is equivalent to foo[5:7,0:8,0:3]. foo[::-1] reverses a tensor with shape 8.
Unfortunately only basic type indexing is available in Tensorflow currently. Advanced type indexing is under development.
The secondary problem, that your resizing was not proper. Tensorflow assumes a 3D or 4D input. You tried to pass a 2D image to `tf.image.resize_images(), which doesn't return the required new image dimensions. So we have to reshape the raw images like this:
x_train = x_train.reshape((-1, x_train.shape[1], x_train.shape[1], 1))
only then we can pass them to:
`x_train = tf.image.resize_images(x_train, [128, 128])
It will return then the proper dimensions:
print(x_train.shape)
Out:
(60000, 128, 128, 1)
So summarizing the whole solution, currently you can do it as follows:
import numpy as np
import tensorflow as tf
batch_size = 32
mnist = tf.keras.datasets.mnist
(x_train, _), (_, _) = mnist.load_data()
x_train = x_train.reshape((-1, x_train.shape[1], x_train.shape[1], 1))
x_train = (x_train.astype(np.float32) - 127.5) / 127.5
x_train = tf.image.resize_images(x_train, [128, 128])
idx = np.random.randint(0, x_train.shape[0], batch_size)
imgs = [x_train[i,:,:,:] for i in idx]
which is a pretty messy "solution".
Other, actually a real solution with rearrange the original code we can achieve what we aimed to as a workaround to the tensorflow indexing issue:
import numpy as np
import tensorflow as tf
batch_size = 32
mnist = tf.keras.datasets.mnist
(x_train, _), (_, _) = mnist.load_data()
x_train = (x_train.astype(np.float32) - 127.5) / 127.5
idx = np.random.randint(0, x_train.shape[0], batch_size)
x_train = x_train[idx]
x_train = x_train.reshape((-1, x_train.shape[1], x_train.shape[1], 1))
x_train = tf.image.resize_images(x_train, [128, 128])
print(x_train.shape)
Out:
(32, 128, 128, 1)
That's it!
Alternatively instead of tf.image.resize_images() you can use an additional image tools like skimage.transform.resize() from scikit-image which returns numpy array type data.