类型错误:无法序列化类型为 <class 'ellipsis'>

问题描述 投票:0回答:1

我正在通过《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
)
python tensorflow machine-learning keras neural-network
1个回答
0
投票

我相信功能模型(与顺序模型不同)无法保存模型的

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
,它执行相同的转换,但可以成功序列化。

© www.soinside.com 2019 - 2024. All rights reserved.