英文:
Using a custom parameter in train_step() method of a VAE, which is different for each epoch
问题
我正在尝试构建一个类似于这里的VAE示例:https://keras.io/examples/generative/vae/
但是,我在模型中使用了自定义损失,我希望这个损失可以乘以一个随着迭代次数增加而增加的因子。我在开始时这样定义了:
def __init__(self, encoder, decoder, **kwargs):
self.eloss_weight = tf.Variable(initial_value=args.eloss_weight, trainable=False)
编译模型以运行eagerly:
vae.compile(optimizer=tf.keras.optimizers.Adam(jit_compile=False), run_eagerly=True)
在拟合模型时,我使用了一个回调来改变能量损失权重的值,类似于这样:
def eloss_weight_increase(epoch, logs):
vae.eloss_weight = vae.eloss_weight + 1
increase_eloss_weight = tf.keras.callbacks.LambdaCallback(on_epoch_end=eloss_weight_increase)
vae.fit(
X_train, V_train, batch_size=args.batch_size, epochs=args.epochs,
callbacks=[increase_eloss_weight], verbose=1,)
我不得不使用run_eagerly
,因为如果不使用它,在train_step
中,当参数被称为self.eloss_weight
时,它不会检查它是否已更改或不变(我猜为了优化模型尽可能快地运行,当test_step
被编译时,它只记住了确切的值,并停止将其视为变量)。然而,由于run_eagerly
,现在运行速度慢了4倍(这相当糟糕,之前模型训练需要4.5小时,现在几乎需要一天)。有没有办法在不使用run_eagerly=True
的情况下完成这个任务?
非常感谢。
英文:
I am trying to build a VAE, similar to the example here: https://keras.io/examples/generative/vae/
However, I am employing a custom loss in the model and I would like this loss to be multiplied by a factor that increases with progressing epochs. I did it by defining at the beginning
def __init__(self, encoder, decoder, **kwargs):
self.eloss_weight = tf.Variable(initial_value=args.eloss_weight, trainable=False)
compiled the model to run eagerly
vae.compile(optimizer=tf.keras.optimizers.Adam(jit_compile=False), run_eagerly=True)
and when fitting I change the value of the energy loss weight using a callback like this
def eloss_weight_increase(epoch, logs):
vae.eloss_weight = vae.eloss_weight + 1
increase_eloss_weight = tf.keras.callbacks.LambdaCallback(on_epoch_end=eloss_weight_increase)
vae.fit(
X_train, V_train, batch_size=args.batch_size, epochs=args.epochs,
callbacks=[increase_eloss_weight], verbose=1,)
I had to use run_eagerly, because if I did not, in train_step, when the parameter was called as self.eloss_weight, it did not look if it was changed or not (I guess in order optimize the model to be as fast as possible, when test_step was compiled, it just remembered the exact value and stopped thinking of it as a variable). However, because of run_eagerly it now runs 4 times slower (which is pretty bad, before this, the model took 4.5 hours to train, now it is almost a day). Is there any way to do this thing without using run_eagerly=True?
Thank you very much.
答案1
得分: 1
vae.eloss_weight = vae.eloss_weight + 1
用一个 Tensor
覆盖了一个 Variable
(不一样)。您应该使用变量的 assign
方法来保持 Variable
对象不变:
vae.eloss_weight.assign(vae.eloss_weight + 1.)
或者
vae.eloss_weight.assign_add(1.)
我以前自己使用过这个方法,所以应该可以工作(而且不需要启用 eager execution)。
英文:
vae.eloss_weight = vae.eloss_weight + 1
overwrites a Variable
by a Tensor
(not the same). You should use a variable's assign
method to keep the Variable
object intact:
vae.eloss_weight.assign(vae.eloss_weight + 1.)
or
vae.eloss_weight.assign_add(1.)
I have used this myself before, so it should work (also without eager execution).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论