前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TensorFlow从1到2(十三)图片风格迁移

TensorFlow从1到2(十三)图片风格迁移

作者头像
俺踏月色而来
发布2019-05-15 14:04:41
2K9
发布2019-05-15 14:04:41
举报
文章被收录于专栏:月色的自留地月色的自留地
风格迁移

《从锅炉工到AI专家(8)》中我们介绍了一个“图片风格迁移”的例子。因为所引用的作品中使用了TensorFlow 1.x的代码,算法也相对复杂,所以文中没有仔细介绍风格迁移的原理。 今天在TensorFlow 2.0的帮助,和新算法思想的优化下,实现同样功能的代码量大幅减少,结构也越发清晰。所以今天就来讲讲这个话题。

“风格迁移”指的是将艺术作品的笔触、技法等表现出来的视觉效果,应用在普通照片上,使得所生成的图片,类似使用同样笔触、技法所绘制完成,但内容跟照片相同的“伪画作”。 在神经网络机器学习的帮助下,生成图片的观赏性非常高,远非早期传统方法得到的图片可比。 这里重贴一遍前文中的例图,让我们有一个更直观的感受。 首先是一张原程序作者的的自拍照:

接着不陌生,著名大作《星空》:

(请将以上两图保存至工作目录,不要修改文件名,我们稍晚的代码中会用到。) 两张图片经过程序处理后,会得到一幅新的图片:

即使用《星空》风格模仿的手绘作品《黄粱一梦》:)

基本原理

风格迁移原理基于论文《A Neural Algorithm of Artistic Style》。 虽然论文中并没有明说,但采用卷积神经网络做图像的风格迁移应当属于一个实验科学的成果而非单纯的理论研究。 我们再引用一张前系列讲解CNN时候的图片:

一张图片数据所形成的矩阵,在经过卷积网络的时候,图像中边缘等视觉特征会被放大、强化,从而形成一种特殊的输出。通常我们只关心数据结果,并没有把这些数据还原为图片来观察。而论文作者不仅这样做了,恐怕还进行了大量的实验。 这些神经网络中间结果图片具有如此典型的特征,可以脱离出主题内容而成为单纯风格的描述。被敏锐的作者抓住深入研究也就不奇怪了。

最终研究成果确立了卷积神经网络进行图片迁移的两大基础算法:

  • 在神经网络中,确定的抽取某些层代表内容的数字描述,以及另外一些层代表风格的数字描述。
  • 多个层的输出数据,通过公式的计算,拟合到同输入图像相同的色域空间。这个公式即能用于代价函数中原始风格同目标风格之间的对比,也可以变形后通过组合多个风格层,生成新的目标图片。

本系列文章都是尽力不出现数学公式,用代码讲原理。 在《从锅炉工到AI专家(8)》引用的代码中,除了构建神经网络、训练,主要工作是在损失函数降低到满意程度之后,使用网络中间层的输出结果计算、组合成目标图片。原文中对这部分的流程也做了简介。 新的代码来自TensorFlow官方文档。除了程序升级为TensorFlow 2.0原生代码。在图片的产生上也做了大幅创新:使用照片图片训练神经网络,每一阶梯的训练结果,不应用回神经网络(网络的权重参数一直固定锁死的),而把训练结果应用到图片本身。在下一次的训练循环中,使用新的图片再次计算损失值。这样,当损失值最小的时候,训练图片本身就已经是符合我们要求的生成图片。当然本质上,跟前一种方法一样的。但感觉上,结构清晰了很多。这个过程对比起来,大量节省了图片生成的计算。当然,主要原因还是TensorFlow 2.0内置的tf.linalg.einsum方法强大好用。

在特征层的定义上,照片内容的描述使用vgg-19网络的第5部分的第2层卷积输出结果。艺术图片风格特征的描述使用了5个层,分别是vgg-19网络的第1至第5部分第1个网络层的输出结果。在程序中,可以这样描述:

网络层的名称来自于vgg-19网络定义完成后,各层的名称。可以使用如下代码得到所有层的名称:

通常的模型训练,都是使用代价函数比较网络输出结果,和目标标注值的差异,使得差异逐渐缩小。 本例的训练目标比较复杂,可以描述为两条:

  • 生成图片的风格层输出,同艺术图片的风格层输出差异最小
  • 生成图片的内容层输出,同原始照片的内容层输出差异最小化

虽然这个代价函数略微复杂,不过比VAE的代价函数还是简单多了:)

源代码

程序中的注释非常详细。跟以前的程序有一点区别,就是直接使用TensorFlow内置方法读取了图片文件,然后调用jpg解码还原为矩阵。 不过TensorFlow内置的将图像0-255整数值转换为浮点数的过程,会自动将数值变为0-1的浮点小数。 这个过程其实对我们多此一举,因为我们后续的很多计算都需要转换回0-255。

程序的输出结果如下图:

看起来基本达到了设计要求,不过再仔细观察,似乎效果虽然都有了,但画面看上去有一点不干净,有很多小的噪点甚至有了干涉纹。 这是因为,在照片原图和艺术作品原图中,肯定天然就存在有噪点以及图片中本身应当有的小而频繁的花纹。这些内容在通过卷积加强后,两幅照片再叠加,这些噪声就被强化了,从而在生成的图片中体现的非常明显。 这个问题如果在传统算法中可以使用高通滤波。在卷积神经网络中则更容易,是统计总体变分损失值(Total Variation Loss),在代价函数中,让这个损失值降到最小,就抑制了这种噪点的产生。也相当于神经网络具有了降噪的效果。 变分损失是计算图片中,在X方向及Y方向,相邻像素的差值。如果像素差别不大,那差肯定很小甚至趋近于0。如果差别大,当然差值就大。 请使用下面的代码,替换上面程序中训练的部分:

再次执行,所得到的输出图片如下:

效果不错吧?可以换上自己的照片还有自己心仪的艺术作品来试试。 程序中限制了图片宽、高最大值是512,如果设备性能比较好,或者有更大尺寸的需求,可以修改程序中的常量。

(待续...)

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-05-09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 风格迁移
  • 基本原理
  • 源代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档