在 TensorFlow.org 上查看 | 在 Google Colab 中运行 | 在 GitHub 上查看 | 下载笔记本 | 查看 TF Hub 模型 |
此 Colab 演示了基于生成对抗网络 (GAN) 的 TF Hub 模块的使用。该模块将来自称为潜在空间的 N 维向量映射到 RGB 图像。
提供了两个示例
- 映射来自潜在空间到图像,以及
- 给定目标图像,使用梯度下降找到生成与目标图像相似的图像的潜在向量。
可选先决条件
- 熟悉 低级 Tensorflow 概念。
- 生成对抗网络 在维基百科上。
- 关于 Progressive GAN 的论文:Progressive Growing of GANs for Improved Quality, Stability, and Variation。
更多模型
这里您可以找到目前托管在 tfhub.dev 上的所有可以生成图像的模型。
设置
# Install imageio for creating animations.
pip -q install imageio
pip -q install scikit-image
pip install git+https://github.com/tensorflow/docs
导入和函数定义
潜在空间插值
随机向量
两个随机初始化向量之间的潜在空间插值。我们将使用 TF Hub 模块 progan-128,其中包含一个预训练的 Progressive GAN。
progan = hub.load("https://tfhub.dev/google/progan-128/1").signatures['default']
2024-03-09 13:17:20.450855: E external/local_xla/xla/stream_executor/cuda/cuda_driver.cc:282] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected
def interpolate_between_vectors():
v1 = tf.random.normal([latent_dim])
v2 = tf.random.normal([latent_dim])
# Creates a tensor with 25 steps of interpolation between v1 and v2.
vectors = interpolate_hypersphere(v1, v2, 50)
# Uses module to generate images from the latent space.
interpolated_images = progan(vectors)['default']
return interpolated_images
interpolated_images = interpolate_between_vectors()
animate(interpolated_images)
在潜在空间中查找最接近的向量
修复目标图像。例如,使用从模块生成的图像或上传您自己的图像。
image_from_module_space = True # @param { isTemplate:true, type:"boolean" }
def get_module_space_image():
vector = tf.random.normal([1, latent_dim])
images = progan(vector)['default'][0]
return images
def upload_image():
uploaded = files.upload()
image = imageio.imread(uploaded[list(uploaded.keys())[0]])
return transform.resize(image, [128, 128])
if image_from_module_space:
target_image = get_module_space_image()
else:
target_image = upload_image()
display_image(target_image)
在定义目标图像和由潜在空间变量生成的图像之间的损失函数后,我们可以使用梯度下降来查找最小化损失的变量值。
tf.random.set_seed(42)
initial_vector = tf.random.normal([1, latent_dim])
display_image(progan(initial_vector)['default'][0])
def find_closest_latent_vector(initial_vector, num_optimization_steps,
steps_per_image):
images = []
losses = []
vector = tf.Variable(initial_vector)
optimizer = tf.optimizers.Adam(learning_rate=0.01)
loss_fn = tf.losses.MeanAbsoluteError(reduction="sum")
for step in range(num_optimization_steps):
if (step % 100)==0:
print()
print('.', end='')
with tf.GradientTape() as tape:
image = progan(vector.read_value())['default'][0]
if (step % steps_per_image) == 0:
images.append(image.numpy())
target_image_difference = loss_fn(image, target_image[:,:,:3])
# The latent vectors were sampled from a normal distribution. We can get
# more realistic images if we regularize the length of the latent vector to
# the average length of vector from this distribution.
regularizer = tf.abs(tf.norm(vector) - np.sqrt(latent_dim))
loss = target_image_difference + regularizer
losses.append(loss.numpy())
grads = tape.gradient(loss, [vector])
optimizer.apply_gradients(zip(grads, [vector]))
return images, losses
num_optimization_steps=200
steps_per_image=5
images, loss = find_closest_latent_vector(initial_vector, num_optimization_steps, steps_per_image)
.................................................................................................... ....................................................................................................
plt.plot(loss)
plt.ylim([0,max(plt.ylim())])
(0.0, 6696.3041717529295)
animate(np.stack(images))
将结果与目标进行比较
display_image(np.concatenate([images[-1], target_image], axis=1))
使用上述示例
如果图像来自模块空间,则下降速度很快,并收敛到一个合理的样本。尝试下降到不是来自模块空间的图像。只有当图像与训练图像空间相当接近时,下降才会收敛。
如何使其下降更快并得到更逼真的图像?您可以尝试
- 使用图像差异上的不同损失,例如二次损失,
- 在潜在向量上使用不同的正则化器,
- 在多次运行中从随机向量初始化,
- 等等。