训练我的模型后,可以保存KERAS模型

发布于 2025-02-03 20:55:59 字数 1865 浏览 3 评论 0原文

我正在遵循keras.io的代码示例,内容涉及无关注的视觉变压器在这里。我想在完成培训后将其保存在tensorflow/keras中,但会产生错误。下面给出了我的模型代码的最后一部分,

# Get the total number of steps for training.
total_steps = int((len(x_train) / config.batch_size) * config.epochs)

# Calculate the number of steps for warmup.
warmup_epoch_percentage = 0.15
warmup_steps = int(total_steps * warmup_epoch_percentage)

# Initialize the warmupcosine schedule.
scheduled_lrs = WarmUpCosine(
lr_start=1e-5, lr_max=1e-3, warmup_steps=warmup_steps, total_steps=total_steps,
)

# Get the optimizer.
optimizer = tfa.optimizers.AdamW(
learning_rate=scheduled_lrs, weight_decay=config.weight_decay
)

# Compile and pretrain the model.
model.compile(
optimizer=optimizer,
loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=[
    keras.metrics.SparseCategoricalAccuracy(name="accuracy"),
    keras.metrics.SparseTopKCategoricalAccuracy(5, name="top-5-accuracy"),
],
)

# Train the model
history = model.fit(
train_ds,
epochs=config.epochs,
validation_data=val_ds,
callbacks=[
    keras.callbacks.EarlyStopping(monitor="val_accuracy", patience=5, mode="auto",)
],
)

# Evaluate the model with the test dataset.
print("TESTING")
loss, acc_top1, acc_top5 = model.evaluate(test_ds)
print(f"Loss: {loss:0.2f}")
print(f"Top 1 test accuracy: {acc_top1*100:0.2f}%")
print(f"Top 5 test accuracy: {acc_top5*100:0.2f}%")

我尝试了下面的两种方法来保存模型

model.save('/content/drive/MyDrive/VIT-SHIFT') 

history.save('/content/drive/MyDrive/VIT-SHIFT')

但它说模型和历史记录尚未定义。完整代码可在 nofollow Noreferrer“

I'm following a code example from keras.io about A Vision Transformer without Attention, here. I want to save it in the tensorflow/keras after completing training but it generates an error. The last part of my model code is given below

# Get the total number of steps for training.
total_steps = int((len(x_train) / config.batch_size) * config.epochs)

# Calculate the number of steps for warmup.
warmup_epoch_percentage = 0.15
warmup_steps = int(total_steps * warmup_epoch_percentage)

# Initialize the warmupcosine schedule.
scheduled_lrs = WarmUpCosine(
lr_start=1e-5, lr_max=1e-3, warmup_steps=warmup_steps, total_steps=total_steps,
)

# Get the optimizer.
optimizer = tfa.optimizers.AdamW(
learning_rate=scheduled_lrs, weight_decay=config.weight_decay
)

# Compile and pretrain the model.
model.compile(
optimizer=optimizer,
loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=[
    keras.metrics.SparseCategoricalAccuracy(name="accuracy"),
    keras.metrics.SparseTopKCategoricalAccuracy(5, name="top-5-accuracy"),
],
)

# Train the model
history = model.fit(
train_ds,
epochs=config.epochs,
validation_data=val_ds,
callbacks=[
    keras.callbacks.EarlyStopping(monitor="val_accuracy", patience=5, mode="auto",)
],
)

# Evaluate the model with the test dataset.
print("TESTING")
loss, acc_top1, acc_top5 = model.evaluate(test_ds)
print(f"Loss: {loss:0.2f}")
print(f"Top 1 test accuracy: {acc_top1*100:0.2f}%")
print(f"Top 5 test accuracy: {acc_top5*100:0.2f}%")

I tried below two methods to save my model

model.save('/content/drive/MyDrive/VIT-SHIFT') 

and

history.save('/content/drive/MyDrive/VIT-SHIFT')

