I have a question about the input_shape of CONV2D layer. As the official doc says:
4 D tensor with shape: batch_shape (channels, rows, cols) if data_format='channels_first' or 4 D tensor with shape: batch_shape (rows, cols, channels) if data_format='channels_last'.
In my case, I assemble the dataset by using the method:
tf.data.Dataset.from_tensor_slices()
The detail goes like this. First, I converted a bunch of image into tensor. The shape is:
(100, 128, 128, 3) -> in the format of (numbers of images, width, height, channels)
And, the ground truth of labels were converted into tensor also. In my case, the each label is a 155 long list with float32. The shape is:
(100, 155) -> in the format of (numbers of labels, labels)
Then, I created the dataset using the method which mentioned above:
dataset = tf.data.Dataset.from_tensor_slices((fetched_image_list, labels))
Next, I iterated a sample in the dataset.
import pprint
pp = pprint.PrettyPrinter()
pp.pprint(f"---------Test----------")
iterator = iter(dataset)
data, label = iterator.get_next()
pp.pprint(data)
pp.pprint(data.shape)
The result is :
'---------Test----------'
<tf.Tensor: shape=(128, 128, 3), dtype=float64, numpy=
array([[[0. , 0. , 0.01568628],
[0. , 0. , 0.01568628],
[0. , 0. , 0.01568628],
...,
[0. , 0. , 0.01568628],
[0. , 0. , 0.01568628],
[0. , 0. , 0.01568628]],
[[0. , 0. , 0.01568628],
[0. , 0. , 0.01568628],
[0. , 0. , 0.01568628],
...,
[0. , 0. , 0.01568628],
[0. , 0. , 0.01568628],
[0. , 0. , 0.01568628]],
[[0. , 0. , 0.01568628],
[0. , 0. , 0.01568628],
[0. , 0. , 0.01568628],
...,
[0. , 0. , 0.01568628],
[0. , 0. , 0.01568628],
[0. , 0. , 0.01568628]],
...,
[[0.94117653, 0.37254903, 0.36862746],
[0.9571079 , 0.52573532, 0.44705883],
[0.99215692, 0.86274517, 0.61960787],
...,
[0.99607849, 0.80000007, 0.56078434],
[0.99607849, 0.79460794, 0.55539221],
[0.99607849, 0.79215693, 0.5529412 ]],
[[0.94117653, 0.37254903, 0.36862746],
[0.9571079 , 0.52573532, 0.44705883],
[0.99215692, 0.86274517, 0.61960787],
...,
[0.99607849, 0.80000007, 0.56078434],
[0.99607849, 0.79460794, 0.55539221],
[0.99607849, 0.79215693, 0.5529412 ]],
[[0.94117653, 0.37254903, 0.36862746],
[0.9571079 , 0.52573532, 0.44705883],
[0.99215692, 0.86274517, 0.61960787],
...,
[0.99607849, 0.80000007, 0.56078434],
[0.99607849, 0.79460794, 0.55539221],
[0.99607849, 0.79215693, 0.5529412 ]]])>
TensorShape([128, 128, 3])
However, I mentioned the official doc about CONV2D where the input should be either (batch_shape, row, colts, channels) or (batch_shape, channels, rows, cols). So I configured my CNN model like this:
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(32, (3, 3), strides=(2,2), padding="same", dilation_rate=(1,1), input_shape=(128, 128, 3), activation='relu'),
tf.keras.layers.Conv2D(71, (3, 3), strides=(2,2), padding="same", dilation_rate=(1,1), activation='relu'),
tf.keras.layers.Conv2D(128, (3, 4), strides=(2,3), padding="same", dilation_rate=(1,1),activation='relu'),
tf.keras.layers.Conv2D(128, (3, 3), strides=(2,2), padding="same", dilation_rate=(1,1),activation='relu'),
tf.keras.layers.Conv2D(128, (3, 4), strides=(2, 3), padding="same", dilation_rate=(1, 1), activation='relu'),
tf.keras.layers.Conv2D(128, (3, 3), strides=(2, 2), padding="same", dilation_rate=(1, 1), activation='relu'),
tf.keras.layers.Dropout(0.20),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(155)
])
But I got this error in return:
raise ValueError(f'Input {input_index} of layer "{layer_name}" is '
ValueError: Input 0 of layer "sequential" is incompatible with the layer: expected shape=(None, 128, 128, 3), found shape=(128, 128, 3)
If I had changed the input_shape into (32, 128, 128, 3). A similar error popped out:
ValueError: Input 0 of layer "sequential" is incompatible with the layer: expected shape=(None, 32, 128, 128, 3), found shape=(128, 128, 3)
I think the problem exist in the way I created the dataset.
How can I fix this issue? What is your suggestion?
CodePudding user response:
You need to set a batch size for the dataset like this
batch_size = 8 #Or some number
dataset = dataset.batch(batch_size)
If you don't do this, your image goes into the model in the shape of (128,128,3)
instead of (batch_size,128,128,3)
which is what Conv2D layer expects.
If you want to send 1 image at a time, set batch size as 1