【问题标题】:ValueError: No gradients provided for any variable - Tensorflow 2.0ValueError:没有为任何变量提供梯度 - Tensorflow 2.0
【发布时间】:2021-03-12 17:08:38
【问题描述】:

我正在尝试从训练有素的 MNIST GAN 模型中找到 MNIST 图像的相应潜在代码。我打算做的是对定义为目标和生成样本之间距离的损失应用梯度下降。随着生成的样本越来越接近目标,损失减少,相应的潜在代码就是我所需要的。

这是我的代码:

import numpy as np
import tensorflow as tf
from tensorflow.keras import Model
from tensorflow.keras import Sequential
import tensorflow.keras.backend as K
from tensorflow.keras.datasets import mnist
from tensorflow.keras import layers
from tensorflow.keras.layers import *
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.optimizers import SGD
from tensorflow.keras.losses import MeanSquaredError
import random

### Load MNIST data
(data_x, _), _ = mnist.load_data()
data_x = np.reshape(np.asarray(data_x), [60000, 28*28]).astype(float)
train = data_x[:1024]
test = data_x[-10:]

### GAN setting
generator = Sequential([
    Dense(7 * 7 * 64, input_shape=[100]),
    BatchNormalization(),
    LeakyReLU(),
    Reshape([7, 7, 64]),
    UpSampling2D([2, 2]),
    Conv2DTranspose(64, [3, 3], padding='same'),
    BatchNormalization(),
    LeakyReLU(),
    UpSampling2D([2, 2]),
    Conv2DTranspose(1, [3, 3], padding='same', activation='sigmoid')
])

discriminator = Sequential([
    Conv2D(64, [3, 3], padding='same', input_shape=[28, 28, 1]),
    BatchNormalization(),
    LeakyReLU(),
    MaxPool2D([2, 2]),
    Conv2D(64, [3, 3], padding='same'),
    BatchNormalization(),
    LeakyReLU(),
    MaxPool2D([2, 2]),
    Flatten(),
    Dense(128),
    BatchNormalization(),
    LeakyReLU(),
    Dense(1, activation='sigmoid')
])

x_input = Input([28, 28, 1])
g_sample_input = Input([100])

log_clip = Lambda(lambda x: K.log(x + 1e-3))

sample_score = discriminator(generator(g_sample_input))

d_loss = (
    - log_clip(discriminator(x_input)) 
    - log_clip(1.0 - sample_score)
)
fit_discriminator = Model(inputs=[x_input, g_sample_input], outputs=d_loss)
fit_discriminator.add_loss(d_loss)
generator.trainable = False
for layer in generator.layers:
    if isinstance(layer, BatchNormalization):
        layer.trainable = True
fit_discriminator.compile(optimizer=Adam(0.001))
generator.trainable = True

g_loss = (
    - log_clip(sample_score)
)
fit_generator = Model(inputs=g_sample_input, outputs=g_loss)
fit_generator.add_loss(g_loss)
discriminator.trainable = False
for layer in discriminator.layers:
    if isinstance(layer, BatchNormalization):
        layer.trainable = True
fit_generator.compile(optimizer=Adam(0.001))
discriminator.trainable = True

### GAN training
train_x = train.reshape([-1, 28, 28, 1]) / 255
batch_size = 64
for i in range(10000):
    x = train_x[random.sample(range(len(train_x)), batch_size)]
    g_sample = np.random.uniform(-1, 1, [batch_size, 100])
    fit_discriminator.fit([K.constant(x), K.constant(g_sample)])
    fit_generator.fit(g_sample)
    
### Search for latent code
target = (test[0] / 255).reshape([28, 28])
mse = MeanSquaredError()
z = np.random.uniform(-1, 1, [1, 100])
z_t = tf.Variable(z, trainable=True)
opt = SGD(learning_rate=0.1)

for _ in range(10):
    loss_fn = lambda: mse(target,
                          generator(z_t.numpy())[0].numpy().reshape([28, 28]))

    opt.minimize(loss_fn, var_list=[z_t])

我得到这个错误:

ValueError:没有为任何变量提供渐变:['Variable:0']。

Tensorflow 似乎无法从这种损失中计算梯度。

如果损失来自另一个模型,有没有办法计算梯度?或者有没有办法在不计算梯度的情况下实现我的目标?

【问题讨论】:

  • 您的代码不会重现您发布的错误。了解如何创建minimal, reproducible example
  • 感谢您的评论。这是我第一次在这里提问,很抱歉缺乏信息。我已经更新了代码,以便提供所有内容。
  • 无需道歉,只是想帮助您提出一个有效的问题。这个网站每分钟都有很多帖子,如果我们可以复制和粘贴您的代码,并且它会重现错误,那么有人能够回答的可能性会大大高于没有回答的可能性:)

标签: python tensorflow deep-learning tensorflow2.0 generative-adversarial-network


【解决方案1】:

我想我找到了关键点。

Tensorflow 基于图形计算梯度。所以我们应该总是把每一个操作都放在图中。

我的代码的错误是由tensor-numpy转换引起的。因为一旦我们将张量转换为一个 numpy 数组,它就会被带出图表,Tensorflow 无法再跟踪它。

这是我的新代码,现在运行良好:

mse = MeanSquaredError()
target = (test[0] / 255).reshape([28, 28])
target_t = tf.convert_to_tensor(target)
z = np.random.uniform(-1, 1, [1, 100])
z_t = tf.Variable(z, trainable=True)
opt = SGD(learning_rate=0.1)

for _ in range(10):
    loss_fn = lambda: mse(target_t,
                          tf.reshape(tf.cast(generator(z_t), tf.float64), [28, 28]))
    opt.minimize(loss_fn, var_list=[z_t])

(这里只显示最后一段代码,其他部分保持不变。)

【讨论】:

    猜你喜欢
    • 2020-07-29
    • 2020-10-31
    • 2020-09-30
    • 2021-09-08
    • 2021-04-17
    • 2020-08-28
    • 2021-07-11
    • 1970-01-01
    • 2021-10-06
    相关资源
    最近更新 更多