首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何用神经网络实现照片的风格转换

如何用神经网络实现照片的风格转换

作者头像
HuangWeiAI
发布于 2020-04-14 07:32:41
发布于 2020-04-14 07:32:41
96500
代码可运行
举报
文章被收录于专栏:浊酒清味浊酒清味
运行总次数:0
代码可运行

1

在今天的文章中,我们将实现风格转换效果。为了做到这一点,我们必须更深入地理解卷积神经网络及其各层是如何工作的。在本文的最后,您将能够创建并运行一个风格转换程序。

02

什么是风格转换

在我们开始我们的风格转换应用程序之前,让我们介绍一下我们正在努力实现的目标。

给定一个输入图像和一个样式图像,我们可以用原始内容和一个新的样式来计算一个输出图像。就像下面这个例子:

波士顿的天际线与梵高的《星夜》交相辉映

03

如何实现风格转换

  1. 我们获取输入图像和风格图像,并将它们调整为相同的形状。
  2. 我们加载一个预先训练好的卷积神经网络(VGG16)。
  3. 知道我们可以区分负责样式的层(基本形状、颜色等)和负责内容的层(特定于图像的特性),我们就可以分离这些层来独立处理内容和样式。
  4. 然后我们把我们的任务设置为一个优化问题,我们要最小化:
  • 内容loss(输入和输出图像之间的距离-我们努力保持内容)
  • 风格loss(样式与输出图像之间的距离—我们努力应用新样式)
  • total variation loss(正则化-对输出图像进行去噪的空间平滑度)

5. 最后,我们使用L-BFGS算法设置梯度并进行优化。

04

代码讲解

你可以在GitHub上找到风格转换项目的完整代码库:

https://github.com/gsurma/style_transfer

输入:

代码语言:javascript
代码运行次数:0
运行
复制
# San Francisco
san_francisco_image_path = "https://www.economist.com/sites/default/files/images/print-edition/20180602_USP001_0.jpg"
#Input visualization

input_image = Image.open(BytesIO(requests.get(san_francisco_image_path).content))
input_image = input_image.resize((IMAGE_WIDTH, IMAGE_HEIGHT))
input_image.save(input_image_path)
input_image

下图就是输入图片:

风格:

代码语言:javascript
代码运行次数:0
运行
复制
# Warsaw by Tytus Brzozowski, http://t-b.pl
tytus_image_path = "http://meetingbenches.com/wp-content/flagallery/tytus-brzozowski-polish-architect-and-watercolorist-a-fairy-tale-in-warsaw/tytus_brzozowski_13.jpg"
# Style visualization 
style_image = Image.open(BytesIO(requests.get(tytus_image_path).content))
style_image = style_image.resize((IMAGE_WIDTH, IMAGE_HEIGHT))
style_image.save(style_image_path)
style_image

风格图片:

数据预处理

代码语言:javascript
代码运行次数:0
运行
复制
# Data normalization and reshaping from RGB to BGR
input_image_array = np.asarray(input_image, dtype="float32")
input_image_array = np.expand_dims(input_image_array, axis=0)
input_image_array[:, :, :, 0] -= IMAGENET_MEAN_RGB_VALUES[2]
input_image_array[:, :, :, 1] -= IMAGENET_MEAN_RGB_VALUES[1]
input_image_array[:, :, :, 2] -= IMAGENET_MEAN_RGB_VALUES[0]
input_image_array = input_image_array[:, :, :, ::-1]

style_image_array = np.asarray(style_image, dtype="float32")
style_image_array = np.expand_dims(style_image_array, axis=0)
style_image_array[:, :, :, 0] -= IMAGENET_MEAN_RGB_VALUES[2]
style_image_array[:, :, :, 1] -= IMAGENET_MEAN_RGB_VALUES[1]
style_image_array[:, :, :, 2] -= IMAGENET_MEAN_RGB_VALUES[0]
style_image_array = style_image_array[:, :, :, ::-1]

网络模型:

代码语言:javascript
代码运行次数:0
运行
复制
# Model
input_image = backend.variable(input_image_array)
style_image = backend.variable(style_image_array)
combination_image = backend.placeholder((1, IMAGE_HEIGHT, IMAGE_SIZE, 3))

input_tensor = backend.concatenate([input_image,style_image,combination_image], axis=0)
model = VGG16(input_tensor=input_tensor, include_top=False)

05

结果

