从这部分开始利用TensorFlow进行实际应用,将会慢慢的把最新的东西一边学习一边整理一边实现,计划是初期的代码都利用tensorflow的基本API完成,后期建立大的网络结构的时候引入Keras等高等级API。
这一节主要是利用tensorflow实现style transfer,这个学习CNN的时候都会看到,原论文在这里
程序的github地址在 —-这里—-,和原来一样几乎都是用notebook写的,注释都在里面。
。
首先从原理上了解一下这个过程是怎么实现的,首先我们需要一个训练好的CNN,文章里用的VGGNet-16,然后我们要有一个概念就是在CNN可视化的结果中,低层保留的内容信息比较多,而高层更多的是从整体角度上的抽象,所以我们可以利用这个概念来得到我们的内容信息和纹理信息并将两者相结合得到一个全新的图片。而且我们原来训练CNN的时候一直反向传播调整的是我们的网络结构参数如w和b,这里却目标是对一个输入的白噪声图片进行不断调整,给其加入内容和纹理信息。当然为了实现这个肯定需要一个损失函数,而损失函数就是整个风格转换的核心内容。
1、获取VGGNet-16
首先我们需要定义一个VGGNet-16网络并加载训练好的参数,其格式如下:
只要把这个下载的.mat模型和程序放在同一个目录下即可。
2、损失函数计算
我们说过损失函数是最重要的部分,那么怎么损失函数形式是怎样的呢?因为我们有两个目标:内容(content)和纹理(style),所以我们需要两个损失函数,而且我们还需要在这两个损失函数之间进行协调,看是纹理更重要还是保留内容更重要,于是有:
其中α和β是权重,因为主要还是集中在tensorflow上,具体的计算原理可以看 这里的损失函数讲解的部分,不过这个写的不是很好,希望能尽可能理解其含义最好还是看看论文。其实比较难理解的是为什么要用Gram矩阵来衡量相关性,可以参考 这个。
3、计算技巧
我们的程序中用了两种调节方法,一种是初始化待调整图为白噪声图片,另一种方法是在content_image上加高比例的白噪声,第二种方法调节的时候比第一种略快(后来测试了一下,其实差不多),但是第一种的好处是更抽象。而且这时候对应的损失函数也会有所不同,比如第二种方法可已设style损失的权重更大,因为content已经差不多可以了,这个比例可以在100:1左右。但是第一种方法要自己试一试,但是相反应该是content的权重略大一点。
还有就是学习率可以开始调的大一点,这样图片变化的也更快一点。
参考:
http://blog.csdn.net/elaine_bao/article/details/50502929
http://blog.csdn.net/aichipmunk/article/details/54175030
http://blog.csdn.net/hungryof/article/details/61195783
http://blog.csdn.net/hungryof/article/details/53981959
https://github.com/chiphuyen/tf-stanford-tutorials/blob/master/assignments/style_transfer/style_transfer_sols.py