Neural Style开辟了计算机与艺术的道路,可以将照片风格化为名家大师的画风。然而这种方法即使使用GPU也要花上几十分钟。Fast Neural Style则启用另外一种思路来快速构建风格化图像,在笔记本CPU上十几秒就可以风格化一张图片。我们来看看这是什么原理。
传统的Neural Style基于VGG构建了一个最优化模型。它将待风格化图片和风格化样本图放入VGG中进行前向运算。其中待风格化图像提取relu4特征图,风格化样本图提取relu1,relu2,relu3,relu4,relu5的特征图。我们要把一个随机噪声初始化的图像变成目标风格化图像,将其放到VGG中计算得到特征图,然后分别计算内容损失和风格损失。内容损失函数为:

Lcontent=12M∑k∑i,j(Flk−Plk)2

L_{content}=\frac{1}{2M}\sum_k\sum_{i,j}{(F^l_k-P^l_k)^2}P和F一个表示目标图像的特征图,一个表示待风格化原图的特征图,l表示是哪个layer,k表示第几个特征图,减法是矩阵元素减法,i,j是矩阵坐标,M是一个可以自由发挥想象的分母,这里定义一个原图与生成图像在l层的所有特征图的欧氏距离之和。风格损失函数为:

Lstyle=∑lwl1N(∑k1,k2∑i,jFlk1Flk2−∑k1,k2∑i,jPlk1Plk2)2

L_{style}=\sum_l {w_l\frac{1}{N}(\sum_{k1,k2}\sum_{i,j} F_{k1}^lF_{k2}^l-\sum_{k1,k2}\sum_{i,j} P_{k1}^lP_{k2}^l)^2}P和F一个表示目标图像的特征图,一个表示风格化样本图的特征图,l表示是哪个layer, wlw_l是不同层特征损失的权重参数(一般是相等的),k表示第几个特征图,乘法是矩阵元素乘法,生成的Gram矩阵是一种未中心化的协方差矩阵,i,j是矩阵坐标,N是一个可以自由发挥想象的分母(虽然原文有明确的值,但是感觉跟原理没关系)。计算和求和Gram矩阵做法其实简单,假设特征图是C个[H,W]的矩阵,那么合并展开为[C,HxW]的矩阵 Φ\Phi,Gram矩阵总的求和就是 ∑ΦΦT\sum\Phi \Phi ^T,这里是矩阵乘法。
有了上面两个损失函数,就可以构建感知损失函数:

Lperceptual=αLstyle+βLcontent+γLtv

L_{perceptual}=\alpha L_{style}+\beta L_{content}+\gamma L_{tv}第三项是噪声约束,不用也可以, α,β,γ\alpha,\beta,\gamma可以按照个人喜好来设置,这是控制输出图像风格化程度的参数。最小化这个感知损失函数,我们就把输入的随机噪声图像变成了风格化的图片。这个最优化模型的收敛速度非常慢,GPU都要计算好久。
Fast Neural Style则可以在普通笔记本电脑中十几秒运算出一个风格化图像。在一些科普文中是这样解释:Neural Style每次风格化都重新训练了一次生成过程,把这个过程提前做好,就可以加速风格化。我觉得这个说法有点奇怪,来看看原文流程图:

这个模型有两个部分,后面一个loss network就是普通Neural Style的VGG网络,这里只当做计算loss的网络,不进行训练;前面一个Image Transform Network一般是一个deep residual CNN,即喜闻乐见的深度残差网络,要训练这个网络。然而,深度残差网络的结构跟VGG是不同,训练深度残差网络不等于提前做好VGG生成过程。这里的思想,我认为是一种生成-判别模型,有生成对抗网络GAN的影子:深度残差网络-》生成模型,VGG-》判别模型。
下面的代码来自国人大神 hzy46,我将预测部分的代码已经升级迁移到python3 tensorflow 1.0正式版:

def resize_conv2d(x, input_filters, output_filters, kernel, strides, training):'''An alternative to transposed convolution where we first resize, then convolve.See http://distill.pub/2016/deconv-checkerboard/For some reason the shape needs to be statically known for gradient propagationthrough tf.image.resize_images, but we only know that for fixed image size, so weplumb through a "training" argument'''with tf.variable_scope('conv_transpose') as scope:height = x.get_shape()[1].value if training else tf.shape(x)[1]width = x.get_shape()[2].value if training else tf.shape(x)[2]new_height = height * strides * 2new_width = width * strides * 2x_resized = tf.image.resize_images(x, [new_height, new_width], tf.image.ResizeMethod.NEAREST_NEIGHBOR)return conv2d(x_resized, input_filters, output_filters, kernel, strides)def residual(x, filters, kernel, strides):with tf.variable_scope('residual') as scope:conv1 = conv2d(x, filters, filters, kernel, strides)conv2 = conv2d(tf.nn.relu(conv1), filters, filters, kernel, strides)residual = x + conv2return residualdef instance_norm(x):epsilon = 1e-9mean, var = tf.nn.moments(x, [1, 2], keep_dims=True)return tf.div(tf.subtract(x, mean), tf.sqrt(tf.add(var, epsilon)))with tf.variable_scope('conv1'):conv1 = tf.nn.relu(instance_norm(conv2d(image, 3, 32, 9, 1)))with tf.variable_scope('conv2'):conv2 = tf.nn.relu(instance_norm(conv2d(conv1, 32, 64, 3, 2)))with tf.variable_scope('conv3'):conv3 = tf.nn.relu(instance_norm(conv2d(conv2, 64, 128, 3, 2)))with tf.variable_scope('res1'):res1 = residual(conv3, 128, 3, 1)with tf.variable_scope('res2'):res2 = residual(res1, 128, 3, 1)with tf.variable_scope('res3'):res3 = residual(res2, 128, 3, 1)with tf.variable_scope('res4'):res4 = residual(res3, 128, 3, 1)with tf.variable_scope('res5'):res5 = residual(res4, 128, 3, 1)with tf.variable_scope('deconv1'):deconv1 = tf.nn.relu(instance_norm(resize_conv2d(res5, 128, 64, 3, 2, training)))with tf.variable_scope('deconv2'):deconv2 = tf.nn.relu(instance_norm(resize_conv2d(deconv1, 64, 32, 3, 2, training)))with tf.variable_scope('deconv3'):deconv3 = tf.nn.tanh(instance_norm(conv2d(deconv2, 32, 3, 9, 1)))y = (deconv3 + 1) * 127.5

明显可以看到这里用了反转卷积conv2d_transpose,可以用resize_conv2d代替,也就是先放大图像然后卷积,数学意义相同,工程效果比直接conv2d_transpose要好,这是生成模型的标配啊!整个模型中,深度残差网络不断从原图生成目标风格化图像,然后VGG不断反馈深度残差网络存在的问题,从而不断优化生成网络,直到生成网络生成标准的风格化图像。最后要投入使用的时候,后面VGG判别网络根本不需要,只需要前面的深度残差生成网络,就像GAN一样。
Fast Neural Style的优点有:

  • 生成速度快。
  • 训练好的模型文件不大,载入简单。不需要VGG网络,那个tensorflow model有500MB。

缺点有:

  • 训练速度很慢。官方推荐用coco数据集训练深度残差网络,这个数据集小的也有13GB,运行要几十个小时。
  • 一个生成网络只能生成一种风格化图像。我们训练生成网络,使用的风格化图像只能用一种。

由于训练的太慢,我就直接用hzy46大神的训练好的model。经过训练后的图像:
INFO:tensorflow:Elapsed time: 1.455744s
你们看,2015 macbook pro低配版上只要1.5秒钟就完成了这个252x252的图像的风格化。
https://github.com/artzers/MachineLearning/tree/master/Tensorflow/fast-neural-style

【机器学习】Tensorflow:理解和实现快速风格化图像fast neural style相关推荐

  1. 【人工智能专题】基于 GAN 的艺术风格化——图像风格迁移

    原文:https://mp.weixin.qq.com/s?__biz=MzAxMzEwMDM2Mg==&mid=2652847175&idx=3&sn=51dcb41bc5c ...

  2. 在Tensorflow中使用深度学习构建图像标题生成器

    by Cole Murray 通过科尔·默里(Cole Murray) 在Tensorflow中使用深度学习构建图像标题生成器 (Building an image caption generator ...

  3. 风格化图像_【技术综述】人脸风格化核心技术与数据集总结

    我的新书<深度学习之人脸图像算法>市了,欢迎大家关注! 言有三新书来袭,业界首次深入全面讲解深度学习人脸图像算法​mp.weixin.qq.com 人脸图像是计算机视觉领域中研究历史最久, ...

  4. 图形图像处理-之-高质量的快速的图像缩放 中篇 二次线性插值和三次卷积插值

    from:http://blog.csdn.net/housisong/article/details/1452249 图形图像处理-之-高质量的快速的图像缩放 中篇 二次线性插值和三次卷积插值    ...

  5. 使用Python+Tensorflow的CNN技术快速识别验证码

    北京 上海巡回站 | NVIDIA DLI深度学习培训 2018年1月26/1月12日 NVIDIA 深度学习学院 带你快速进入火热的DL领域 阅读全文                        ...

  6. VS2015+OpenCV3.4.5+QT5.12+WINDOWS10用c++调用tensorflow训练好的.pb文件图像检测

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_31806049/article/ ...

  7. 利用TensorFlow搭建CNN,DNN网络实现图像手写识别,总结。

    利用TensorFlow搭建CNN,DNN网络实现图像手写识别,总结. 摘要 一.神经网络与卷积网络的对比 1.数据处理 2.对获取到的数据进行归一化和独热编码 二.开始我们的tensorflow神经 ...

  8. 机器学习是什么?我对机器学习的理解

    第一次听到机器学习这个名词的时候,很恍惚,不知道它到底是什么? 我对机器学习的理解 机器学习是什么? 机器学习的工作流程是什么? 在机器学习中对于数据集的理解 数据分割 什么是特征工程? 特征工程分类 ...

  9. 机器学习数据预处理之离群值/异常值:图像对比法

    机器学习数据预处理之离群值/异常值:图像对比法 garbage in,garbage out. 异常值是分析师和数据科学家常用的术语,因为它需要密切注意,否则可能导致错误的估计. 简单来说,异常值是一 ...

  10. 为ListView组件加上快速滑块以及修改快速滑块图像

    本文转载自:http://blog.csdn.net/ouyang_peng/article/details/46919723 作者:欧阳鹏  欢迎转载,与人分享是进步的源泉! 转载请保留原文地址:h ...

最新文章

  1. 【单片机】时钟周期 器械周期 指令周期的关系
  2. 这套Java调优方案太顶了!同时支撑10个618大促都不是问题
  3. Solaris10下NDOUtils的安装
  4. 详析数字图像中高斯模糊理论及实现
  5. android程序名称,Android应用程序名称带上标
  6. 关于在新建的package中用SetContentView()函数时无法找到已创建的R.layout的布局文件的的问题的解决办法
  7. 华为注册鸿蒙商标与三海经,华为注册了一本《山海经》?除了鸿蒙商标,还有很多...
  8. c++数据结构队列栈尸体_数据结构-第三章:栈和队列(栈的应用、括号匹配、表达式转换)...
  9. 关于用java做微信机器人的艰辛过程
  10. springmvc 同时匹配.do,.action
  11. Echarts数据可视化开发参数配置全解
  12. 编程开发必须用到的工具书MSDN中文版
  13. 计算机视觉:图像分割算法综述总结
  14. 张量分解--非负矩阵分解 (NMF)
  15. JDBC中connection.isClosed 和 connection.isValid的区别
  16. 肿瘤基因检测的解读流程
  17. 永续公债(or统一公债)的麦考利久期(Macaulay Duration)的计算
  18. python中三角函数运算符_Python入门之三角函数sin()函数实例详解
  19. 手机商城系统开发流程_各系统业务逻辑关系架构图_OctShop
  20. 独立安装的黑莓模拟器的上网方法

热门文章

  1. 17AHU排位赛1 C题(经典DP)
  2. EditText实现输入自定义表情
  3. Symbian OS 源码下载方式
  4. 【数据压缩】作业1:分析浊音清音爆破音的时域和频域特性以及RGB熵的计算
  5. 静静的推荐分数 20作者 陈越单位 浙江大学
  6. A Jupyter widget could not be displayed because the widget state could not be found.
  7. 华硕服务器 bios 内存 1333 显示 800,华硕服务器bios设置
  8. 人均劳动生产率的单位_生产率的单位是什么?
  9. mysql入库字段编码导致报错 Incorrect string value: ‘\xF0\x9F\x91\xBD\xF0\x9F...‘ for column ‘content‘
  10. Tomcat中Session钝化与活化实现步骤