0

我正在关注有关在 Keras 上实现 EfficientNet 的教程:

张量流

我正在使用自己的数据集,因此必须手动加载它。出于某种原因,批量大小包含在张量形状中,并且会引发错误。

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)

我不断收到错误消息:

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

前面的 32 显然是批量大小。但我不知道为什么这是形状并且无法弄清楚它是否匹配。

4

1 回答 1

1

正如@Frightera 评论的那样,tf.keras.utils.image_dataset_from_directory 返回 4Dimension 的图像形状。

示例代码

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)

输出

(7, 180, 180, 3)
(7,)
于 2021-10-19T11:36:45.663 回答