丰富的线上&线下活动,深入探索云世界
做任务,得社区积分和周边
最真实的开发者用云体验
让每位学生受益于普惠算力
让创作激发创新
资深技术专家手把手带教
遇见技术追梦人
技术交流,直击现场
海量开发者使用工具、手册,免费下载
极速、全面、稳定、安全的开源镜像
开发手册、白皮书、案例集等实战精华
为开发者定制的Chrome浏览器插件
图像风格迁移是指利用算法学习著名画作的风格,然后再把这种风格应用到另一张图片上的技术。
风格迁移的两个要素是内容与风格。我们希望达成的效果是,输入一张图像,程序可以把它转化为带有某种特定风格的图像,同时保留图像中原有的内容信息,而这种风格应该是由人工智能从该类风格的图像中学习得到。
下面介绍两种简单的方法,它们并没有用到GAN,甚至第一种方法竟甭神经网络。
导读:
这是一种颜色风格迁移。首先引入Lab色彩空间的概念。色彩空间是对颜色的一种量化描述。例如常见的RGB颜色空间,R、G、B分别为红、绿、蓝三个分量。而Lab色彩空间,L为亮度,其值从0到100;a为红色到绿色之间的变化区域,正数时代表红色,负数时代表绿色,其值从-120到120;b为黄色到蓝色之间的变化区域,正数时代表黄色,负数时代表蓝色,其值从-120到120。
之所以将图像从RGB空间转换到Lab空间,是因为Lab图像表示亮度的L通道反映了图像的内容,要做风格转换,只需保留L通道,而将a和b通道替换。
可以通过学习风格图像从L通道到a、b通道的映射,即由对应的L值来决定a、b的值。
仅考虑单个L值到单个a\b值的映射太单一,我们用3x3的块——L值以及八个邻域的值,共9个值。
用KNN来实现这个映射,在风格图像的L通道中找到K个与内容图像最接近的块,将风格图像对应的a、b值加权求和作为迁移图像的a、b值,权重为块像素之差的平方和的倒数。
优点是内容图像和迁移图像可以不同尺寸,并且一次可以使用多张风格图像,实现多种风格的迁移。
第二种方法虽然也是一种老方法,但是它的做法对我来说反而是新奇的。
一般,我们用神经网络,是将网络的参数作为自变量,构造损失函数更新它们。但是现在反了过来,以输入作为自变量!
网络是预训练的,使用时固定参数不变,用于提取内容图像、风格图像以及迁移图像的特征,再用这些特征构造内容损失和风格损失。最小化迁移图像和内容图像的内容损失;最小化迁移图像和风格图像的风格损失。
首先,初始化迁移图像=一部分内容图像+一部分噪声。
由于我们只使用卷积部分提取特征,所以对代码作出一点修改。
计算内容损失使用层conv4_2,计算风格损失使用层conv1_1,conv2_1,conv3_1,conv4_1,conv5_1。
将所有最大池化改为平均池化,以改善梯度流。
defcontentloss(content,transfer):return0.5*P.sum((content-transfer)**2)风格损失略复杂,先引入格拉姆矩阵(GramMatrix)的概念。格拉姆矩阵由展平后的特征图两两作内积得到。
其中i、j是特征图通道的编号,k是展平后特征图的长度,也就是展平前的长x宽。
故风格损失构造为
defstyleloss(style,transfer,weight):loss=0foriinrange(len(style)):gram_style=gram(style[i])gram_transfer=gram(transfer[i])_,c,h,w=style[i].shapeloss+=weight[i]*P.sum((gram_style-gram_transfer)**2)/(2*c*h*w)**2returnlossdefadam(image_transfer,m,v,g,t,η,β1=0.9,β2=0.999,ε=1e-8):m=β1*m+(1-β1)*gv=β2*v+(1-β2)*g**2m_hat=m/(1-β1**t)v_hat=v/(1-β2**t)image_transfer-=η*m_hat/(P.sqrt(v_hat)+ε)returnimage_transfer,m,v(四)、生成图像定义一个训练函数,由于只更新迁移图像参数,因此只需要计算一次内容图像与风格图像的特征,而迁移图像的特征在每次更新迭代中都会发生变化:
上述方法训练虽然简单,但是只能处理相同大小的内容图像与风格图像,在某些应用场景中并不方便,PaddleHub也提供了图像风格迁移的接口,实现简单方便且高效,代码如下:
【学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。】