总说
最近更新:17-5-9 增加Neural style使用Gram矩阵的前提工作
其实这个方向火起来是从2015年Gatys发表的一篇文章 A Neural Algorithm of Artistic Style, 当然了,当时新闻报道还是很标题党的,看的我热血沸腾。。言归正传,虽然只过了短短一年多,但是相关的论文已经有二三十篇了,这些论文在原有的基础上进行了极大的扩展。从最初的Neural Style,到Ulyanov的Texture Networks: Feed-forward Synthesis of Textures and Stylized Images以及李飞飞老师的Perceptual Losses for Real-Time Style Transfer and Super-Resolution。 一般来说主要就是这3篇,后面两篇是差不多的,都是将原来的求解全局最优解问题转换成用前向网络逼近最优解,原版的方法每次要将一幅内容图进行风格转换,就要进行不断的迭代,而后两篇的方法是先将其进行训练,训练得到前向生成网络,以后再来一张内容图,直接输入到生成网络中,即可得到具有预先训练的风格的内容图。 除了这3篇主要的,还有就是将style transfer应用到视频中的,以及一些在改变Gram矩阵的,还有其他很多。这里只写其中某几篇。
下面是最初版本的效果图
Prisma上的一些图片,用的应该是改进版本的方法
额,别跟我提新海诚滤镜,能把人变成二次元?我直接呵呵。你用多了就知道,它的天空就是直接从原著漫画中截取的,就几种,根本不管你现实中有没有云彩。试用“新海诚风”滤镜后 我忍不住戳穿了它。 原理的话,自己百度一下“新海诚滤镜特效的实现解密”就可以了。在此不做评论。
说一下Neural style的工作用Gram的前些工作
在neural style出来之前,Gatys还做了这个工作Texture Synthesis Using Convolutional Neural
Networks,他们发现如果让隐藏层的特征用协方差来进行进行约束,可以得到较好的纹理生成。
他们发现如果用协方差(也就是Gram矩阵)来进行约束隐藏层特征的话,重建出来的特征虽然有些会保持,但是有些可能位置会打散。比如最右侧的一张图,人还是人,但是重建出来相当于“拼图”效果了。这是因为协方差本身就是去除了位置信息。 那么既然协方差可以用于纹理生成,那么如果我们加上 “让生成图的隐藏层特征与原图尽量一样,另一方面让生成图的打散特征与画的打散特征尽量相似”,这就是用神经网络做风格转换的最初想法。这也比较符合“风格”的定义,毕竟风格不应该具有位置信息,一种风格应该是与位置无关的。
注意:Gatys的几篇论文没有解释为什么用Gram矩阵, 其实可以这样认为, 协方差就是一种二阶统计信息, 我们要求输出图的什么信息与风格图相近, 肯定不是feature map上单纯的逐点的相近, Gram矩阵描述的就是全局特征的自相关, 如果输出图与风格图的这种自相关相近, 那么差不多是我们所理解的”风格”. 当然, 其实也可以用很多其他的统计信息进行描绘风格. 这也就是后面有用直方图的, 甚至直接简化成”均值+方差”进行描绘风格的.
A Neural Algorithm of Artistic Style
下面约定
为风格图,
为待转换的图,即内容图。比如
为某张梵高的画,
为某个场景,生成为
,即具有梵高的画的风格的场景图。首先定义两个损失,
和
,前者希望
和
在“风格”上尽量一致,后者则希望
与
在内容上尽量一致。
上式子的 和 为两个损失的平衡参数。我们希望 尽量小,采用梯度下降即可优化。所用的CNN网络是VGG-19。开始训练时,随机生成 同等大小的随机噪声图 ,通过指定不同的层作为content损失的提取层 以及style损失的提取层 ,使得 在 层得到的内容损失 与 尽量一样。同时,使得 在 层得到的风格损失 与 也尽量一样。其中 的具体形式可以由MSE来指定,而 可由对应的Gram矩阵来计算。
Gram矩阵则是计算feature map内部特征的互相关,由于采用的是VGG19较后层的feature map,因此提出的特征具有更多的语义性。
这个论文的方法是采用直接修改随机噪声,使得总体的误差最小。该方法每进行一次前向反向传播,都使得原有噪声得到微调,逐步逼近最终的效果图。主要缺点是速度慢,其次就是如果有大量的图要转换成同一种风格效果,比如我有很多图都想转换成古代文人墨客的山水画效果,我得一张一张的前向反向训练,效率实在太低,针对这一问题,有了下面的论文。
原版代码地址
https://github.com/jcjohnson/neural-style
Texture Networks: Feed-forward Synthesis of Textures and Stylized Images
该论文采用的方法就是根据Neural Style的速度慢的问题。他们通过两个网络,前一个是生成网络
和后一个是描述网络
。这样的话,就是学习
的权值。这就需要大量的内容图
,风格图仍旧是一张
。首先计算内容图的VGG特征
,并全部存储。训练时,假设某一次取的图是:
, 对应的已存储的VGG特征是
, 将内容图
作为输入
的前3个通道内容,
的其他通道是噪声通道,从而得到
,通过
网络得到
,再提取
在描述网络
中的content层的特征
。同时 提取
在描述网络中的style层,得到特征
。之后内容损失
采用的是
和
的MSE,同时风格损失
则先计算
和
各自的Gram矩阵,再求MSE。其中Gram矩阵定义如下:
其中 是第 层的的第 个feature map的竖直向量化表示。可以看出是将每一个feature map相互内积。个人认为,同一层得到的不同个feature map可以认为是“同等非线性复杂程度的feature map”。这种特征对物体的特征表达能力是相近的,可以进行互相关操作,进而综合利用这些特征从而表示图像的风格。
该方法的模型一旦训练好,则生成网络 就会将输入 转换成符合风格 的效果图,同时保持其原本内容的语义信息。从这里就可以看出,如果要想两个图像在语义层次上的信息匹配,那么就要减少高层的特征之间的差异。图像的风格似乎还需要进行Gram矩阵运算,从而找到这些feature map之间的特征的互相关,而这些互相关可以作为一张图片的风格表达。由于Neural Style在content loss和style loss之间是有比例的,不同比例可以设置效果图的风格化程度。但是该论文的方法当模型训练时,两个loss的比例已经固定,然而在测试时仍旧可以将 的噪声通道乘上一个系数 来得到不同的风格化程度。至于为什么要选用内容图 作为 的前3个通道,很简单。因为你最终得到的效果图在内容上是 的,所以图像的概率分布应该类似,所以这样做就是为了加速学习效果。
另一篇与之有异曲同工之妙的是李飞飞的Perceptual Losses for Real-Time Style Transfer and Super-Resolution。只不过后者生成网络没有用多个分辨率的 ,其在style transfer中是先将input进行stride-2的下采样,然后再接上数个残差网络,再用stride为1/2的fractionally convolution进行上采样。而Texture Nets则是采用金字塔模型,其相比Percentual Losses的模型缺少一定程度的自适应性。貌似有一种趋势,普通的Pooling和直接的上/下采样正在逐渐被stride>1的convolution和fractionally convolution所取代。人们解释说这种采样方式可能更加具有自适应性。
图1. Texture Nets的网络
图2. Percentual Losses的G
代码地址
https://github.com/DmitryUlyanov/texture_nets ,他们不久后又发了一篇论文Instance Normalization: The Missing Ingredient for Fast Stylization,因此代码其实实现了他们自己的2篇,也是李飞飞的非官方Torch7实现。
李飞飞的原版代码是chainer框架的:https://github.com/yusuketomoto/chainer-fast-neuralstyle
Incorporating long-range consistency in CNN-based texture generation
该论文解释了Gram矩阵为什么可以用于图像风格提取。其认为feature map经过Gram矩阵后,就是将各个特征进行内积。论文指出:Gram矩阵只能提取静态特征,而且是将整幅图片进行空间平均(spatial averaging)。其对参考图像中的物体的空间排列是完全blind。因此,作者希望能找到一种特征的表达方式,使得物体的空间排列信息保留。论文中采用feature maps
和feature maps的一个空间变换
进行内积。由于
与
具有空间的偏移,进而进行Gram矩阵计算得到互相关,这种互相关包含 的空间偏移,即保留了物体的空间排列信息。
论文中实现了平移和翻转的空间变换,并且通过这些变换计算出来的style loss可以组合,从而得到具有特定对称信息的图片。在某种程度上,可以这样认为该论文通过对Gram的空间变换,从而赋予特征互相关信息额外的空间信息。这种丰富化的互相关信息在可以进行更加有效地风格化表达。
代码
这个论文不太有名。。 https://github.com/guillaumebrg/texture_generation
其实直接用原版代码改改Gram矩阵就可以了。
Deep Identity-aware Transfer of Facial Attributes
这篇论文将GAN与Style Transfer结合在一起,实现了一些人脸属性的风格转换。以前的GAN是由噪声直接通过minmax过程生成与数据集具有类似分布的图片,而Style Transfer是将一幅图的属性迁移到另一幅图上面。如果要实现自身属性的变换,假设原图为 ,属性变换后的图为 ,而由于一般情况下没有可以参照的“风格图(即 的GroundTruth)”,因此无法像常规的Style Transfer那样进行优化。该论文以眼镜去除为例, 为戴眼镜的一些图,想得到去除眼镜的 , 利用其他一些图片 (未戴眼镜)作为引导。由于 和 的概率分布不会相差特别大,因此可以作为一个引导。采用GAN的思想,使得 和 让判别网络 无法分辨。此时即可认为 接近 的GroundTruth。
论文的关键是目标函数,提出了DIAT和DIAT-A。由于前者效果较后者差,而且方法较为繁琐,因而这里只说DIAT-A。个人认为DIAT-A最关键的一点是将属性损失定义在
上。这一点好像是Improved GAN的思想中的Feature Matching。主要是认为,先前的定义在固定的VGG-Face网络中的损失在优化上不容易,如果能在
的隐藏层
进行加入监督项,用以衡量 生成的效果。使得
能在网络
更新时随时更改,此时更易得到更好的
。
更新
时,
固定,此时
是固定的。因此损失是
更新
时,
固定,因此
固定,可去除,最终损失为:
效果图
插入对Gram的解释
Gram矩阵其实是一种度量矩阵。矩阵分析中有这样的定义。
设
是
维欧式空间
是它的一个基,
, 则称
为基
的度量矩阵,也称为Gram矩阵。
重点解释:
因此:对于三维的向量求Gram矩阵,就是要求
,而
就是第i通道与第j通道进行点乘,然后相加。其实专业点就是i通道的feature map与j通道的feature map进行内积。查看内积定义:对于两个竖直向量
, 规定
。所以可以看出,如果将矩阵先进行竖直向量化,然后将其转置,两者进行矩阵相乘,结果就是内积,或是说对应位置点乘,然后相加。
Gram矩阵和卷积网络中的卷积的差别
Gram矩阵是计算每个通道i的feature map与每个通道j的feature map的内积。自然就会得到C*C的矩阵。Gram矩阵的每个值可以说是代表i通道的feature map与j通道的feature map的互相关程度。而卷积网络的卷积其实也是互相关,具体情况见CNN基本问题。 值得注意的是:卷积网络的卷积的实现与框架有关。反正torch是直接将将卷积核卷积的,并不先进行旋转卷积核,即互相关是一样的,而不是信号处理中所说的要先将卷积核旋转180再计算。 原因很简单,因为两种方式的最终学到的权值的差别,也就是旋转180°就可以了,完全不影响效果。
require("torch")
require('nn')
local net = nn.Sequential()
local module = nn.SpatialConvolution(1,1,2,2):noBias()
net:add(module)
local wt = torch.Tensor(2,2)
wt[{1,1}]=5
wt[{1,2}]=6
wt[{2,1}]=7
wt[{2,2}]=8
print(wt)
net:get(1).weight = wt:view(1,1,2,2)
local input = torch.Tensor(2,2)
--local wt = torch.Tensor(2,2)
input[{1,1}]=1
input[{1,2}]=5
input[{2,1}]=3
input[{2,2}]=4
print(net:forward(input:view(1,1,2,2)))
print('xcorr2')
print(torch.xcorr2(input,wt))
print('conv2')
print(torch.conv2(input,wt))
-- 输出结果
[torch.DoubleTensor of size 2x2]
(1,1,.,.) =
88
[torch.DoubleTensor of size 1x1x1x1]
xcorr2
88
[torch.DoubleTensor of size 1x1]
-- 这里确实是卷积核旋转180度,再卷
conv2
81
[torch.DoubleTensor of size 1x1]
结论:卷积网络中的卷积就是互相关,等价于torch.xcorr2或torch.xorr3之类的
,而信号处理说的卷积等价于torch.conv2之类的
更多的style transfer可以看
超越fast style transfer—-任意风格图和内容图0.1秒出结果
后面可能会写 style transfer(二)记录最新的发展。