简体   繁体   中英

Incorrect Shape in Tensorflow Neural Network - Batch size in shape

I'm following this tutorial on implementing EfficientNet on Keras.:

Tensorflow

I am using my own dataset and so had to load it manually. For some reason the batch size is being included in the tensor shape and it is throwing an error.

from tensorflow.keras.models import Sequential
from tensorflow.keras import layers
from tensorflow.keras.layers import Dense, Dropout, GlobalMaxPooling2D, Input
from tensorflow.keras import optimizers
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.applications import EfficientNetB0
import tensorflow as tf
import os, os.path
import glob
import shutil
import sys
import matplotlib.pyplot as plt

sys.path.insert(1, './efficientnet_keras_transfer_learning')


# Options: EfficientNetB0, EfficientNetB1, EfficientNetB2, EfficientNetB3 to B7
# Higher the number, the more complex the model is.
# EfficientNetB0, EfficientNetB1, EfficientNetB2, EfficientNetB3
# loading pretrained conv base model
# define input height and width

### This changes model weights name ###
model_type = 'B0'

if model_type == 'B0':
    height, width = 224, 224
elif model_type == 'B1':
    height, width = 240, 240
elif model_type == 'B2':
    height, width = 260, 260
elif model_type == 'B3':
    height, width = 300, 300
elif model_type == 'B4':
    height, width = 380, 380
elif model_type == 'B5':
    height, width = 456, 456
elif model_type == 'B6':
    height, width = 528, 528
elif model_type == 'B7':
    height, width = 600, 600

# input_shape = (height, width, 3)

# ### Change Model Type ###
# conv_base = EfficientNetB0(
#     include_top=True,
#     weights=None,
#     classes=3
#     # input_shape=input_shape,
# )

filepath = (os.path.expanduser(
    '~') + '\dataset')

# Prepare Data
train_dir = filepath + '\Train'
test_dir = filepath + '\Test'
val_dir = filepath + '\Val'

batch_size = 32

train_ds = tf.keras.utils.image_dataset_from_directory(
    train_dir,
    labels='inferred',
    seed=42,
    image_size=(height, width),
    batch_size=batch_size
    )

val_ds = tf.keras.utils.image_dataset_from_directory(
    val_dir,
    labels='inferred',
    seed=42,
    image_size=(height, width),
    batch_size=batch_size
    )

class_names = train_ds.class_names
num_classes = len(class_names)
print('There are ' + str(num_classes) + ' classes:\n' + str(class_names))


train_ds = train_ds.map(lambda image, label: (tf.image.resize(image, (height, width)), label))
val_ds = val_ds.map(lambda image, label: (tf.image.resize(image, (height, width)), label))

# plt.figure(figsize=(10, 10))
# for images, labels in train_ds.take(1):
#   for i in range(9):
#     ax = plt.subplot(3, 3, i + 1)
#     plt.imshow(images[i].numpy().astype("uint8"))
#     plt.title(class_names[labels[i]])
#     plt.axis("off")


img_augmentation = Sequential(
    # [
        # layers.RandomRotation(factor=0.15),
        # layers.RandomTranslation(height_factor=0.1, width_factor=0.1),
        # layers.RandomFlip(),
        # layers.RandomContrast(factor=0.1),
    # ],
    name="img_augmentation",
)


# One-hot / categorical encoding
def input_preprocess(image, label):
    label = tf.one_hot(label, num_classes)
    return image, label

train_ds = train_ds.map(
    input_preprocess, num_parallel_calls=tf.data.AUTOTUNE)
train_ds = train_ds.batch(batch_size=batch_size, drop_remainder=True)
train_ds = train_ds.prefetch(tf.data.AUTOTUNE)

val_ds = val_ds.map(input_preprocess)
val_ds = val_ds.batch(batch_size=batch_size, drop_remainder=True)

inputs = Input(shape=(height, width, 3))
x = img_augmentation(inputs)
outputs = EfficientNetB0(include_top=True, weights=None, classes=num_classes)(x)


model = tf.keras.Model(inputs, outputs)
model.compile(
    optimizer="adam", loss="categorical_crossentropy", metrics=["accuracy"]
)

model.summary()

epochs = 50
hist = model.fit(train_ds, epochs=epochs, validation_data=val_ds, verbose=2)

I keep getting an error:

    ValueError: Input 0 is incompatible with layer model_4: expected shape=(None, 224, 224, 3), found shape=(32, None, 224, 224, 3)

The 32 in the front is obviously the batch size. But I don't know why this is in the shape and can't figure out to get it to match.

As commented by @Frightera, tf.keras.utils.image_dataset_from_directory returns image shape of 4Dimension.

Sample code

import pathlib
data_dir = pathlib.Path('/content/images/images')

import tensorflow as tf
batch_size = 16
img_height = 180
img_width = 180
train_ds = tf.keras.preprocessing.image_dataset_from_directory(
  data_dir,
  validation_split=0.2,
  subset="training",
  seed=123,
  image_size=(img_height, img_width),
  batch_size=batch_size)

for image_batch, labels_batch in train_ds:
  print(image_batch.shape)
  print(labels_batch.shape)

Output

(7, 180, 180, 3)
(7,)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM