我正在通过《Python 深度学习》一书学习 Tensorflow / Keras。第 8 章解释了如何使用预训练模型。但是,提供的代码无法运行,并且在执行时收到错误消息
model.fit
:
TypeError: Cannot serialize object Ellipsis of type <class 'ellipsis'>.
To be serializable, a class must implement the 'get_config()' method.
我使用的是 Tensorflow 版本 2.15.0
该程序使用来自 kaggle 的 dogs-vs-cats 数据集。它创建一个较小的子集并创建训练、验证和测试数据集。这一切都有效,就像本书中其他一些示例所使用的那样。然后,它使用预训练的 VGG16 模型并训练与其连接的密集层
这是我的代码:
import tensorflow as tf
from tensorflow import keras
#upload kaggle.json file with the kaggle API Token
from google.colab import files
files.upload()
!mkdir ~/.kaggle
!cp kaggle.json ~/.kaggle
!chmod 600 ~/.kaggle/kaggle.json
!unzip -qq dogs-vs-cats.zip
!unzip -qq train.zip
import os, shutil, pathlib
original_dir = pathlib.Path("train")
new_base_dir = pathlib.Path("dogs-vs-cats_small")
def make_subset(subset_name, start_index, end_index):
for category in ("cat", "dog"):
dir = new_base_dir / subset_name / category
os.makedirs(dir)
fnames = [f"{category}.{i}.jpg" for i in range(start_index, end_index)]
for fname in fnames:
shutil.copyfile(src=original_dir / fname, dst=dir / fname)
make_subset("train", start_index=0, end_index=1000)
make_subset("validation", start_index=1000, end_index=1500)
make_subset("test", start_index=1500, end_index=2500)
import pathlib
base_dir = pathlib.Path("dogs-vs-cats_small")
train_dataset = keras.utils.image_dataset_from_directory(
base_dir / "train",
image_size=(180, 180),
batch_size=32
)
validation_dataset = keras.utils.image_dataset_from_directory(
base_dir / "validation",
image_size=(180, 180),
batch_size=32
)
test_dataset = keras.utils.image_dataset_from_directory(
base_dir / "test",
image_size=(180, 180),
batch_size=32
)
#create neural network
conv_base = keras.applications.vgg16.VGG16(
weights="imagenet",
include_top=False
)
conv_base.trainable = False
data_augmentation = keras.Sequential(
[
keras.layers.RandomFlip("horizontal"),
keras.layers.RandomRotation(0.1),
keras.layers.RandomZoom(0.2)
]
)
inputs = keras.Input(shape=(180, 180, 3))
x = data_augmentation(inputs)
x = keras.applications.vgg16.preprocess_input(x)
x = conv_base(x)
x = keras.layers.Flatten()(x)
x = keras.layers.Dense(256)(x)
x = keras.layers.Dropout(0.5)(x)
outputs = keras.layers.Dense(1, activation="sigmoid")(x)
model = keras.Model(inputs, outputs)
model.compile(
loss="binary_crossentropy",
optimizer="rmsprop",
metrics=["accuracy"]
)
callbacks = [
keras.callbacks.ModelCheckpoint(
filepath="features_extraction_with_data_augmentation.keras",
save_best_only=True,
monitor="val_loss"
)
]
history = model.fit( # error thrown here
train_dataset,
epochs=50,
validation_data=validation_dataset,
callbacks=callbacks
)
我相信功能模型(与顺序模型不同)无法保存模型的
keras.applications.vgg16.preprocess_input
部分(对我来说看起来像一个错误)。保存尝试发生在 ModelCheckpoint
回调中。
对我来说(Apple Silicon、MacOS Sonoma 14.2.1、带有tensorflow-metal 1.1.0的TF 2.15)使用VGG16预处理步骤的自定义实现是有效的:
def preprocess_input(imgs):
return tf.reverse(imgs, axis=[-1]) - tf.constant([103.939, 116.779, 123.68], dtype=tf.float32)
这可以用来代替
keras.applications.vgg16.preprocess_input
,它执行相同的转换,但可以成功序列化。