ValueError: No gradients provided for any variable in TensorFlow when building a GAN

ValueError: No gradients provided for any variable in TensorFlow when building a GAN

我正在尝试为大学作业构建 GAN。我的代码与 TF 网站 this tutorial 中的介绍示例非常相似。

以下是我认为代码的相关部分(如果需要可以提供更多细节,例如鉴别器模型是如何构建的)。给我错误的行是:

generator_optimizer.apply_gradients(zip(gradients_of_generator, generador.trainable_variables))

这可能与我生成器的层有关,因为它几乎是与 TF 示例代码的唯一区别..

def create_generator(max_len, vocab_size):
  model = tf.keras.Sequential()
  model.add(tf.keras.layers.Embedding(vocab_size, output_dim=64, input_length=max_len))  
  model.add(tf.keras.layers.LSTM(units=1024, activation='tanh'))
  model.add(tf.keras.layers.Dense(units=1024, activation='sigmoid'))
  model.add(tf.keras.layers.Dense(units=MAX_LEN, activation=None))

  return model

generator = create_generator(MAX_LEN, VOCABULARY_SIZE)

for epoch in range(EPOCHS):
  noise = (tf.random.uniform([BATCH_SIZE, LATENT_DIM], minval=0, maxval = VOCABULARY_SIZE))

  with tf.GradientTape() as disc_tape, tf.GradientTape() as gen_tape:

    # Generator loss    
    fake_revs = generator(noise)
    pred_class_fake_revs = discriminator(fake_revs)
    gen_loss, gen_acc = generator_loss_and_accuracy(pred_class_fake_revs)

    # Disc loss
    real_revs = reviews_tok_padded[np.random.randint(0, len(reviews_tok_padded),BATCH_SIZE)]
    pred_class_real_revs = discriminator(real_revs) 
    disc_loss, disc_acc = discriminator_loss_and_accuracy(pred_class_real_revs, pred_class_fake_revs)

    gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)    
    disc_grad = disc_tape.gradient(disc_loss, discriminator.trainable_variables)

    generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))
    disc_optimizer.apply_gradients(zip(disc_grad, discriminator.trainable_variables))

我得到的确切错误是:

ValueError: No gradients provided for any variable: ['embedding_22/embeddings:0', 'lstm_22/lstm_cell_30/kernel:0', 'lstm_22/lstm_cell_30/recurrent_kernel:0', 'lstm_22/lstm_cell_30/bias:0', 'dense_44/kernel:0', 'dense_44/bias:0', 'dense_45/kernel:0', 'dense_45/bias:0'].

编辑:经过进一步调查,问题很明显是磁带不计算梯度,因此对于所有 generator.trainable_variables,变量 gradients_of_generator 等于 none。但是,我不知道为什么会这样。

所以,我终于找到了导致问题的原因。它与鉴别器模型中的层有关,它甚至没有包含在上面的代码块中,因为我认为这不是问题所在(因为当我将鉴别器作为独立模型进行测试时,它起作用了)。它是这样定义的:


    def crear_discriminador():
      model = tf.keras.Sequential()    
      model.add(tf.keras.layers.Embedding(input_dim=VOCABULARY_SIZE, output_dim=64, input_length=MAX_LEN))
      model.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(units=64, activation='tanh')))
      model.add(tf.keras.layers.Dense(64, activation='relu'))
      model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
    
    return model

问题是嵌入层不可微,因此当结合生成器和鉴别器时,鉴别器中的嵌入层阻止了生成器中层的梯度计算。