#python #python-3.x #tensorflow #generative-adversarial-network
#python #python-3.x #tensorflow #порождающая-состязательная-сеть
Вопрос:
Я пытаюсь создать GAN для университетского задания. Мой код очень похож на вводный пример в этом руководстве с веб-сайта TF.
Ниже приведены, по моему мнению, соответствующие части кода (при необходимости можно предоставить более подробную информацию, например. как строится модель дискриминатора). Строка, которая выдает мне ошибку:
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'].
Редактировать: после некоторого дальнейшего исследования становится ясно, что проблема заключается в том, что лента не вычисляет градиент, поэтому переменная gradients_of_generator
равна none для всех generator.trainable_variables
. Однако я не знаю, почему это происходит.
Комментарии:
1. Во время прямого прохождения вы используете другую градиентную ленту (disc_tape_real, disc_tape_fake), но вы пытаетесь вычислить градиенты дискриминатора с совершенно другой ленты (gen_tape или disc_tape)……… gen_tap не имеет отслеживания графика
2. Вы правы, это проблема. Однако это была ошибка при копировании кода и его упрощении для создания этого сообщения. Я только что исправил это и все еще получаю ту же проблему.
3. Я воспроизвел ваш код в colab, я не получаю ошибок, и градиенты вычисляются нормально. Можете ли вы поделиться своим кодом с ошибкой в colab? потому что я не вижу в этом никакой ошибки
4. Привет. Я только что нашел причину проблемы. Смотрите Ответ ниже. Спасибо, что уделили мне время.
Ответ №1:
Итак, я наконец-то нашел причину проблемы. Это связано со слоями в модели дискриминатора, которая даже не включена в приведенный выше фрагмент кода, поскольку я думал, что это не проблема (потому что, когда я тестировал дискриминатор как отдельную модель, он работал). Вот как это определяется:
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
Проблема в том, что слой встраивания не является дифференцируемым, поэтому при объединении генератора и дискриминатора слой встраивания в дискриминаторе препятствовал вычислению градиента для слоев в генераторе.
Комментарии:
1. Проблема сейчас в том, что невозможность использовать слои на основе RNN (поскольку они нуждаются в встраивании) означает, что GAN работает намного хуже для генерации текста, что я и пытаюсь сделать. Так что любые предложения о том, как решить эту проблему, приветствуются
2. слой встраивания поддается обучению IMO, но я предполагаю, что вы делаете argmax, чтобы выбрать правильные индексы из генератора, прежде чем передавать его дискриминатору, который не предоставляет градиентов.