but it says model and history are not defined. Full code is available in this colab notebook

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花开雨落又逢春i 2025-02-10 20:55:59

如您有关同一代码的另一个问题所述,在这里,您可能需要实现呼叫>呼叫首先。现在,保存和重新加载模型应该很简单,但是我遇到了有关layers.randomcrop增强层的问题。

def get_augmentation_model():
    """Build the data augmentation model."""
    data_augmentation = keras.Sequential(
        [
            layers.Resizing(..),
            layers.RandomCrop(...), # <--- possible causes
            layers.RandomFlip("horizontal"),
            layers.Rescaling(1 / 255.0),
        ]
    )
    return data_augmentation

称为已删除的函数引用变量。这可能意味着创建了函数 - 本地变量,并且未在程序中其他地方引用。这通常是一个错误;考虑在第一个调用上存储变量在对象属性中。

尽管我看了看源代码,但没有任何可疑错误。因此,为了结束这一点,我实施了自定义的随机作物层,从理论上讲,这些层也是如此。但是,如果您坚持使用内置layers.randomcrop,那么我建议您在Github上开票有关此问题。


要使整个代码端到端培训和节省+重新加载,请按以下方式更改代码。首先,在shiftVitModel类中实现呼叫方法。

class ShiftViTModel(keras.Model):
    def __init__(self):
        super().__init__(**kwargs)
        ...
        # init params

    def get_config(self):
        ...
        return config

    def _calculate_loss(self, data, training=False):
        ...
        return total_loss, labels, logits

    def train_step(self, inputs):
        ...
        return {m.name: m.result() for m in self.metrics}

    def test_step(self, data):
        ...
        return {m.name: m.result() for m in self.metrics}
    
    # implement the call function
    def call(self, images):
        augmented_images = self.data_augmentation(images)
        x = self.patch_projection(augmented_images)
        logits = self.global_avg_pool(x)
        return logits

接下来,实现自定义的随机裁剪层,并按照以下方式使用它,而不是layers.randomcrop

class CustomRandomCrop(layers.Layer):
    def __init__(self, size, **kwargs):
        super().__init__(**kwargs)
        self.size = size
        
    def call(self, inputs, training=True):
        if training:
            outputs = tf.map_fn(lambda img: tf.image.random_crop(img,
                                               self.size), inputs)
        else:
            outputs = tf.image.resize(inputs, self.size[:-1])
        return outputs
            
    def get_config(self):
        config = super().get_config()
        config.update(
            {
                'size': self.size,
            }
        )
        return config
def get_augmentation_model():
    """Build the data augmentation model."""
    data_augmentation = keras.Sequential(
        [
            layers.Resizing(...),
            CustomRandomCrop(...), # custom random crop
            layers.RandomFlip("horizontal"),
            layers.Rescaling(1 / 255.0),
        ]
    )
    return data_augmentation

在这些更改之后,我们现在可以按以下方式执行任何错误。

x,y = next(iter(train_ds))
print(x.shape, y.shape)
model(x.shape) 
# OK

history = model.fit(
    x=x, y=y,
    epochs=1
) 
# OK

model.evaluate(x, y)
# OK

节省和重新加载工作。

model.save('/content/VIT-SHIFT')
# OK

new_model = tf.keras.models.load_model('/content/VIT-SHIFT')
# OK

np.testing.assert_allclose(
    model.predict(x), new_model.predict(x)
)
# OK

这是完整的工作 code noreferrer“> code-in-code-in-colab 。请保存文件,我可能有一天会从驱动器中删除文件。

最后,fyi,history.save('...'),您不能在keras中这样做。为了保存tensorflow/keras模型,请参阅 /a>文档。 历史记录对象将仅返回训练时间期间跟踪的指标和损失。例如,

history = model.fit(
    x=x, y=y,
    epochs=1
)

history.history

