如果不知道风格转换的,移步 http://blog.csdn.net/hungryof/article/details/53981959 ,瞄上一眼再回来。
1. 以前风格转换速度之尴尬
如果从得到效果图速度来分的话,可以分为三个阶段。
阶段一
最初的用神经网络实现的风格转换是需要不断迭代的,不仅速度慢,而且我要在A图加上B图的风格,就需要分别根据这两幅图进行不断前反向传播,更新输入,效率实在太低。称之为style transfer
阶段二
后来人们就想能不能直接一个前向传播搞定啊~,然后他们想出了,先训练一个G, 这个
阶段三
大家就想,我怎么直接输入任意A和B,一次前向出来呢?如果能成功,那么速度就不需要考虑了,因为已经到达顶峰了。
style-swap 就是第三阶段的开始。
0.1秒出结果。
2. Style-swap的魅力
效果还是挺不错的嘛~~再放几张。。
用上面素描画形成的效果:
别问这人是谁,一个好友的qq头像,有较多的纹理,就直接拿过来试了试效果。。
3. style-swap浅谈
论文分为2个部分,第一部分就是常规的迭代方式,第二个是将常规的改成一次前向的方法。
3.1 style-swap的新方法
以前不都是认为Gram操作就是相当于“风格”的一种表示嘛,他们认为,如果我要得到C图的内容加上S图的风格,那么我希望我的网络输入I在高维度特征
后来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 实现方法
C和
- 先提取一系列块
ϕi(C) 和ϕj(S)。其中i∈nc, j∈ns,其中nc和ns分别是能从ϕi(C)和ϕj(S)抽取的块数。- 对于每块ϕ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)|| - 这步称之为重建Φss(C,S)。这时候我们只需要平均一下那些重叠区域的值就行了。这样就可以得到Φss(C,S),称之为Φss(C,S)的重建。
因此总的优化目标是:
Istylized(C,S)=ARGMINI∈Rh×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)><script id="MathJax-Element-41" type="math/tex"><\phi_i(C),\phi_j(S)></script>是相关操作,也是卷积网络中说的卷积,对于某一块 ϕ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,b 是O中以(a,b) 为中心点的ns*1*1大小的输出张量,那么Oa,b,j是ϕa,b(C)与ϕj(S)的卷积的值。因此我们对于每个位置(a,b)如果第j个通道的值是ns 个值中最大的,将该位置记为1,其他ns−1个通道记为0. 这样就选出了块ϕi(C)对应的最匹配的块ϕj(S)的j值!K¯¯¯a,b,j={1,0,if j=argmaxj′Ka,b,j′ otherwise
没错,第二步就是通道最大值记录为1,其余为0。
实现结束高效方法的第一第二步,我们要的就是K¯¯¯。
该步称之为Maxcoord3.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,j≠200。K¯¯¯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)=ARGMINI∈Rh×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))−H∥2F+λℓ(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
- 对于每块ϕi(C),我们希望选择其最近的style 块ϕj(S), 称之为ϕssi(C,S).