tf.gradients() 返回 [None]

时间:2021-03-05 19:59:32

标签: python tensorflow keras generative-adversarial-network generative

抱歉,这听起来像是重复。我已经解决了所有相关问题,但没有找到适合我的问题上下文的解决方案。

我正在尝试构建一个生成模型,该模型输出每个跟踪的 COVID 日的概率,以输入到基于 SEIR 的流行病学模型中。

这一代有效。但是,我无法弄清楚如何训练模型。我必须编写一个自定义损失函数,该函数通过流行病学模型的阶跃函数运行每日参数,并将填充每天“已确认”和“已删除”的数据集。然后,我将该数据与 GitHub 上 John Hopkin's COVID dataset 记录的“已确认”和“已删除”进行比较。

我使用平均绝对误差根据生成的概率和来自 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_valuegenerator.trainable_weights 按预期填充。

编辑:更新了代码以反映 Myrl Marmarelis 的建议和 TensorFlow's custom training loop guide 的架构。仍然存在梯度是 None 列表的相同问题。

1 个答案:

答案 0 :(得分:0)

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

我还建议将您的训练过程包装在 tf.Tensor 中,以便 Tensorflow 可以将其编译为静态图。

相关问题