提交 1c4b02f5 编写于 作者: W wizardforcel

2020-12-09 11:06:20

上级 c08d8f85
......@@ -24,7 +24,7 @@
使用深度神经网络将图像内容与另一种图像的样式合并的原始思想和算法于 2015 年夏季发表在题为[《艺术风格的神经算法》](https://arxiv.org/abs/1508.06576)的论文中。它是 2014 年 ImageNet 图像识别挑战赛的获胜者,该挑战赛具有 16 个卷积层或特征图,分别代表不同级别的图像内容。 在这种原始方法中,首先将最终传输的图像初始化为与内容图像合并的白噪声图像。 内容损失函数定义为内容图像和结果图像的卷积层 conv4_2 上都被馈入 VGG-19 网络后,特定的一组特征表示形式的平方误差损失。 样式损失函数计算样式图像和所得图像在五个不同卷积层上的总误差差。 然后,将总损失定义为内容损失和样式损失的总和。 在训练期间,损失会降到最低,并生成将一个图像的内容与另一个图像的样式混合在一起的结果图像。
使用深度神经网络将图像内容与另一种图像的样式合并的原始思想和算法于 2015 年夏季发表在题为[《艺术风格的神经算法》](https://arxiv.org/abs/1508.06576)的论文中。它是 2014 年 ImageNet 图像识别挑战赛的获胜者,该挑战赛具有 16 个卷积层或特征图,分别代表不同级别的图像内容。 在这种原始方法中,首先将最终传输的图像初始化为与内容图像合并的白噪声图像。 内容损失函数定义为内容图像和结果图像的卷积层`conv4_2`上都被馈入 VGG-19 网络后,特定的一组特征表示形式的平方误差损失。 样式损失函数计算样式图像和所得图像在五个不同卷积层上的总误差差。 然后,将总损失定义为内容损失和样式损失的总和。 在训练期间,损失会降到最低,并生成将一个图像的内容与另一个图像的样式混合在一起的结果图像。
尽管原始神经样式转换算法的结果令人惊叹,但其性能却很差-训练是样式转换图像生成过程的一部分,通常在 GPU 上花费几分钟,在 CPU 上花费约一个小时才能生成良好的图像。 结果。
......@@ -54,11 +54,11 @@ mkdir test_dir
python style.py --style images/starry_night.jpg --test images/ww1.jpg --test-dir test_dir --content-weight 1.5e1 --checkpoint-dir checkpoints --checkpoint-iterations 1000 --batch-size 10
```
images 目录中还有一些其他样式的图像,可用于创建不同的检查点文件。 此处使用的`starry_night.jpg`样式图片是 Vincent van Gogh 的一幅著名画作,如图 4.1 所示:
`images`目录中还有一些其他样式的图像,可用于创建不同的检查点文件。 此处使用的`starry_night.jpg`样式图片是梵高的一幅著名画作,如图 4.1 所示:
![](img/ea1f4494-b7f4-4be2-a897-adfcbc4f0ef4.jpg)Figure 4.1 Using Van Gogh's painting as the style image
在第 1 章, *Mobile TensorFlow* 入门中设置的 NVIDIA GTX 1070 GPU 驱动的 Ubuntu 上,整个训练大约需要 5 个小时,并且在 CPU 上肯定要花更长的时间 。
在第 1 章, “移动 TensorFlow 入门”中设置的 NVIDIA GTX 1070 GPU 驱动的 Ubuntu 上,整个训练大约需要 5 个小时,并且在 CPU 上肯定要花更长的时间 。
The script was originally written for TensorFlow 0.12 but modified later for TensorFlow 1.1, and has been verified to also run OK in the TensorFlow 1.4 with Python 2.7 environment we set up earlier.
......@@ -83,7 +83,7 @@ python evaluate.py --checkpoint checkpoints \
python freeze.py --model_folder=checkpoints_ios --output_graph fst_frozen.pb
```
7. 假设您具有`/tf_files`目录,将生成的`fst_frozen.pb`文件复制到`/tf_files``cd`直接复制到 TensorFlow 源根目录(可能是`~/tensorflow-1.4.0`),然后运行以下命令以生成`.pb`的量化模型 ]文件(我们在第 2 章,“通过迁移学习对图像进行分类”中介绍了量化):
7. 假设您具有`/tf_files`目录,将生成的`fst_frozen.pb`文件复制到`/tf_files``cd`直接复制到 TensorFlow 源根目录(可能是`~/tensorflow-1.4.0`),然后运行以下命令以生成量化模型的`.pb`文件(我们在第 2 章,“通过迁移学习对图像进行分类”中介绍了量化):
```py
bazel-bin/tensorflow/tools/quantization/quantize_graph \
......@@ -107,7 +107,7 @@ bazel-bin/tensorflow/tools/quantization/quantize_graph \
事实证明,在由 TensorFlow 实验性容器构建的 iOS 应用中,使用在步骤 7 中生成的`fst_frozen_quantized.pb`模型文件没有问题,如第 2 章,“通过迁移学习对图像分类”,但 TensorFlow Magenta 项目中的预训练多样式模型文件(我们将在本章的后续部分中使用)将不会随 TensorFlow pod 一起加载(截至 2018 年 1 月 )—尝试加载多样式模型文件时将引发以下错误:
事实证明,在由 TensorFlow 实验性容器构建的 iOS 应用中,使用在步骤 7 中生成的`fst_frozen_quantized.pb`模型文件没有问题,如第 2 章,“通过迁移学习对图像分类”,但 TensorFlow Magenta 项目中的预训练多样式模型文件(我们将在本章的后续部分中使用)将不会随 TensorFlow Pod 一起加载(截至 2018 年 1 月)—尝试加载多样式模型文件时将引发以下错误:
```py
Could not create TensorFlow Graph: Invalid argument: No OpKernel was registered to support Op 'Mul' with these attrs. Registered devices: [CPU], Registered kernels:
......@@ -127,7 +127,7 @@ Could not create TensorFlow Graph: Invalid argument: No OpKernel was registered
如果您尚未手动构建 TensorFlow 库,则需要先回到上一章。 然后执行以下步骤以将 TensorFlow 支持和快速的神经样式传输模型文件添加到您的 iOS 应用并测试运行该应用:
1. 如果您已经具有添加了 TensorFlow 手动库的 iOS 应用,则可以跳过此步骤。 否则,类似于我们在上一章中所做的,创建一个新的基于 Objective-C 的 iOS 应用程序,例如`NeuralStyleTransfer`,或者在现有应用程序中,在 PROJECT 的下创建一个新的用户定义设置 使用`$HOME/tensorflow-1.4.0`值命名为`TENSORFLOW_ROOT`的构建设置,假定在那儿已安装 TensorFlow 1.4.0,然后在 TARGET 的构建设置中,将其他链接器标志设置为:
1. 如果您已经具有添加了 TensorFlow 手动库的 iOS 应用,则可以跳过此步骤。 否则,类似于我们在上一章中所做的,创建一个新的基于 Objective-C 的 iOS 应用程序,例如`NeuralStyleTransfer`,或者在现有应用程序中,在`PROJECT`下创建一个新的用户定义设置 使用`$HOME/tensorflow-1.4.0`值命名为`TENSORFLOW_ROOT`的构建设置,假定在那儿已安装 TensorFlow 1.4.0,然后在`TARGET`的构建设置中,将其他链接器标志设置为:
```py
-force_load $(TENSORFLOW_ROOT)/tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a $(TENSORFLOW_ROOT)/tensorflow/contrib/makefile/gen/protobuf_ios/lib/libprotobuf.a $(TENSORFLOW_ROOT)/tensorflow/contrib/makefile/gen/protobuf_ios/lib/libprotobuf-lite.a $(TENSORFLOW_ROOT)/tensorflow/contrib/makefile/downloads/nsync/builds/lipo.ios.c++11/nsync.a
......@@ -238,13 +238,13 @@ return imgScaled;
由于此 Android 应用程序提供了一个很好的机会来使用最少的 TensorFlow 相关代码,Android UI 和线程化代码来运行完整的 TensorFlow 模型驱动的应用程序,因此,我们将从头开始添加每行代码,以帮助您进一步了解 从头开始开发 Android TensorFlow 应用需要什么:
1. 在 Android Studio 中,选择文件 | 新增 | New Project ... ,然后输入`FastNeuralTransfer`作为应用程序名称; 在单击“完成”之前,接受所有默认设置。
1. 在 Android Studio 中,选择“文件 | 新增 | 新项目...”,然后输入`FastNeuralTransfer`作为应用程序名称; 在单击“完成”之前,接受所有默认设置。
2. 创建一个新的`assets`文件夹,如图 2.13 所示,然后将您训练过的快速神经传递模型从 iOS 应用中拖动(如果您在上一节中尝试过),或者从文件夹`/tf_files`中拖动,如步骤 7 所示 *训练快速神经样式转换模型*部分,以及一些测试图像到`assets`文件夹。
2. 创建一个新的`assets`文件夹,如图 2.13 所示,然后将您训练过的快速神经传递模型从 iOS 应用中拖动(如果您在上一节中尝试过),或者从文件夹`/tf_files`中拖动,如“训练快速神经样式转换模型”部分步骤 7 所示,以及一些测试图像到`assets`文件夹。
3. 在应用程序的`build.gradle` 文件中,在 `dependencies` 的末尾添加一行 `compile 'org.tensorflow:tensorflow-android:+'`和。
4. 打开`res/layout/activity_main.xml`文件,在其中删除默认的 TextView,然后首先添加一个 ImageView 以显示样式转换前后的图像:
4. 打开`res/layout/activity_main.xml`文件,在其中删除默认的`TextView`,然后首先添加一个`ImageView`以显示样式转换前后的图像:
```py
<ImageView
......@@ -292,7 +292,7 @@ private static final int WANTED_WIDTH = 300;
private static final int WANTED_HEIGHT = 400;
```
您可以将任何训练有素的模型文件用于`MODEL_FILE``INPUT_NODE``OUTPUT_NODE`的值与我们在 Python 训练脚本中设置并在 iOS 应用中使用的值相同。 同样,`WANTED_WIDTH``WANTED_HEIGHT`与我们在*训练快速神经风格转换模型*部分的第 5 步中使用的`--in-path`图像的图像宽度和高度相同。
您可以将任何训练有素的模型文件用于`MODEL_FILE``INPUT_NODE``OUTPUT_NODE`的值与我们在 Python 训练脚本中设置并在 iOS 应用中使用的值相同。 同样,`WANTED_WIDTH``WANTED_HEIGHT`与我们在“训练快速神经风格转换模型”部分的第 5 步中使用的`--in-path`图像的宽度和高度相同
8. 声明四个实例变量:
......@@ -348,7 +348,7 @@ mButton.setOnClickListener(new View.OnClickListener() {
});
```
12. 在线程的`run`方法中,我们首先声明三个数组,并为其分配适当的内存:`intValues`数组保存测试图像的像素值,每个像素值代表 32 位 ARGB(Alpha,Red,Green ,蓝色)值; `floatValues`阵列如模型所预期的那样分别保存每个像素的红色,绿色和蓝色值,因此其大小是`intValues`的三倍,并且`outputValues`的大小与`floatValues`相同 ],但保留模型的输出值:
12. 在线程的`run`方法中,我们首先声明三个数组,并为其分配适当的内存:`intValues`数组保存测试图像的像素值,每个像素值代表 32 位 ARGB(Alpha,红,绿,蓝色)值; `floatValues`阵列如模型所预期的那样分别保存每个像素的红色,绿色和蓝色值,因此其大小是`intValues`的三倍,并且`outputValues`的大小与`floatValues`相同 ],但保留模型的输出值:
```py
public void run() {
......@@ -384,7 +384,7 @@ mInferenceInterface.run(new String[] {OUTPUT_NODE}, false);
mInferenceInterface.fetch(OUTPUT_NODE, outputValues);
```
模型生成的`outputValues`在每个元素中都保留 0 到 255 之间的 8 位红色,绿色和蓝色值之一,我们首先对红色和绿色值使用左移操作,但是 具有不同的移位大小(16 和 8),然后使用按位或运算将 8 位 Alpha 值(0xFF)与 8 位 RGB 值组合,将结果保存在`intValues`数组中:
模型生成的`outputValues`在每个元素中都保留 0 到 255 之间的 8 位红色,绿色和蓝色值之一,我们首先对红色和绿色值使用左移操作,但是 具有不同的移位大小(16 和 8),然后使用按位或运算将 8 位 Alpha 值(`0xFF`)与 8 位 RGB 值组合,将结果保存在`intValues`数组中:
```py
for (int i=0; i < intValues.length; ++i) {
......@@ -394,7 +394,7 @@ for (int i=0; i < intValues.length; ++i) {
| ((int) outputValues[i*3+2]);
```
然后,我们创建一个新的 Bitmap 实例,并使用`intValues`数组设置其像素值,将位图缩放到测试图像的原始大小,并将缩放后的位图保存到`mTransferredBitmap`
然后,我们创建一个新的`Bitmap`实例,并使用`intValues`数组设置其像素值,将位图缩放到测试图像的原始大小,并将缩放后的位图保存到`mTransferredBitmap`
```py
Bitmap outputBitmap = scaledBitmap.copy( scaledBitmap.getConfig() , true);
......@@ -424,9 +424,9 @@ mHandler.sendMessage(msg);
[TensorFlow Magenta 项目](https://github.com/tensorflow/magenta)允许您使用 10 多种经过预训练的模型来生成新的音乐和图像。 在本节和下一节中,我们将重点介绍使用 Magenta 的图像样式化模型。 您可以单击链接在计算机上安装 Magenta,尽管要在移动应用程序中使用其炫酷的图像样式传输模型,也不必安装 Magenta。 *2017* 中基于论文*习得的艺术风格*实现的洋红色预训练风格转换模型,消除了一个模型只能具有一种风格并允许多种风格的限制 包含在单个模型文件中,您可以选择使用这些样式的任意组合。 您可以在[这个页面](https://github.com/tensorflow/magenta/tree/master/magenta/models/image_stylization)上快速浏览该演示,但可以在此处下载两个预先训练的检查点模型。 由于检查点文件中保存了某些 NaN(不是数字)错误,因此无法直接在您的移动应用中使用。 我们不会详细说明如何删除这些数字并生成可在您的应用中使用的`.pb`模型文件(如果感兴趣,您可以查看 这里](https://github.com/tensorflow/tensorflow/issues/9678)),我们仅使用 TensorFlow Android 示例`tensorflow/examples/android/assets`中包含的经过预训练的`stylize_quantized.pb`模型文件来查看其工作原理。
[TensorFlow Magenta 项目](https://github.com/tensorflow/magenta)允许您使用 10 多种经过预训练的模型来生成新的音乐和图像。 在本节和下一节中,我们将重点介绍使用 Magenta 的图像样式化模型。 您可以单击链接在计算机上安装 Magenta,尽管要在移动应用程序中使用其炫酷的图像样式传输模型,也不必安装 Magenta。 基于论文《艺术风格的习得表示》实现的 Magenta 预训练风格转换模型,消除了一个模型只能具有一种风格并允许多种风格的限制 包含在单个模型文件中,您可以选择使用这些样式的任意组合。 您可以在[这个页面](https://github.com/tensorflow/magenta/tree/master/magenta/models/image_stylization)上快速浏览该演示,但可以在此处下载两个预先训练的检查点模型。 由于检查点文件中保存了某些`NaN`(不是数字)错误,因此无法直接在您的移动应用中使用。 我们不会详细说明如何删除这些数字并生成可在您的应用中使用的`.pb`模型文件(如果感兴趣,您可以查看 这里](https://github.com/tensorflow/tensorflow/issues/9678)),我们仅使用 TensorFlow Android 示例`tensorflow/examples/android/assets`中包含的经过预训练的`stylize_quantized.pb`模型文件来查看其工作原理。
如果您确实想训练自己的模型,则可以按照前面的 image_stylization 链接中的训练模型下的步骤进行。 但是请注意,您至少需要 500GB 的可用磁盘空间才能下载 ImageNet 数据集,并需要强大的 GPU 来完成训练。 在本节或下一节中看到代码和结果之后,您更有可能对预训练的`stylize_quantized.pb`模型启用的炫酷样式转换效果感到满意。
如果您确实想训练自己的模型,则可以按照前面的`image_stylization`链接中的训练模型下的步骤进行。 但是请注意,您至少需要 500GB 的可用磁盘空间才能下载 ImageNet 数据集,并需要强大的 GPU 来完成训练。 在本节或下一节中看到代码和结果之后,您更有可能对预训练的`stylize_quantized.pb`模型启用的炫酷样式转换效果感到满意。
在本章前面创建的 iOS 应用中,执行以下步骤来使用和运行多样式模型:
......@@ -462,7 +462,7 @@ tensorflow::Tensor image_tensor(tensorflow::DT_FLOAT, tensorflow::TensorShape({1
auto image_tensor_mapped = image_tensor.tensor<float, 4>();
```
5. 我们还需要将`style_tensor`定义为形状为[`NUM_STYLES` * 1)的另一个张量,其中`NUM_STYLES`在`ViewController.mm`的开头定义为`const int NUM_STYLES = 26;`。 数字 26 是 `stylize_quantized.pb`模型文件中内置的样式数,您可以在其中运行 Android TF Stylize 应用并查看 26 种结果,如图 4.5 所示。 请注意,第 20 张图片(左下角的图片)是梵高熟悉的繁星点点的夜晚:
5. 我们还需要将`style_tensor`定义为形状为`[NUM_STYLES * 1]`的另一个张量,其中`NUM_STYLES``ViewController.mm`的开头定义为`const int NUM_STYLES = 26;`。 数字 26 是 `stylize_quantized.pb`模型文件中内置的样式数,您可以在其中运行 Android TF 风格化应用并查看 26 种结果,如图 4.5 所示。 请注意,第 20 张图片(左下角的图片)是梵高熟悉的繁星点点的夜晚:
![](img/ea7a04fe-8b56-47b2-ac5a-7f25ced4acbd.png)Figure 4.5 The 26 style images in the multi-style model
......@@ -485,7 +485,7 @@ out_style[4] = 0.5;
out_style[19] = 0.5;
```
如果您希望所有 26 种样式均等地混合使用,请将前面的 for 循环更改为以下样式,并且不要将其他值设置为任何特定的`out_style`元素:
如果您希望所有 26 种样式均等地混合使用,请将前面的`for`循环更改为以下样式,并且不要将其他值设置为任何特定的`out_style`元素:
```py
for (int i = 0; i < NUM_STYLES; i++) {
......@@ -509,7 +509,7 @@ tensorflow::Status run_status = session->Run({{input_layer, image_tensor}, {styl
![](img/c462927f-71be-46f1-995f-5cbd536ae175.png)Figure 4.7 Showing the choice of two style models
两张已传输图像的结果,out_style [19] = 1.0; 如图 4.8 所示:
两张已传输图像的结果,`out_style[19] = 1.0`; 如图 4.8 所示:
![](img/cc28a550-1a66-4845-b330-1c01d3806e62.png)Figure 4.8 The style-transferred results with two different models (fast style transfer on the left, multi-style on the right)
......@@ -597,7 +597,7 @@ for (int i=0; i < intValues.length; ++i) {
}
```
注意,多样式模型返回浮点数数组 至 `outputValues` ,它们的范围都在 0.0 到 1.0 之间,因此我们需要将它们相乘 在应用左位移操作以获取 Red 和 Green 值之前,先进行 255 乘以 255,然后对 `intValues` 数组的每个元素应用按位“或”设置最终 ARGB 值。
注意,多样式模型返回浮点数数组 至 `outputValues` ,它们的范围都在 0.0 到 1.0 之间,因此我们需要将它们相乘 在应用左位移操作以获取红色和绿色值之前,先进行 255 乘以 255,然后对 `intValues` 数组的每个元素应用按位“或”设置最终 ARGB 值。
这就是将酷炫的多样式模型添加到独立的 Android 应用程序所需的全部工作。 现在,让我们运行该应用程序,并使用不同的测试图像,但使用与 iOS 应用程序中相同的三种样式值组合。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册