{'accuracy': [0.09765625],
 'loss': [6.204378128051758],
 'top-5-accuracy': [0.36328125]}

您可以从上面的字典中保存训练日志,也可以更好地使用 > 在培训期间。

As mentioned in your other question about the same code, HERE, you may need to implement the call method first. Now, saving and reloading the model should be straightforward but I've encountered an issue regarding a layers.RandomCrop augmentation layer that is used in the code.

def get_augmentation_model():
    """Build the data augmentation model."""
    data_augmentation = keras.Sequential(
        [
            layers.Resizing(..),
            layers.RandomCrop(...), # <--- possible causes
            layers.RandomFlip("horizontal"),
            layers.Rescaling(1 / 255.0),
        ]
    )
    return data_augmentation

Called a function referencing variables that have been deleted. This likely means that function-local variables were created and not referenced elsewhere in the program. This is generally a mistake; consider storing variables in an object attribute on the first call.

Though I looked over the source code but didn't feel any suspicious bug. So, to end this, I've implemented custom random crop layers which theoretically do the same. However, if you insist to use built-in layers.RandomCrop, then I would recommend opening a ticket on GitHub regarding this issue.


To make the whole code end-to-end training and saving+reloading, change the code as follows. First, implement the call method in the ShiftViTModel class.

class ShiftViTModel(keras.Model):
    def __init__(self):
        super().__init__(**kwargs)
        ...
        # init params

    def get_config(self):
        ...
        return config

    def _calculate_loss(self, data, training=False):
        ...
        return total_loss, labels, logits

    def train_step(self, inputs):
        ...
        return {m.name: m.result() for m in self.metrics}

    def test_step(self, data):
        ...
        return {m.name: m.result() for m in self.metrics}
    
    # implement the call function
    def call(self, images):
        augmented_images = self.data_augmentation(images)
        x = self.patch_projection(augmented_images)
        logits = self.global_avg_pool(x)
        return logits

Next, implement a custom random crop layer and use it as follows instead of layers.RandomCrop.

class CustomRandomCrop(layers.Layer):
    def __init__(self, size, **kwargs):
        super().__init__(**kwargs)
        self.size = size
        
    def call(self, inputs, training=True):
        if training:
            outputs = tf.map_fn(lambda img: tf.image.random_crop(img,
                                               self.size), inputs)
        else:
            outputs = tf.image.resize(inputs, self.size[:-1])
        return outputs
            
    def get_config(self):
        config = super().get_config()
        config.update(
            {
                'size': self.size,
            }
        )
        return config
def get_augmentation_model():
    """Build the data augmentation model."""
    data_augmentation = keras.Sequential(
        [
            layers.Resizing(...),
            CustomRandomCrop(...), # custom random crop
            layers.RandomFlip("horizontal"),
            layers.Rescaling(1 / 255.0),
        ]
    )
    return data_augmentation

After these changes, we can now do as follows without any error.

x,y = next(iter(train_ds))
print(x.shape, y.shape)
model(x.shape) 
# OK

history = model.fit(
    x=x, y=y,
    epochs=1
) 
# OK

model.evaluate(x, y)
# OK

Saving and reloading work as well.

model.save('/content/VIT-SHIFT')
# OK

new_model = tf.keras.models.load_model('/content/VIT-SHIFT')
# OK

np.testing.assert_allclose(
    model.predict(x), new_model.predict(x)
)
# OK

HERE is the complete working Code-in-Colab. Please save the file, I might erase the file from the drive someday.

Lastly, FYI, history.save('...'), you can't do that in keras. In order to save the tensorflow/keras model, please refer to this document. The history object will return only the tracked metrics and loss during training time. For example

history = model.fit(
    x=x, y=y,
    epochs=1
)

history.history

{'accuracy': [0.09765625],
 'loss': [6.204378128051758],
 'top-5-accuracy': [0.36328125]}

You can save the training logs from the above dictionary or better use the CSVLogger during training.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文