图像风格迁移是指,将一副内容图的内容,和一幅或多幅风格图的风格融合在一起,从而生成一些有意思的图片。
我们使用 TensorFlow 和 Keras 分别来实现图像风格迁移,主要用到深度学习中的卷积神经网络,即CNN。
安装包。
pip install numpy scipy tensorflow keras
再准备一些风格图片,和一张内容图片。
为了将风格图的风格和内容图的内容进行融合,所生成的图片,在内容上应当尽可能接近内容图,在风格上应当尽可能接近风格图。因此需要定义 内容损失函数 和 风格损失函数,经过加权后作为总体损失函数。
实现步骤如下:
- 随机产生一张图片
- 在每轮迭代中,根据总体损失函数,调整图片的像素值
- 经过多轮迭代,得到优化后的图片
CNN是一类深度学习模型的统称,而VGG是其中一种经典的卷积神经网络模型,它在图像分类任务中表现出色,成为了深度学习模型的重要代表之一。
这里我们使用 conv4_2 的输出作为图像的内容表示,定义内容损失函数如下:
这是内容损失函数的公式表示,其中 公式表示如下:
L c o n t e n t ( p ⃗ , x ⃗ , l ) = 1 2 ∑ i , j ( F i j l − P i j l ) 2 \mathcal{L}_{content}(\vec{p}, \vec{x}, l) = \frac{1}{2} \sum_{i,j} (F_{ij}^l - P_{ij}^l)^2 Lcontent(p,x,l)=21i,j∑(Fijl−Pijl)2
风格是一个很难说清楚的概念,可能是笔触、纹理、结构、布局、用色等等。
这里我们使用卷积层各个特征图之间的互相关作为图像的风格,以conv1_1为例:
风格损失函数用于衡量两张图片之间的风格相似程度,可以用于图像风格转换等任务中。下面是风格损失函数的公式表示:
L s t y l e ( p ⃗ , x ⃗ ) = ∑ l = 1 L w l ⋅ 1 4 N l 2 M l 2 ∑ i = 1 N l ∑ j = 1 N l ( G i j l − A i j l ) 2 \mathcal{L}_{style}(\vec{p}, \vec{x}) = \sum_{l=1}^{L} w_l \cdot \frac{1}{4N_l^2M_l^2} \sum_{i=1}^{N_l} \sum_{j=1}^{N_l} (G_{ij}^l - A_{ij}^l)^2 Lstyle(p,x)=l=1∑Lwl⋅4Nl2Ml21i=1∑Nlj=1∑Nl(Gijl−Aijl)2
Gram 矩阵的计算方法如下:
G i j l = ∑ k = 1 M l F i k l ⋅ F j k l G_{ij}^l = \sum_{k=1}^{M_l} F_{ik}^l \cdot F_{jk}^l Gijl=k=1∑MlFikl⋅Fjkl
风格损失函数的含义是,计算参考图片和待转换图片在卷积神经网络的不同层中的 Gram 矩阵之间的差异,以此来衡量两张图片之间的风格相似程度。因为使用了平均平方差,所以公式中没有除以 2。
总体损失函数即内容损失函数和风格损失函数的加权,不同的权重会导致不同的迁移风格效果。
这是图像风格转换任务中的总损失函数,其中 p ⃗ \vec{p} p 表示参考图片, a ⃗ \vec{a} a 表示参考图片的风格, x ⃗ \vec{x} x 表示待转换图片, α \alpha α 和 β \beta β 是两个超参数,公式表示如下:
L t o t a l ( p ⃗ , a ⃗ , x ⃗ ) = α ⋅ L c o n t e n t ( p ⃗ , x ⃗ ) + β ⋅ L s t y l e ( a ⃗ , x ⃗ ) \mathcal{L}_{total}(\vec{p}, \vec{a}, \vec{x}) = \alpha \cdot \mathcal{L}_{content}(\vec{p}, \vec{x}) + \beta \cdot \mathcal{L}_{style}(\vec{a}, \vec{x}) Ltotal(p,a,x)=α⋅Lcontent(p,x)+β⋅Lstyle(a,x)