Tensorflow:理解和實現快速風格化圖像fast neural style

lhqlyh 7年前發布 | 22K 次閱讀 機器學習 TensorFlow

Neural Style 開辟了計算機與藝術的道路,可以將照片風格化為名家大師的畫風。然而這種方法即使使用GPU也要花上幾十分鐘。 Fast Neural Style 則啟用另外一種思路來快速構建風格化圖像,在筆記本CPU上十幾秒就可以風格化一張圖片。我們來看看這是什么原理。
傳統的Neural Style基于VGG構建了一個最優化模型。它將待風格化圖片和風格化樣本圖放入VGG中進行前向運算。其中待風格化圖像提取relu4特征圖,風格化樣本圖提取relu1,relu2,relu3,relu4,relu5的特征圖。我們要把一個隨機噪聲初始化的圖像變成目標風格化圖像,將其放到VGG中計算得到特征圖,然后分別計算內容損失和風格損失。內容損失函數為:

c o n e n = 1 2 ∑ ∑ i , ( ? ) 2

P和F一個表示目標圖像的特征圖,一個表示待風格化原圖的特征圖,l表示是哪個layer,k表示第幾個特征圖,減法是矩陣元素減法,i,j是矩陣坐標,M是一個可以自由發揮想象的分母,這里定義一個原圖與生成圖像在l層的所有特征圖的歐氏距離之和。風格損失函數為:

s y e = ∑ w ( ∑ 1 , 2 ∑ i , ? ∑ 1 , 2 ∑ i , P 1 P 2 ) 2

P和F一個表示目標圖像的特征圖,一個表示風格化樣本圖的特征圖,l表示是哪個layer,k表示第幾個特征圖,乘法是矩陣元素乘法,生成的Gram矩陣是一種未中心化的協方差矩陣,i,j是矩陣坐標,N是一個可以自由發揮想象的分母(雖然原文有明確的值,但是感覺跟原理沒關系)。計算和求和Gram矩陣做法其實簡單,假設特征圖是C個[H,W]的矩陣,那么合并展開為[C,HxW]的矩陣 Φ ,Gram矩陣總的求和就是 ∑ Φ Φ ,這里是矩陣乘法。
有了上面兩個損失函數,就可以構建感知損失函數:

p e c e p u a = α s y e + c o n e n + v

第三項是噪聲約束,不用也可以。最小化這個感知損失函數,我們就把輸入的隨機噪聲圖像變成了風格化的圖片。這個最優化模型的收斂速度非常慢,GPU都要計算好久。
Fast Neural Style則可以在普通筆記本電腦中十幾秒運算出一個風格化圖像。在一些科普文中是這樣解釋:Neural Style每次風格化都重新訓練了一次生成過程,把這個過程提前做好,就可以加速風格化。我覺得這個說法有點奇怪,來看看原文流程圖:

這個模型有兩個部分,后面一個loss network就是普通Neural Style的VGG網絡,這里只當做計算loss的網絡,不進行訓練;前面一個Image Transform Network一般是一個deep residual CNN,即喜聞樂見的深度殘差網絡,要訓練這個網絡。然而,深度殘差網絡的結構跟VGG是不同,訓練深度殘差網絡不等于提前做好VGG生成過程。這里的思想,我認為是一種生成-判別模型,有生成對抗網絡GAN的影子:深度殘差網絡-》生成模型,VGG-》判別模型。
下面的代碼來自國人大神 hzy46 ,我將預測部分的代碼已經升級遷移到python3 tensorflow 1.0正式版:

def resize_conv2d(x, input_filters, output_filters, kernel, strides, training):
    '''
    An alternative to transposed convolution where we first resize, then convolve.
    See http://distill.pub/2016/deconv-checkerboard/

    For some reason the shape needs to be statically known for gradient propagation
    through tf.image.resize_images, but we only know that for fixed image size, so we
    plumb through a "training" argument
    '''
    with tf.variable_scope('conv_transpose') as scope:
        height = x.get_shape()[1].value if training else tf.shape(x)[1]
        width = x.get_shape()[2].value if training else tf.shape(x)[2]
        new_height = height * strides * 2
        new_width = width * strides * 2
        x_resized = tf.image.resize_images(x, [new_height, new_width], tf.image.ResizeMethod.NEAREST_NEIGHBOR)
        return conv2d(x_resized, input_filters, output_filters, kernel, strides)

def instance_norm(x):
    epsilon = 1e-9
    mean, var = tf.nn.moments(x, [1, 2], keep_dims=True)
    return tf.div(tf.subtract(x, mean), tf.sqrt(tf.add(var, epsilon)))

with tf.variable_scope('conv1'):
        conv1 = tf.nn.relu(instance_norm(conv2d(image, 3, 32, 9, 1)))
    with tf.variable_scope('conv2'):
        conv2 = tf.nn.relu(instance_norm(conv2d(conv1, 32, 64, 3, 2)))
    with tf.variable_scope('conv3'):
        conv3 = tf.nn.relu(instance_norm(conv2d(conv2, 64, 128, 3, 2)))
    with tf.variable_scope('res1'):
        res1 = residual(conv3, 128, 3, 1)
    with tf.variable_scope('res2'):
        res2 = residual(res1, 128, 3, 1)
    with tf.variable_scope('res3'):
        res3 = residual(res2, 128, 3, 1)
    with tf.variable_scope('res4'):
        res4 = residual(res3, 128, 3, 1)
    with tf.variable_scope('res5'):
        res5 = residual(res4, 128, 3, 1)
    with tf.variable_scope('deconv1'):
        deconv1 = tf.nn.relu(instance_norm(resize_conv2d(res5, 128, 64, 3, 2, training)))
    with tf.variable_scope('deconv2'):
        deconv2 = tf.nn.relu(instance_norm(resize_conv2d(deconv1, 64, 32, 3, 2, training)))
    with tf.variable_scope('deconv3'):
        deconv3 = tf.nn.tanh(instance_norm(conv2d(deconv2, 32, 3, 9, 1)))
    y = (deconv3 + 1) * 127.5

 

明顯可以看到這里用了反轉卷積conv2d_transpose,這是生成模型的標配啊!整個模型中,深度殘差網絡不斷從原圖生成目標風格化圖像,然后VGG不斷反饋深度殘差網絡存在的問題,從而不斷優化生成網絡,直到生成網絡生成標準的風格化圖像。最后要投入使用的時候,后面VGG判別網絡根本不需要,只需要前面的深度殘差生成網絡,就像GAN一樣。
Fast Neural Style的優點有:

  • 生成速度快。
  • 訓練好的模型文件不大,載入簡單。不需要VGG網絡,那個tensorflow model有500MB。

缺點有:

  • 訓練速度很慢。官方推薦用coco數據集訓練深度殘差網絡,這個數據集小的也有13GB,運行要幾十個小時。
  • 一個生成網絡只能生成一種風格化圖像。我們訓練生成網絡,使用的風格化圖像只能用一種。

由于訓練的太慢,我就直接用hzy46大神的訓練好的model。經過訓練后的圖像:


INFO:tensorflow:Elapsed time: 1.455744s
你們看,2015 macbook pro低配版上只要1.5秒鐘就完成了這個252x252的圖像的風格化。
https://github.com/artzers/MachineLearning/tree/master/Tensorflow/fast-neural-style

 

 

來自:http://blog.csdn.net/lpsl1882/article/details/56666265

 

 本文由用戶 lhqlyh 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!