经过运行程序,我们获得了如下结果:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python与机器学习之路 微信公众号,前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
挑战程序竞赛系列(37):3.4利用数据结构高效求解
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/77587840
用户1147447
2019/05/26
4490
挑战程序竞赛系列(88):3.6平面扫描(2)
用户1147447
2018/01/02
5680
挑战程序竞赛系列(88):3.6平面扫描(2)
挑战程序竞赛系列(85):3.6极限情况(2)
摘要总结:本文主要介绍了如何通过Java和Python分别实现一个排序算法,比较它们的性能差异。同时,还介绍了如何利用工具类实现一个高精度加法器。
用户1147447
2018/01/02
6880
挑战程序竞赛系列(85):3.6极限情况(2)
挑战程序竞赛系列(91):3.6凸包(2)
本文介绍了凸包相关的一系列算法,包括如何计算凸包、如何求凸包的顶点、如何求凸包的面积和如何求凸包的 法向量。同时,还介绍了如何使用这些算法来解决几何问题,例如求一个凸多边形的面积和求一个曲线的曲率。
用户1147447
2018/01/02
7100
挑战程序竞赛系列(91):3.6凸包(2)
挑战程序竞赛系列(90):3.6凸包(1)
挑战程序竞赛系列(90):3.6凸包(1) 传送门:POJ 2187: Beauty Contest 题意: 平面上有N个牧场。i号牧场的位置在格点(xi,yi)(x_i, y_i),所有牧场的位置
用户1147447
2018/01/02
8150
挑战程序竞赛系列(90):3.6凸包(1)
挑战程序竞赛系列(58):4.6树上的分治法(1)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/77941761
用户1147447
2019/05/26
4190
挑战程序竞赛系列(59):4.6树上的分治法(2)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/77945137
用户1147447
2019/05/26
3480
挑战程序竞赛系列(54):4.4 双端队列(1)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/77881703
用户1147447
2019/05/26
3030
挑战程序竞赛系列(46):4.1Polya 计数定理(2)
思路: 首先能想到的是Polya计数,但是此题的trick在于还需要控制A或B不能连续出现的次数。
用户1147447
2019/05/26
3330
挑战程序竞赛系列(43):4.1矩阵 高斯消元
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/77747706
用户1147447
2019/05/26
5990
挑战程序竞赛系列(53):4.4 栈
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/77878355
用户1147447
2019/05/26
3780
挑战程序竞赛系列(44):4.1计数 欧拉函数
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/77763235
用户1147447
2019/05/26
3600
挑战程序竞赛系列(39):4.1模运算的世界(2)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/77684806
用户1147447
2019/05/26
3340
挑战程序竞赛系列(81):4.3 LCA(1)
挑战程序竞赛系列(81):4.3 LCA(1) 传送门:POJ 2763: Housewife Wind 题意: XX村里有n个小屋,小屋之间有双向可达的道路相连,所构成的图是一棵树。通过连接ai
用户1147447
2018/01/02
8700
挑战程序竞赛系列(81):4.3  LCA(1)
挑战程序竞赛系列(89):3.6平面扫描(3)
挑战程序竞赛系列(89):3.6平面扫描(3) 传送门:POJ 3292: Rectilinear polygon 题意参考hankcs: http://www.hankcs.com/progra
用户1147447
2018/01/02
6780
挑战程序竞赛系列(89):3.6平面扫描(3)
挑战程序竞赛系列(84):3.6极限情况(1)
本文介绍了使用Java编写的一个解决矩形重叠问题,主要思路是使用空间换时间的策略,通过预处理将矩形按照面积从小到大排序,然后使用动态规划的思想解决,具体实现上使用了双指针扫描的方法。同时,对于面积相同的矩形,使用了排序后处理的方法,可以在线性时间内解决,最后给出了测试用例和性能测试结果。
用户1147447
2018/01/02
5980
挑战程序竞赛系列(84):3.6极限情况(1)
挑战程序竞赛系列(94):3.6凸包(5)
本文介绍了凸包问题的一种解决方案,通过计算每个点与对角线的距离来排序点,从而找到凸包。同时介绍了基于排序的凸包算法,通过排序三次即可找到凸包。
用户1147447
2018/01/02
6720
挑战程序竞赛系列(94):3.6凸包(5)
挑战程序竞赛系列(42):4.1模运算的世界(4)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/77721125
用户1147447
2019/05/26
4050
挑战程序竞赛系列(38):4.1模运算的世界(1)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/77679432
用户1147447
2019/05/26
3470
挑战程序竞赛系列(72):4.7高度数组(2)
摘要总结:本文介绍了一种用于字符串比较的评分算法,该算法基于Levenshtein距离,可以用于比较字符串的相似度。该算法通过动态规划求解,并利用一个数组来存储累计的编辑距离,最后返回比较结果。
用户1147447
2018/01/02
5440
挑战程序竞赛系列(72):4.7高度数组(2)
推荐阅读
相关推荐
挑战程序竞赛系列(37):3.4利用数据结构高效求解
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档