如果不知道风格转换的,移步 http://blog.csdn.net/hungryof/article/details/53981959 ,瞄上一眼再回来。
如果从得到效果图速度来分的话,可以分为三个阶段。
最初的用神经网络实现的风格转换是需要不断迭代的,不仅速度慢,而且我要在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 Images 和 Perceptual Losses for Real-Time Style Transfer and Super-Resolution . 这也就是网上经常说的 fast style transfer.
大家就想,我怎么直接输入任意A和B,一次前向出来呢?如果能成功,那么速度就不需要考虑了,因为已经到达顶峰了。
style-swap 就是第三阶段的开始。
0.1秒出结果。
效果还是挺不错的嘛~~再放几张。。
用上面素描画形成的效果:
别问这人是谁,一个好友的qq头像,有较多的纹理,就直接拿过来试了试效果。。
论文分为2个部分,第一部分就是常规的迭代方式,第二个是将常规的改成一次前向的方法。
以前不都是认为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,这使得一次前向传播得到的特征图成为可能。
C 和 S 分别代表内容图和风格图, ϕ(⋅) 代表预训练网络(一般VGG19)的前部分网络。 ϕ(C) 就是 C 传入网络中在某一层出来的特征。
因此总的优化目标是:
这里可能会写的比较啰嗦。。因为要讲的很明白,确实需要啰嗦点。。为了简便,提取的块spatial size就3x3吧, relu3_1层是256个通道。下面的三步统称为style-swap.
先看看3.2节实现方法的第一二步干啥:
结论:用 Φ(C) 作为输入, ns 块 ϕj(S)∥ϕj(S)∥ 作为卷积核( ns×256×3×3 )。得到的输出就是所有的 i=1,⋯,nc 的 ϕi(C) 所对应的
第一步得到的输出 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¯¯¯ 作为输入,将 ϕ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。
这是第二部分内容,是核心部分。回忆第一部分的优化目标:
值得注意的是,如果我们训练好Inverse网络,称之为decoder, 然后进行前向传播是,首先是 Φ(C) 经过style-swap结构后得到 Φss(C,S) ,再输入到decoder中,即可得到 Iˆstylized(C,S) 。
至此, 彻底完成一次前向传播出结果的目标!!!!!
在训练时,
为了方便,直接说为什么是用 Φ(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