风格迁移的工作原理

2025年3月17日 | 阅读 7 分钟

神经风格迁移是用于获取两张图像——内容图像风格参考图像并将它们混合的技术,因此输出图像看起来像内容图像,但以风格参考图像的风格“绘制”。

导入并配置模块

打开 Google colab


输出

TensorFlow 2.x selected.

输出

Downloading data from https://www.eadegallery.co.nz/wp-content/uploads/2019/03/626a6823-af82-432a-8d3d-d8295b1a9aed-l.jpg
1122304/1117520 [==============================] - 1s 1us/step
Downloading data from https://i.pinimg.com/originals/11/91/4f/11914f29c6d3e9828cc5f5c2fd64cfdc.jpg
      49152/43511 [=================================] - 0s 0us/step5. def 

将最大测量值检查到 512 像素。

创建一个函数来显示图像


输出

Working of Style Transferring

输出

Downloading data from https://github.com/fchollet/deep-learning-    models/releases/download/v0.1/vgg19_weights_tf_dim_ordering_tf_kernels.h5

574717952/574710816 [==============================] - 8s 0us/step
TensorShape([1, 1000])

输出

Downloading data from https://storage.googleapis.com/download.tensorflow.org/data/imagenet_class_index.json
40960/35363 [==================================] - 0s 0us/step
[('mobile_home', 0.7314594),
 ('picket_fence', 0.119986326),
 ('greenhouse', 0.026051044),
 ('thatch', 0.023595566),
 ('boathouse', 0.014751049)]

定义风格和内容表示

使用模型的中间层来表示图像的内容和风格。 从输入层开始,前几层的激活表示低级表示,例如边缘和纹理。

对于输入图像,尝试匹配中间层中相似的风格和内容目标表示。

加载 VGG19 并在我们的图像上运行它,以确保它在这里被正确使用。

输出

Download data from https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg19_weights_tf_dim_ordering_tf_kernels_notop.h5
80142336/80134624 [==============================] - 2s 0us/step

input_2
block1_conv1
block1_conv2
block1_pool
block2_conv1
block2_conv2
block2_pool
block3_conv1
block3_conv2
block3_conv3
block3_conv4
block3_pool
block4_conv1
block4_conv2
block4_conv3
block4_conv4
block4_pool
block5_conv1
block5_conv2
block5_conv3
block5_conv4
block5_pool

风格和内容的中间层

从高级来看,一个用于执行图像分类的网络了解图像,并且需要将图像作为像素并构建一个内部插图,该插图将原始图像像素转换为图像中存在的复杂特征。

这也是卷积神经网络能够很好地泛化的原因:它们可以捕获类中不同的和定义特征(例如,猫 vs. 狗),这些特征与图像馈入模型和输出排列标签的方式无关,模型将其作为复杂的特征提取器交付。 通过访问模型的中间层,我们可以描述输入图像的风格和内容。

构建模型

tf.keras.applications 中定义了网络,因此我们可以使用 Keras 功能 API 轻松提取中间层的值。

要使用功能 API 定义任何模型,请指定输入和输出

model= Model(inputs, outputs)

给定的函数构建一个 VGG19 模型,该模型返回中间层列表。


输出

block1_conv1
  shape:  (1, 427, 512, 64)
  min:  0.0
  max:  763.51953
  mean:  25.987665

block2_conv1
  shape:  (1, 213, 256, 128)
  min:  0.0
  max:  3484.3037
  mean:  134.27835

block3_conv1
  shape:  (1, 106, 128, 256)
  min:  0.0
  max:  7291.078
  mean:  143.77878

block4_conv1
  shape:  (1, 53, 64, 512)
  min:  0.0
  max:  13492.799
  mean:  530.00244

block5_conv1
  shape:  (1, 26, 32, 512)
  min:  0.0
  max:  2881.529
  mean:  40.596397

Gram 矩阵

计算风格

图像的内容由地图的常见特征的值表示。

计算一个 Gram 矩阵,它通过对所有位置进行输出乘积来包含此信息。

Gram 矩阵可以为特定层计算为

Working of Style Transferring

这使用 tf.linalg.einsum 函数简洁地实现

提取图像的风格和内容

构建返回内容和风格张量的模型。

当在图像上调用时,此模型返回 style_layers 的 Gram 矩阵(风格)和 content_layers 的内容

输出

Styles:
   block1_conv1
    shape:  (1, 64, 64)
    min:  0.0055228453
    max:  28014.557
    mean:  263.79025

   block2_conv1
    shape:  (1, 128, 128)
    min:  0.0
    max:  61479.496
    mean:  9100.949

   block3_conv1
    shape:  (1, 256, 256)
    min:  0.0
    max:  545623.44
    mean:  7660.976

   block4_conv1
    shape:  (1, 512, 512)
    min:  0.0
    max:  4320502.0
    mean:  134288.84

   block5_conv1
    shape:  (1, 512, 512)
    min:  0.0
    max:  110005.37
    mean:  1487.0381

Contents:
   block5_conv2
    shape:  (1, 26, 32, 512)
    min:  0.0
    max:  2410.8796
    mean:  13.764149

运行梯度下降

使用此风格和内容提取器,我们实现风格迁移算法。 通过评估我们的图像输出相对于每个目标的均方误差来执行此操作,然后获取损失的加权和。

设置我们的 风格内容 目标值

定义一个 tf.Variable 来包含要保存的图像。 借助内容图像(tf.Variable 的形状与内容图像相同)对其进行初始化

这是一个浮动图像,定义一个将像素值保持在 01 之间的函数

创建优化器。 本文推荐 LBFGS

要优化它,请使用两个损失的权重组合来获得总损失


使用函数 tf.GradientTape 来更新图像。

运行以下步骤进行测试

输出

Working of Style Transferring

转换图像

在此步骤中执行更长的优化

输出

Working of Style Transferring
Working of Style Transferring
Working of Style Transferring
Working of Style Transferring
Working of Style Transferring
Working of Style Transferring
Working of Style Transferring
Working of Style Transferring
Working of Style Transferring
Working of Style Transferring

总变异损失


输出

Working of Style Transferring
Working of Style Transferring

这显示了高频分量如何增加。

此高频分量是一个边缘检测器。 我们从给定的示例中得到来自边缘检测器的相同输出

输出

Working of Style Transferring

与此相关的正则化损失是值的平方和


输出

99172.59

这演示了它的作用。 但无需自己实现它,它包含一个标准实现

输出

array([99172.59], dtype=float32)

重新运行优化函数

选择函数 total_variation_loss 的权重

现在,train_step 函数

重新初始化优化变量

并运行优化

输出

Working of Style Transferring

最后保存结果


下一主题TensorBoard