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
對比一下: