利用自編碼(Autoencoder)來提取輸入數據的特征


自編碼(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

參考

本文內容來自於莫煩python,進行學習整理,非常感謝。
相關代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM