超越fast style transfer----任意风格图和内容图0.1秒出结果

版权声明:要转随便转,如果能加上原文的链接就感谢各位了。( ⊙ o ⊙ ) https://blog.csdn.net/Hungryof/article/details/61195783

如果不知道风格转换的,移步 http://blog.csdn.net/hungryof/article/details/53981959 ,瞄上一眼再回来。

1. 以前风格转换速度之尴尬

如果从得到效果图速度来分的话,可以分为三个阶段。

阶段一

最初的用神经网络实现的风格转换是需要不断迭代的,不仅速度慢,而且我要在A图加上B图的风格,就需要分别根据这两幅图进行不断前反向传播,更新输入,效率实在太低。称之为style transfer

阶段二

后来人们就想能不能直接一个前向传播搞定啊~,然后他们想出了,先训练一个G, 这个G可以让输入I通过G后得到的G(I)是A图加上B图的风格。这个方法还是有很大的问题,那就是我训练的G必须是同一种风格,一般就用一幅风格图B,然后用很多的内容图,不断优化训练G, 最终G有啥用啊,只是“B风格的滤镜”罢了。那我要很多种风格呢?我就要训练很多很多的G,那挺尴尬的。. 代表论文是是 http://blog.csdn.net/hungryof/article/details/53981959 中提到的 Texture Networks: Feed-forward Synthesis of Textures and Stylized ImagesPerceptual Losses for Real-Time Style Transfer and Super-Resolution . 这也就是网上经常说的 fast style transfer.

阶段三

大家就想,我怎么直接输入任意A和B,一次前向出来呢?如果能成功,那么速度就不需要考虑了,因为已经到达顶峰了。
style-swap 就是第三阶段的开始。
0.1秒出结果。
这里写图片描述

2. Style-swap的魅力


这里写图片描述

效果还是挺不错的嘛~~再放几张。。

图片名称

图片名称

用上面素描画形成的效果:

这里写图片描述

这里写图片描述
别问这人是谁,一个好友的qq头像,有较多的纹理,就直接拿过来试了试效果。。

3. style-swap浅谈

论文分为2个部分,第一部分就是常规的迭代方式,第二个是将常规的改成一次前向的方法。

3.1 style-swap的新方法

以前不都是认为Gram操作就是相当于“风格”的一种表示嘛,他们认为,如果我要得到C图的内容加上S图的风格,那么我希望我的网络输入I在高维度特征ϕ(I)(一般用VGG19的某一层的相应的输出,作为I的高维特征)与C图的高维特征ϕ(C)尽量一样,同时希望ϕ(I)进行Gram计算后得到的G(ϕ(I))G(ϕ(S))尽量一样。为什么要用Gram矩阵呢?是否有必要?这些都不知道。
后来Chuan Li的 Combining Markov Random Fields and Convolutional Neural Networks for
Image Synthesis将Style loss改成了MRFs Loss Function,依旧保留content loss。这篇论文第一部分工作其实就单纯用第一种loss了,舍弃了content loss。 这篇论文的详细讲了计算这种Loss的高效方法。这篇论文的主要贡献还是第二部分工作,引入了Inverse Net,这使得一次前向传播得到的特征图成为可能。

3.2 实现方法

CS分别代表内容图和风格图,ϕ()代表预训练网络(一般VGG19)的前部分网络。ϕ(C)就是C传入网络中在某一层出来的特征。

  1. 先提取一系列块ϕi(C)ϕj(S)。其中inc, jns,其中ncns分别是能从ϕi(C)ϕj(S)抽取的块数。
  2. 对于每块ϕi(C),我们希望选择其最近的style 块ϕj(S), 称之为ϕssi(C,S).
    ϕssi(C,S):=ARGMAXϕj(S),j=1,,ns<ϕi(C),ϕj(S)>||ϕi(C)||||ϕj(S)||
  3. 这步称之为重建Φss(C,S)。这时候我们只需要平均一下那些重叠区域的值就行了。这样就可以得到Φss(C,S),称之为Φss(C,S)的重建。

因此总的优化目标是:

Istylized(C,S)=ARGMINIRh×w×d||Φ(I)Φss(C,S)||2F+λTV(I)

3.3 高效方法

这里可能会写的比较啰嗦。。因为要讲的很明白,确实需要啰嗦点。。为了简便,提取的块spatial size就3x3吧, relu3_1层是256个通道。下面的三步统称为style-swap.

3.3.1 实现方法的第一二步解释

先看看3.2节实现方法的第一二步干啥:

ϕssi(C,S):=ARGMAXϕj(S),j=1,,ns<ϕi(C),ϕj(S)>||ϕi(C)||||ϕj(S)||

对于每一块ϕi(C),从nsϕj(S)中找到与其最匹配的块,称之为ϕssi(C,S)。最终我们可以找到ncϕssi(C,S)
可以发现<ϕi(C),ϕj(S)>是相关操作,也是卷积网络中说的卷积,对于某一块ϕi(C) ,其和ns块分别进行相关,不就是将这ns块看成ns个卷积核,每个卷积核就是ϕj(S)(大小是256×3×3)。输入是ϕi(C), 最终输出是ϕi(C)ns个卷积核卷积后的输出,大小为ns×1×1。总共有ncϕi(C),恰恰对应这卷积核在Φ(C)上的位置的所有情况,就是卷积核在Φ(C)上的卷积操作的移动恰恰就能满足这样。

3.3.2 高效方法的第一步

结论:Φ(C)作为输入,nsϕj(S)ϕj(S)作为卷积核(ns×256×3×3)。得到的输出就是所有的i=1,,ncϕi(C)所对应的

ϕj(S),j=1,,ns<ϕi(C),ϕj(S)>||ϕj(S)||

论文的写法更为简便:
Ka,b,j=ϕa,b(C),ϕj(S)ϕi(S)

输出的大小为:ns×w×h, 显然w×h等于nc。为了计算速度,省略了ϕi(C), 因为这不会影响取哪一个最近style块。
该步称之为swap_enc

3.3.3 高效方法的第二步

第一步得到的输出O到底是什么?记Oa,bO中以(a,b)为中心点的ns*1*1大小的输出张量,那么Oa,b,jϕa,b(C)ϕj(S)的卷积的值。因此我们对于每个位置(a,b)如果第j个通道的值是ns个值中最大的,将该位置记为1,其他ns1个通道记为0. 这样就选出了块ϕi(C)对应的最匹配的块ϕj(S)j值!

K¯¯¯a,b,j={1,0,if j=argmaxjKa,b,j otherwise

没错,第二步就是通道最大值记录为1,其余为0
实现结束高效方法的第一第二步,我们要的就是K¯¯¯
该步称之为Maxcoord

3.3.4 高效方法的第三步

K¯¯¯作为输入,将ϕj(S)作为反卷积核。显然反卷积核与刚才的一样,也是ns×256×3×3
对于每个位置(a,b), 只有最匹配的style块才会输出,其他的块都被乘上了0!此时就可以得到ϕssa,b(C,S),比如与ϕ10,10(C)相关程度最大的块是第200块,即max{O10,10,j}的值为O10,10,200,得到K¯¯¯10,10,200=1, 同时 K¯¯¯10,10,j=0,j200K¯¯¯10,10,jϕ(S)反卷积,此时可以提取出ϕssa,b(C,S),就是ϕ200(S)。直到这里我们才弄好了所有的ϕssa,b(C,S), 反卷积后这些ϕssa,b(C,S)是重叠的,重叠部分取平均即可。
此时才真正得到Φss(C,S)
这一步称之为swap_dec

4. 训练Inverse网络

这是第二部分内容,是核心部分。回忆第一部分的优化目标:

Istylized(C,S)=ARGMINIRh×w×d||Φ(I)Φss(C,S)||2F+λTV(I)

我们希望该Inverse网络f无论对于任何输入H (这些输入包括Φ(C)或是Φ(S)或是Φss(C,S) ), 我们都能使得f(H)能得到Istylized(C,S)。 即Φ(f(H))H尽量一样。因此有:
arginff=EH[Φ(f(H))H2F+λ(f(H))]

值得注意的是,如果我们训练好Inverse网络,称之为decoder, 然后进行前向传播是,首先是Φ(C)经过style-swap结构后得到Φss(C,S),再输入到decoder中,即可得到Iˆstylized(C,S)

至此, 彻底完成一次前向传播出结果的目标!!!!!

4.1 训练时代码的细节

在训练时,

Enc(4,256,64,64)latent_beforeswapLoss(8,256,64,64)latent_after(8,256,64,64)recons_latentdec(8,3,256,256)recons_inputEnc

比如我一下子输入2个content图和2个style图,然后latent_before是(4, 256, 64, 64),经过swap结构,得到latent_after是(8,256,64,64)。注意的是latent_after的前4个仍旧是latent_before, 而后4个是Φss(C,S)。更加准确的说:
latent_before[1]和latent_before[2]是Φ(C1)Φ(C2),而latent_before[3]和latent_before[4]是Φ(S1)Φ(S2)。 然后传入swap中,得到latent_after,latent_after[1:4]与latent-before一致,latent_after[5:8]分别为Φ(C1,S1),Φ(C1,S2),Φ(C2,S1),Φ(C2,S2)。得到的Loss是MSE(latent_after, recons_latent)。具体的含义见下图

Enc[Φ(C),Φ(S)]swapLoss[Φ(C),Φ(S),Φss(C,S)][Φ(f(Φ(C))),Φ(f(Φ(S))),Φ(f(Φss(C,S)))]Dec[f(Φ(C)),f(Φ(S)),f(Φss(C,S))]Enc

因此我们当然是希望Φ(f(Φ(C)))Φ(C)尽量接近,Φ(f(Φ(S)))Φ(S)尽量接近,Φ(f(Φss(C,S))Φss(C,S)尽量接近,这样才能实现对于Φ的反转!

为什么是用[Φ(C),Φ(S),Φ(C,S)][Φ(f(Φ(C))),Φ(f(Φ(S))),Φ(f(Φss(C,S)))]进行求Loss,再反向传播呢?

为了方便,直接说为什么是用Φ(C,S)Φ(f(Φss(C,S)))。其实我们希望优化Dec,那么最好是希望f(Φ(C,S))C在高层语义上尽量一样。高层语义自然要将f(Φ(C,S))C进行升维,所以把f(Φ(C,S))再次输入到Φ中,与Φ(C)相比,用MSE就行了。
其实这种思想和fast neural style是类似的,或是可以看成是fast neural style的升级版本。fast neural style使用G网络生成G(x),使用D网络提供Loss形式。希望在高层语义特征上D(G(x))D(C)尽量接近,同时希望在高层语义上Gram(D(G(x)))Gram(D(S))尽量接近。那么style-swap也是如此。Enc就是D,而Dec就是G。不过更加准确的说Dec不仅仅是G,而是G的升级版,因为以前的G只是针对一种style进行训练,而这里的Dec是针对大量的style一起训练。

附录:
Fast Patch-based Style Transfer of Arbitrary Style

没有更多推荐了,返回首页