Reputation: 77
I am new to tensorflow (version 2.3.0). I want to build an image classfier based on the 'oxford_flower102' with inception v3. I have prepared the dataset and now wants to train the inception v3 network, but I get an error which I do not understand. The error code is:
ValueError: Input 0 of layer conv2d is incompatible with the layer: : expected min_ndim=4, found ndim=3. Full shape received: [500, 667, 3]
The preprocess of the datasets seems to be fine, the error comes when I want to feed the data into the inception v3 network with the command
predictions = model(images, training=True)
Here you can find my whole code:
import warnings
import tensorflow as tf
import tensorflow_datasets as tfds
tfds.disable_progress_bar()
import logging
logger = tf.get_logger()
logger.setLevel(logging.ERROR)
import os
import tensorflow as tf
warnings.filterwarnings('ignore')
EPOCHS = 50
BATCH_SIZE = 8
NUM_CLASSES = 102
image_height = 299
image_width = 299
channels = 3
save_model_dir = os.getcwd()
def get_model():
model = tf.keras.applications.InceptionV3(include_top=True,weights=None,classes=NUM_CLASSES)
model.build(input_shape=(None, image_height, image_width, channels))
return model
def get_loss_object():
return tf.keras.losses.SparseCategoricalCrossentropy()
def get_optimizer():
return tf.keras.optimizers.Adadelta()
def get_train_loss():
return tf.keras.metrics.Mean(name='train_loss')
def get_train_accuracy():
return tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')
def get_valid_loss():
return tf.keras.metrics.Mean(name='valid_loss')
def get_valid_accuracy():
return tf.keras.metrics.SparseCategoricalAccuracy(name='valid_accuracy')
if __name__ == '__main__':
dataset, dataset_info = tfds.load('oxford_flowers102', with_info=True, as_supervised=True)
dataset_info
test_set, training_set, validation_set = dataset['test'], dataset['train'], dataset['validation']
num_training_examples = 0
num_validation_examples = 0
num_test_examples = 0
for example in training_set:
num_training_examples += 1
for example in validation_set:
num_validation_examples += 1
for example in test_set:
num_test_examples += 1
model =get_model()
loss_object = get_loss_object()
optimizer=get_optimizer()
train_loss= get_train_loss()
train_accuracy=get_train_accuracy()
valid_loss=get_valid_loss()
valid_accuracy=get_valid_accuracy()
@tf.function
def train_step(images, labels):
with tf.GradientTape() as tape:
predictions = model(images, training=True) #here I get the error
# start training
for epoch in range(EPOCHS):
train_loss.reset_states()
train_accuracy.reset_states()
valid_loss.reset_states()
valid_accuracy.reset_states()
step = 0
for images, labels in training_set:
step += 1
train_step(images,labels)
Upvotes: 1
Views: 337
Reputation: 2647
Keras models expect batches of instances as input. You are feeding images one by one. If you want to train a model I recommend you batching the dataset. You can do it as follows:
dataset, dataset_info = tfds.load('oxford_flowers102', with_info=True, as_supervised=True)
dataset_info
def resize_im(im, label):
return tf.image.resize(im, [224, 224]), label
test_set, training_set, validation_set = dataset['test'], dataset['train'], dataset['validation']
training_set = training_set.map(resize_im)
test_set = test_set.map(resize_im)
validation_set = validation_set.map(resize_im)
training_set = training_set.batch(32)
test_set = test_set.batch(32)
validation_set = validation_set.batch(32)
# Then feed the images to the model
for images, labels in training_set:
train_step(images, labels)
Reference: https://www.tensorflow.org/tutorials/load_data/images
Upvotes: 0
Reputation: 69
The shape of input is [none, width, height, channels], which are incomnpatible with your [500, 667, 3] apparently.
In the block of "start training", you are trying to use train_step for each image and label. Note that :
for images, labels in training_set:
pass
indeed, you get image other than images:
for image, label in training_set:
pass
You'd better use multiple images and labels for training, if you realy want use one image for each epoch, just reshape the image and the label.
For example, [500, 667, 3] to [1, 500, 667, 3] if you want use one image for a epoch.
Upvotes: 1