自編碼(Autoencoder)介紹
Autoencoder是一種無監督的學習算法,將輸入信息進行壓縮,提取出數據中最具代表性的信息。其目的是在保證重要特征不丟失的情況下,降低輸入信息的維度,減小神經網絡的處理負擔。簡單來說就是提取輸入信息的特征。類似於主成分分析(Principal Components Analysis,PAC)
對於輸入信息X,通過神經網絡對其進行壓縮,提取出數據的重要特征,然后將其解壓得到數據Y,然后通過對比X與Y求出預測誤差進行反向傳遞,逐步提升自編碼的准確性。訓練完成的自編碼中間部分就是輸入數據的精髓,實際使用中通常只會用到自編碼的前半部分。
Tensorflow實現
用到的數據集
用到的數據集是Tensorflow模塊中的mnist數據集,其中有70000個數字0-9的帶標簽圖片樣本,包含了60000個訓練樣本和10000個測試樣本。
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot=False) #讀取文件
"/tmp/data/"為文件保存的位置,如果沒有則會自動下載到該文件夾。"one_hot=False"表示返回一個長度為n的numpy數組.每個元素代表圖片上的數字.
參數定義
# Parameter
learning_rate = 0.01 #學習率0.01
training_epochs = 5 # 五組訓練
batch_size = 256 #批尺寸大小
display_step = 1 #每隔多少epoch顯示打印一次cost
examples_to_show = 10 #顯示多少張圖片
網絡輸入inputs
n_input = 784 # mnist中圖片的尺寸是28*28總共有784個像素特征
# tf Graph input (only pictures)
X = tf.placeholder("float", [None, n_input]) #定義網絡的輸入特征
隱藏層的權重weights和偏置biases定義
- 將輸入進的784個Features,經過第一個隱藏層壓縮到256個Features,然后經過第二個隱藏層壓縮至128個。
- 在解壓環節將128個Features還原至256,再到784.
- 將前后的784個特征進行對比,反向傳遞cost來提升自編碼的准確度
# hidden layer settings
n_hidden_1 = 256 # 第一層隱藏層的特征數量
n_hidden_2 = 128 # 第二層的數量
weights = {
'encoder_h1':tf.Variable(tf.random_normal([n_input,n_hidden_1])), #[784,256]
'encoder_h2': tf.Variable(tf.random_normal([n_hidden_1,n_hidden_2])), #[256,128]
'decoder_h1': tf.Variable(tf.random_normal([n_hidden_2,n_hidden_1])), #[128,256]
'decoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_input])), #[256,784]
}
biases = {
'encoder_b1': tf.Variable(tf.random_normal([n_hidden_1])), #[256]
'encoder_b2': tf.Variable(tf.random_normal([n_hidden_2])), #[128]
'decoder_b1': tf.Variable(tf.random_normal([n_hidden_1])), #[256]
'decoder_b2': tf.Variable(tf.random_normal([n_input])), #[784]
}
定義壓縮Encoder和解壓Decoder層
使用的激活函數是sigmoid,壓縮之后的值應該在[0,1],在decoder中激活函數一樣
# Building the encoder
def encoder(x):
# Encoder Hidden layer with sigmoid activation #1
layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']),
biases['encoder_b1']))
# Decoder Hidden layer with sigmoid activation #2
layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['encoder_h2']),
biases['encoder_b2']))
return layer_2
# Building the decoder
def decoder(x):
# Encoder Hidden layer with sigmoid activation #1
layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']),
biases['decoder_b1']))
# Decoder Hidden layer with sigmoid activation #2
layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['decoder_h2']),
biases['decoder_b2']))
return layer_2
Encoder和Decoder的輸出結果
encoder_op = encoder(X) # 128 Features
decoder_op = decoder(encoder_op) # 784 Features
# Prediction
y_pred = decoder_op # 預測值
y_true = X # 真實值(原始輸入)
定義cost和訓練
cost = tf.reduce_mean(tf.pow(y_true - y_pred, 2)) #cost為(y_true - y_pred)^2的均值
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost) #利用AdamOptimizer來訓練
最后通過Matplotlib的pyplot來顯示結果
with tf.Session() as sess:
init=tf.global_variables_initializer()
sess.run(init)
total_batch=int(mnist.train.num_examples/batch_size) #計算訓練循環的次數
#train cycle
for epoch in range(training_epochs):
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
_, c = sess.run([optimizer, cost], feed_dict={X: batch_xs})
if epoch % display_step == 0: #輸入經過每一個epoch后cost的值
print("Epoch:", '%04d' % (epoch + 1), #輸出格式為Epoch:0001 cost=0.123456789
"cost=", "{:.9f}".format(c))
print("Optimization Finished!")
#在測試集上應用encoder和decoder
encode_decode = sess.run(
y_pred, feed_dict={X: mnist.test.images[:examples_to_show]})
# 顯示對比圖像
f, a = plt.subplots(2, 10, figsize=(10, 2)) #定義畫布
for i in range(examples_to_show):
a[0][i].imshow(np.reshape(mnist.test.images[i], (28, 28)))
a[1][i].imshow(np.reshape(encode_decode[i], (28, 28)))
plt.show()
結果
Epoch: 0001 cost= 0.077869482
Epoch: 0002 cost= 0.070396304
Epoch: 0003 cost= 0.066303633
Epoch: 0004 cost= 0.062276978
Epoch: 0005 cost= 0.055230502