【问题标题】:tf.gradients() returns a list of [None]tf.gradients() 返回 [None] 的列表
【发布时间】:2021-06-04 12:13:08
【问题描述】:

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

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

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

我使用平均绝对误差根据生成的概率和 JHU 数据集中的实际值来计算“已确认”和“已删除”之间的损失。我遇到的问题是当我调用the tf.gradient() 函数时,它会返回Nones 的列表。我被困在这里,任何帮助将不胜感激。

这是我正在使用的代码:

训练步骤

# 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 的列表。

【问题讨论】:

  • 检查你的损失函数是否可微。
  • 损失函数是 tf.MeanAbsoluteError() 所以它应该是可微的

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


【解决方案1】:

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

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

【讨论】:

  • 我尝试了您的建议并更新了我的问题中的代码以反映更改。但是,问题仍然存在。不过,谢谢你的回答。在研究@tf.function 时,这是一个非常有见地的兔子洞
猜你喜欢
  • 2021-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-14
  • 2017-03-08
相关资源
最近更新 更多