在 TensorFlow 1.15 的自定义训练循环中将张量转换为 numpy 数组

Converting a tensor to a a numpy array inside custom training loop in TensorFlow 1.15

我正在 TensorFlow 中训练模型,我想在每批次后打印模型的损失。我正在使用看起来像

的自定义训练循环
import tensorflow as tf
from tensorflow.keras.losses import cosine_similarity
from tensorflow.keras.optimizers import Adam


model = get_model(**model_params)
g = get_generator(**generator_params)

optimizer = Adam()
epochs = 10

for epoch in range(epochs):
   for i in range(len(g)):
      with tf.GradientTape() as tape:
         x,y = g[i]
         model_prediction = model(x)
         loss = cosine_similarity(y, model_prediction)
         gradients = tape.gradient(loss, model.trainable_weights)
         optimizer.apply_gradients(zip(gradients, model.trainable_weights))
         
         print(f"Batch {i}/{len(g)}. Loss: {loss.eval(session=tf.Session()): .4f}")

因为损失是一个张量,为了能够实际看到我需要将其转换为 NumPy 数组的值(计划不是打印数组,但是一旦我可以将张量转换为数组,那解决了我的问题)。 不幸的是,我一直在尝试的方式导致了以下错误

Failed precondition: Error while reading resource variable dense_5/kernel from Container: localhost. 
This could mean that the variable was uninitialized. Not found: Container localhost does not exist.`

我也尝试通过添加

来编辑循环

for epoch in range(epochs):
   for i in range(len(g)):
      with tf.GradientTape() as tape, tf.Session() as session:
         # training code
         loss_numpy = session.run(loss)

这给了我与上面相同的错误,并且还尝试在每个训练步骤初始化全局变量


for epoch in range(epochs):
   for i in range(len(g)):
      with tf.GradientTape() as tape, tf.Session() as session:
         # training code
         init = tf.global_variables_initializer()
         session.run(init)
         print(f"Batch {i}/{len(g)}. Loss: {session.run(loss): .4f}")

它不会引发错误,但速度很慢,并且会输出很多其他我想避免的与 Nvidia 相关的内容。

有没有办法避免这个错误,又不用每一步都初始化变量。或者也许有一种方法可以使与 Nvidia 相关的输出静音。

查看代码和错误,我的猜测是您没有根据 Keras 需要和使用的 TensorFlow 会话正确处理范围。

一个选项是它没有被正确初始化。这是可能的,因为您没有使用处理该问题的香草 Keras 培训制度。或者它可能会中途结束,然后,因为您正在使用 with 运算符,当 with 内的块完成时,会话将关闭。这就是 with 在 Python.

中的作用

我自己还没有尝试过,但我的直觉是,如果您在开始搞乱训练之前自己实例化一个会话,然后在整个过程中保持该会话,这应该可行。

顺便说一下,您实际上不需要将损失转换为 NumPy 对象来打印或检查它。如果您直接使用 TensorFlow 进行数学计算并避免进行转换,您可能会更轻松(在速度和稳定性方面)。