1. 程式人生 > >Tensorflow機器學習(三) 程式碼實現反捲積過程(de-convolution/convolution transpose)

Tensorflow機器學習(三) 程式碼實現反捲積過程(de-convolution/convolution transpose)

卷積神經網路是深度學習中一個很流行的網路模型,

它的原理和過程我就不在此介紹了,感興趣的可以去看一下https://blog.csdn.net/kane7csdn/article/details/83617086


在這裡,介紹一下反捲積過程(可以叫做deconvolution,或者也可以稱作convolution transpose)。

反捲積也可以理解為逆卷積,顧名思義,卷積的逆過程。

我們如果把用卷積網路提取資料特徵看作一個壓縮過程,或者編碼過程

那麼反捲積過程便可以叫做解壓過程,或者解碼過程

這是一張來自 Learning Deconvolution Network for Semantic Segmentation 

的介紹圖。


下面我們用一個簡單的程式碼例子來實現一下反捲積過程。

原始資料為一個4*4矩陣:

[[1. 2. 3. 4.]
 [2. 3. 4. 5.]
 [3. 4. 5. 6.]
 [4. 5. 6. 7.]]

要求通過卷積+反捲積過程,儘可能的還原這個矩陣。

需要說明的是,通常一個卷積網路包含有卷積層+池化層,這裡為了方便演示,僅包含卷積層

另外,在本例子中因為只存在卷積層,且padding方式為same,所以不存在資料的丟失,因此反捲積的效果很好。

但實際專案中,由於池化層的存在,反捲積難以完全還原初始資料。

import tensorflow as tf
import numpy as np

data = np.array(([1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7]), dtype=float)
data = data.reshape((1, 4, 4, 1))

Data = tf.placeholder(tf.float32, (None, 4, 4, 1))
conv1 = tf.layers.conv2d(
    inputs=Data,
    filters=1,
    kernel_size=[2, 2],
    strides=[1, 1],
    padding="same"
)
deconv1 = tf.layers.conv2d_transpose(
    inputs=conv1,
    filters=1,
    kernel_size=[2, 2],
    strides=[1, 1],
    padding="same"
)
cost = tf.reduce_mean(tf.pow(deconv1 - Data, 2))
optimizer = tf.train.AdamOptimizer(0.01).minimize(cost)

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    for epoch in range(1000):
        _, loss = sess.run([optimizer, cost], feed_dict={Data: data})
        if (epoch+1) % 100 == 0:
            print("# Epoch %d, loss= %.2f" % (epoch+1, loss))
    print(data.reshape((4, 4)))
    deconv1_run = sess.run(deconv1, feed_dict={Data: data})
    print(deconv1_run.reshape((4, 4)))

# Epoch 100, loss= 0.55
# Epoch 200, loss= 0.29
# Epoch 300, loss= 0.15
# Epoch 400, loss= 0.07
# Epoch 500, loss= 0.04
# Epoch 600, loss= 0.02
# Epoch 700, loss= 0.01
# Epoch 800, loss= 0.01
# Epoch 900, loss= 0.00
# Epoch 1000, loss= 0.00
[[1. 2. 3. 4.]
 [2. 3. 4. 5.]
 [3. 4. 5. 6.]
 [4. 5. 6. 7.]]
[[1.0833378 1.9922134 2.9193594 3.9001908]
 [2.0152264 3.0306787 4.005212  5.048442 ]
 [3.0097656 4.005212  4.979745  6.0332966]
 [4.026579  5.0057573 5.9834356 6.9873247]]

經過反捲積重塑的矩陣與原矩陣非常相似。


用一個更加直觀的例子,模擬生產一組三軸感測器訊號:

(畫圖相關的程式碼略去了)

import tensorflow as tf
import numpy as np

data = 10 * np.random.random(size=120)
data = data.reshape((1, 3, 40, 1))

Data = tf.placeholder(tf.float32, (None, 3, 40, 1))
conv1 = tf.layers.conv2d(
    inputs=Data,
    filters=1,
    kernel_size=[3, 2],
    strides=[1, 1],
    padding="same"
)
deconv1 = tf.layers.conv2d_transpose(
    inputs=conv1,
    filters=1,
    kernel_size=[3, 2],
    strides=[1, 1],
    padding="same"
)
cost = tf.reduce_mean(tf.pow(deconv1 - Data, 2))
optimizer = tf.train.AdamOptimizer(0.01).minimize(cost)

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    for epoch in range(1000):
        _, loss = sess.run([optimizer, cost], feed_dict={Data: data})
        if (epoch+1) % 100 == 0:
            print("# Epoch %d, loss= %.2f" % (epoch+1, loss))
    deconv1_run = sess.run(deconv1, feed_dict={Data: data})

效果:# Epoch 1000, loss= 0.51

對比一下: