神经风格迁移一经提出,便引起了业界的巨大兴趣,一些网站允许用户上传照片以进行风格迁移,甚至有一些有人将其用于商品销售(例如某宝的“DIY数字油画定制照片”等等)。当七夕来临,又到了挠头想送女朋友什么礼物的时候了,虽然定制照片很有意义,但是并不能保证风格是自己想要的呀,这种固定的风格怎么能是技术宅的 Style?当然是用 TensorFlow 实现实时任意风格迁移,为女朋友用心选一张最合适的风格化照片了。
我们虽然在改进风格迁移,重拾《星空》梦!中改进了传统的神经风格迁移,但是仍然只能使用训练所得的固定数量的风格。因此我们要学习另一种允许实时任意风格迁移的神经网络模型,获得更多创意选择。
AdaIN(adaptive instance normalization)
是实例归一化的一种,这意味着其均值和标准差是在每个图像和每个通道 (H, W)
上计算的。在 CIN
中, γ γ γ 和 β β β 系数是可训练的变量,它们学习不同风格所需的均值和方差。在AdaIN中, γ γ γ 和 β β β 被风格特征的标准差和均值所取代:
A d a I N ( x , y ) = σ ( y ) x − μ ( x ) σ ( x ) + μ ( y ) AdaIN(x,y)=\sigma(y)\frac {x-\mu (x)}{\sigma(x)} + \mu(y) AdaIN(x,y)=σ(y)σ(x)x−μ(x)+μ(y)
AdaIN
仍可以理解为条件实例规范化的一种形式,其中条件是风格特征而不是风格标签。在训练和推理时,我们使用VGG提取风格层输出并将其统计信息用作风格条件,这样避免了只能预先定义一组固定风格。
使用TensorFlow来创建自定义AdaIN层:
class AdaIN(layers.Layer):
def init(self, epsilon=1e-5):
super(AdaIN, self).init()
self.epsilon = epsilon
def call(self, inputs):
x = inputs[0] # content
y = inputs[1] # style
mean_x, var_x = tf.nn.moments(x, axes=(1,2), keepdims=True)
mean_y, var_y = tf.nn.moments(y, axes=(1,2), keepdims=True)
std_x = tf.sqrt(var_x + self.epsilon)
std_y = tf.sqrt(var_y + self.epsilon)
output = std_y * (x - mean_x) / std_x + mean_y
return output
Tips:可以看出,这是对 AdaIN 方程式的直接实现。其中 tf.nn.moments 用于计算特征图的均值和方差,其中轴1、2指向特征图的H,W。还设置keepdims