为了账号安全,请及时绑定邮箱和手机立即绑定

更改 Keras 模型变量

更改 Keras 模型变量

明月笑刀无情 2023-06-27 14:10:28
我想逐渐增加 Keras 模型中用于计算损失的系数。变量值基于当前纪元。但是,当我想设置该值时,出现以下错误:float object has no attribute dtype我的代码:def warm_up(epoch, logs):    new_value=  tf.keras.backend.variable(np.array(1.0, dtype=np.float32), dtype=tf.float32)    tf.keras.backend.set_value(model.variable1, new_value)callback = tf.keras.callbacks.LambdaCallback(on_epoch_begin=warm_up)model.fit(..., callbacks = [callback])如何在训练期间更改自定义 Keras 模型中的变量?我使用的是 Tensorflow 2.2。追溯:\Anaconda3\lib\site-packages\tensorflow\python\keras\engine\training.py in _method_wrapper(self, *args, **kwargs)     64   def _method_wrapper(self, *args, **kwargs):     65     if not self._in_multi_worker_mode():  # pylint: disable=protected-access---> 66       return method(self, *args, **kwargs)     67      68     # Running inside `run_distribute_coordinator` already.~\Anaconda3\lib\site-packages\tensorflow\python\keras\engine\training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq, max_queue_size, workers, use_multiprocessing)    836       for epoch, iterator in data_handler.enumerate_epochs():    837         self.reset_metrics()--> 838         callbacks.on_epoch_begin(epoch)    839         with data_handler.catch_stop_iteration():    840           for step in data_handler.steps():~\Anaconda3\lib\site-packages\tensorflow\python\keras\callbacks.py in on_epoch_begin(self, epoch, logs)    347     logs = self._process_logs(logs)    348     for callback in self.callbacks:--> 349       callback.on_epoch_begin(epoch, logs)    350     self._reset_batch_timing()    351 c:\Users\..\training.py in warm_up(epoch, logs)    379 def warm_up(epoch, logs):    380     test =  tf.keras.backend.variable(np.array(1.0, dtype=np.float32), dtype=tf.float32)--> 381     tf.keras.backend.set_value(model.variable1, test)    382     383 
查看完整描述

2 回答

?
FFIVE

TA贡献1797条经验 获得超6个赞

当我首先初始化模型并将其作为额外参数添加到回调方法时,它会起作用。所以解决办法如下:


class LossCallback(tf.keras.callbacks.Callback):

    def __init__(self, model):

        super(LossCallback, self).__init__()

        model.beta_x = tf.Variable(1.0, trainable=False, name='weight1', dtype=tf.float32)


    def on_epoch_begin(self, epoch, logs=None):

        tf.keras.backend.set_value(self.model.beta_x, tf.constant(0.5) * epoch)


    def on_epoch_end(self, epoch, logs=None):

        logs = logs or {}

        logs['beta_x'] = tf.keras.backend.get_value(self.model.beta_x)


model = create_model() # initialize custom keras model

callback = LossCallback(model)


model.fit(..., callbacks=[callback])


查看完整回答
反对 回复 2023-06-27
?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

避免直接编辑变量。您必须像这样访问 keras 变量


import tensorflow as tf

from tensorflow import keras

import numpy as np


def warm_up(epoch, logs):

    val = keras.backend.get_value(model.optimizer.lr)

    val *= 1.1

    tf.keras.backend.set_value(model.optimizer.lr, val)

    


callback = tf.keras.callbacks.LambdaCallback(on_epoch_begin=warm_up)


model = tf.keras.models.Sequential([

    keras.layers.Dense(10, 'relu'),

    keras.layers.Dense(1, 'sigmoid')

])


model.compile(loss='binary_crossentropy')


X_train = tf.random.uniform((10,10))

y_train = tf.ones((10,))

model.fit(X_train, y_train, 

          callbacks = [callback])

请注意我如何获取当前值,例如val = keras.backend.get_value(model.optimizer.lr)。这是在运行时获取正确值的正确方法。另外,不要在循环内使用或声明新变量。您可能可以new_value通过阅读和更改旧的内容来获得新的内容。另外,请避免在回调内部使用除 Tensorflow 之外的任何其他库,尤其是当您的回调经常被调用时。不要使用numpy,使用tensorflow。实际上总有一种张量流操作可以满足您的需要。


编辑:如果您有一些自定义值要更新,您可以使用如下模式:


class LossCallback(tf.keras.callbacks.Callback):

    def __init__(self):

        super(LossCallback, self).__init__()

        self.someValue = tf.Variable(1.0, trainable=False, name='weight1', dtype=tf.float32)


    def on_epoch_end(self, epoch, logs=None):

        tf.keras.backend.set_value(self.model.loss.someValue, self.someValue * epoch)

或者您仍然可以尝试使用 lambda 回调。

从回调中,您可以访问模型的任何变量。像这样self.model.someVariable。您还可以访问模型自定义__init__函数中定义的任何自定义变量,如下所示:


#in model's custom __init__

def __init__(self, someArgs):

    ...

    self.someArg = someArgs

    ...


#in callback's "on_epoch_..." method

    ...

    keras.backend.set_value(self.model.someArg, 42)

    ...


请注意,您不能self.model在回调__init____init__函数中使用,因为调用回调时模型仍未初始化。


这有帮助吗?


查看完整回答
反对 回复 2023-06-27
  • 2 回答
  • 0 关注
  • 205 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信