如何使用 tf.keras.preprocessing.image_dataset_from_directory() 创建具有特定形状的数据集?

How do I use tf.keras.preprocessing.image_dataset_from_directory() to create a dataset with a certain shape?

我有一个包含大约 3500 张图像的数据集,分为 3 个文件夹,我从我的 google 驱动器加载到 Google Collab,我正试图将它们变成 ML 算法通过以下代码使用 keras 和 tensorflow:

train = tf.keras.preprocessing.image_dataset_from_directory(
  path,
  labels = "inferred",
  label_mode = "categorical",
  color_mode = "rgb",
  batch_size = 32,
  image_size = (140,140),
  seed = 1234,
  subset = "training",
  validation_split = 0.2
  
)

shape = tf.TensorShape([None,140,140,3])
print(shape)


valid = tf.keras.preprocessing.image_dataset_from_directory(
  path,
  labels = "inferred",
  label_mode = "categorical",
  color_mode = "rgb",
  batch_size = 32,
  image_size = (140,140),
  seed = 1234,
  subset = "validation",
  validation_split = 0.2
)

print(train)
print(valid)


print(tf.keras.utils.image_dataset_from_directory(path, labels='inferred'))
from keras.models import Sequential
from keras.layers import Dense
from tensorflow import keras
#from tensorflow.keras import layers

model = Sequential()
model.add(Dense(256, activation = "softmax", input_shape = (140,140,3)))
model.add(Dense(64, activation = "softmax"))
model.add(Dense(32, activation = "softmax"))
#model.add(Dense(3, activation = "softmax"))
model.compile(loss = 'categorical_crossentropy', optimizer = 'adam', metrics = ['accuracy']) 

print(model.summary())
keras.utils.plot_model(model, "my_first_model_with_shape_info.png", show_shapes=True)
#print(tf.keras.utils.plot_model(model))
model.fit(train, validation_data = valid, epochs = 50, batch_size = 32)

然而,当我 运行 代码时,我得到了这个错误:

ValueError: Shapes (None, 3) and (None, 140, 140, 32) are incompatible

我尝试通过将 (None,140,​​140,​​3) 形状添加到“train”变量来解决此问题,但我不确定该怎么做,所以有人知道如何制作该形状我的“火车”和“有效”变量与我制作的模型兼容?谢谢。

作为参考,这是火车变量:

train = tf.keras.preprocessing.image_dataset_from_directory(
  path,
  labels = "inferred",
  label_mode = "categorical",
  color_mode = "rgb",
  batch_size = 32,
  image_size = (140,140),
  seed = 1234,
  subset = "training",
  validation_split = 0.2
)

然而,当我打印“train”时,我得到了这个

<BatchDataset element_spec=(TensorSpec(shape=(None, 140, 140, 3), dtype=tf.float32, name=None), TensorSpec(shape=(None, 3), dtype=tf.float32, name=None))>

那么谁也可以解释一下什么是 BatchDataset 元素,以及我如何首先编辑它的形状?谢谢。

最后一层的神经元数量不应与您要分类的 类 数量相同(如果您尝试对 3 种花进行分类而不是 32 种,则应为 3)。添加了一些卷积层和池化层以提高性能。

import tensorflow as tf
from tensorflow.keras import layers
import pathlib
dataset_url = "https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz"
data_dir = tf.keras.utils.get_file('flower_photos', origin=dataset_url, untar=True)
path = pathlib.Path(data_dir)
train = tf.keras.preprocessing.image_dataset_from_directory(
  path,
  labels = "inferred",
  label_mode = "categorical",
  color_mode = "rgb",
  batch_size = 32,
  image_size = (140,140),
  seed = 1234,
  subset = "training",
  validation_split = 0.2
  
)

shape = tf.TensorShape([None,140,140,3])
print(shape)


valid = tf.keras.preprocessing.image_dataset_from_directory(
  path,
  labels = "inferred",
  label_mode = "categorical",
  color_mode = "rgb",
  batch_size = 32,
  image_size = (140,140),
  seed = 1234,
  subset = "validation",
  validation_split = 0.2
)
classnames = train.class_names
print(classnames)
print(train)
print(valid)
num_classes = len(classnames)

print(tf.keras.utils.image_dataset_from_directory(path, labels='inferred'))
from keras.models import Sequential
from keras.layers import Dense
from tensorflow import keras
#from tensorflow.keras import layers

model = Sequential([
  layers.Rescaling(1./255, input_shape=(140,140, 3)),
  layers.Conv2D(16, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(32, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(64, 3, padding='same', activation='relu'),
  layers.MaxPooling2D(),
  layers.Flatten(),
  layers.Dense(128, activation='relu'),
  layers.Dense(num_classes) // in your case layers.Dense(3)
])
model.compile(loss = tf.keras.losses.CategoricalCrossentropy(),optimizer = 'adam', metrics = ['accuracy']) 

print(model.summary())
keras.utils.plot_model(model, "my_first_model_with_shape_info.png", show_shapes=True)

#print(tf.keras.utils.plot_model(model))
model.fit(train, validation_data = valid, epochs = 50, batch_size = 32)