tf.gradients() 返回 [None] 的列表

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

我正在尝试构建一个生成模型,输出跟踪的每一天新冠病毒的概率,并将其输入到基于 SEIR 的流行病学模型中。

这一代人在工作。但是,我不知道如何训练模型。我必须编写一个自定义损失函数,该函数通过流行病学模型的步骤函数运行每日参数,并将填充每天的“确认”和“删除”数据集。然后,我将该数据与 GitHub 上的 John Hopkin 的 COVID 数据集 中记录的“已确认”和“已删除”数据进行比较。

我使用平均绝对误差根据生成的概率和 JHU 数据集中的实际值来计算“已确认”和“已删除”之间的损失。我遇到的问题是,当我调用

the tf.gradient()
函数时,它返回一个
None
列表。我被困在这里,我们将不胜感激任何帮助。

这是我正在使用的代码:

训练步骤

# Define function to train the model based on one input
loss_fn = MeanAbsoluteError()
optimizer = Adam(learning_rate=0.005)

@tf.function
def train_step(x, y):

  y_pred = np.zeros((3, latent_dim))

  N = tf.constant(int(7_000_000_000), dtype=tf.float64)
  E0 = tf.Variable(int(1000), trainable=False, dtype=tf.float64)
  I0 = tf.Variable(covid_df.iloc[0]["Confirmed"], trainable=False, dtype=tf.float64)
  R0 = tf.Variable(covid_df.iloc[0]["Removed"], trainable=False, dtype=tf.float64)
  S0 = tf.Variable(N - E0 - I0 - R0, trainable=False, dtype=tf.float64)
  u0 = tf.Variable(0, trainable=False, dtype=tf.float64)

  SuEIRs = tf.stack([S0,u0,E0,I0,R0])

  with tf.GradientTape() as tape:
    logits = generator(tf.reshape(x, (batch_size, 4, latent_dim)), training=True)

    betas = logits[0][0]
    sigmas = logits[0][1]
    mus = logits[0][2]
    gammas = logits[0][3]

    for t in range(latent_dim):
      SuEIR_diffs = SuEIR_step(SuEIRs, t, N, betas, sigmas, mus, gammas)

      SuEIRs = SuEIRs + SuEIR_diffs

      confirmed = SuEIRs[3]
      removed = SuEIRs[4]

      # update y_pred
      y_pred[0,t] = float(t+1)
      y_pred[1,t] = confirmed.numpy()
      y_pred[2,t] = removed.numpy()

    # Convert predictions
    y_pred = tf.convert_to_tensor(y_pred)

    # Calculate loss
    loss_value = loss_fn(y[1], y_pred[1]) + loss_fn(y[2], y_pred[2])

  # Calculate the gradient
  grads = tape.gradient(loss_value, generator.trainable_weights)

  print(grads) ##==>> outputs [None, None, None, None]

  # Apply gradients to model
  optimizer.apply_gradients(zip(grads, generator.trainable_weights))
  return loss_value

训练循环

import time

epochs = 2
for epoch in range(epochs):
  print("\nStart of epoch %d" % (epoch,))
  start_time = time.time()

  # Iterate over the batches of the dataset.
  for step in range(sample_size):
    loss_value = train_step(x_input[step], y_true)

    # Log every 5 batches.
    if step % 5 == 0:
      print(
        "Training loss (for one batch) at step %d: %.4f"
        % (step, float(loss_value))
      )
    print("Time taken: %.2fs" % (time.time() - start_time))

错误输出

ValueError: No gradients provided for any variable: ['dense/kernel:0', 'dense/bias:0', 'dense_1/kernel:0', 'dense_1/bias:0'].

loss_value
generator.trainable_weights
按预期填充。

编辑:更新了代码以反映 Myrl Marmarelis 的建议和 TensorFlow 的自定义训练循环指南的架构。仍然存在同样的问题,即渐变是

None
的列表。

python tensorflow keras generative-adversarial-network
1个回答
0
投票

在将损失(尤其是

np.array(...)
)计算为
y_pred
之前,尝试将调用更改为
tf.convert_to_tensor(...)
。您需要通过将所有内容保留为
tf.Tensor
来构建正确的符号图。事实上,请确保您没有将模型参数和损失之间的计算链中的任何内容转换为非张量。

我还建议将你的训练过程包装在

@tf.function
中,以便 Tensorflow 可以将其编译成静态图。

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