神經網絡圖像編碼與解碼

神經網絡圖像編碼與解碼

原來有時神經網絡要接受大量的輸入信息, 比如輸入信息是高清圖片時, 輸入信息量可能達到上千萬, 讓神經網絡直接從上千萬個信息源中學習是一件很吃力的工作. 所以, 何不壓縮一下, 提取出原圖片中的最具代表性的信息, 縮減輸入信息量, 再把縮減過後的信息放進神經網絡學習. 這樣學習起來就簡單輕鬆了. 所以, 自編碼就能在這時發揮作用. 通過將原數據白色的X 壓縮, 解壓 成黑色的X, 然後通過對比黑白 X ,求出預測誤差, 進行反向傳遞, 逐步提升自編碼的準確性. 訓練好的自編碼中間這一部分就是能總結原數據的精髓. 可以看出, 從頭到尾, 我們只用到了輸入數據 X, 並沒有用到 X 對應的數據標籤, 所以也可以說自編碼是一種非監督學習. 到了真正使用自編碼的時候. 通常只會用到自編碼前半部分.

Autoencoder 簡單來說就是將有很多Feature的數據進行壓縮,之後再進行解壓的過程。 本質上來說,它也是一個對數據的非監督學習,如果大家知道 PCA (Principal component analysis), 與 Autoencoder 相類似,它的主要功能即對數據進行非監督學習,並將壓縮之後得到的“特徵值”,這一中間結果正類似於PCA的結果。 之後再將壓縮過的“特徵值”進行解壓,得到的最終結果與原始數據進行比較,對此進行非監督學習。

今天的代碼,我們會運用兩個類型:

  • 第一,是通過Feature的壓縮並解壓,並將結果與原始數據進行對比,觀察處理過後的數據是不是如預期跟原始數據很相像。(這裡會用到MNIST數據)
  • 第二,我們只看 encoder 壓縮的過程,使用它將一個數據集壓縮到只有兩個Feature時,將數據放入一個二維座標系內.

第一:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data

learning_rate = 0.01
training_epochs = 20
batch_size = 256
example_image_show = 10

mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
n_input = 28*28
n_hidden_1 = 256
n_hidden_2 = 128
weights = {
 'encode_1': tf.Variable(tf.random.normal([n_input, n_hidden_1])),
 'encode_2': tf.Variable(tf.random.normal([n_hidden_1, n_hidden_2])),
 'decode_1': tf.Variable(tf.random.normal([n_hidden_2, n_hidden_1])),
 'decode_2': tf.Variable(tf.random.normal([n_hidden_1, n_input]))
}
bais = {
 'encode_1': tf.Variable(tf.random.normal([n_hidden_1])),
 'encode_2': tf.Variable(tf.random.normal([n_hidden_2])),
 'decode_1': tf.Variable(tf.random.normal([n_hidden_1])),
 'decode_2': tf.Variable(tf.random.normal([n_input]))
}

def encode(x):
 layer1 = tf.nn.sigmoid(tf.matmul(x, weights['encode_1']) + bais['encode_1'])
 layer2 = tf.nn.sigmoid(tf.matmul(layer1, weights['encode_2']) + bais['encode_2'])
 return layer2

def decode(x):
 layer1 = tf.nn.sigmoid(tf.matmul(x, weights['decode_1']) + bais['decode_1'])
 layer2 = tf.nn.sigmoid(tf.matmul(layer1, weights['decode_2']) + bais['decode_2'])
 return layer2

x = tf.placeholder(tf.float32, shape=[None, n_input])
encode_op = encode(x)
decode_op = decode(encode_op)
y_pred = decode_op
y_true = x
cost = tf.reduce_mean(tf.pow(y_true - y_pred, 2))
train_op = tf.train.AdamOptimizer(learning_rate).minimize(cost)

re_loss = []
with tf.Session() as sess:
 sess.run(tf.global_variables_initializer())
 batch = int(mnist.train.num_examples/batch_size)

 for i in range(training_epochs):
 mean_loss = 0
 for j in range(batch):
 batch_x, _ = mnist.train.next_batch(batch_size)
 feed = {x:batch_x}
 _, ls = sess.run([train_op, cost], feed_dict=feed)
 mean_loss += ls

 re_loss.append(mean_loss / batch)

 plt.plot(np.linspace(0, training_epochs, training_epochs), re_loss, c='red')
 plt.show()

 plt.figure(2)
 auto_y = sess.run(decode_op, feed_dict={x: mnist.test.images[:example_image_show]})
 f, ax = plt.subplots(2, 10, figsize=(10, 2))
 for i in range(example_image_show):
 ax[0][i].imshow(np.reshape(mnist.test.images[i], [28, 28]))
 ax[1][i].imshow(np.reshape(auto_y[i], [28, 28]))
 plt.show()
神經網絡圖像編碼與解碼

神經網絡圖像編碼與解碼

第二: 我們只顯示 encoder 之後的數據, 並畫在一個二維直角座標系內。做法很簡單,我們將原有 784 Features 的數據壓縮成僅剩 2 Features 的數據:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data

learning_rate = 0.01
batch_size = 256
training_epoch = 10

mnist = input_data.read_data_sets("MNIST_data", one_hot=True)
print(np.argmax(mnist.test.labels, axis=1).shape)
n_inputs = 28*28
n_hidden_1 = 128
n_hidden_2 = 64
n_hidden_3 = 10
n_hidden_4 = 2

weight = {
 'encoder_1': tf.Variable(tf.random.normal([n_inputs, n_hidden_1])),
 'encoder_2': tf.Variable(tf.random.normal([n_hidden_1, n_hidden_2])),
 'encoder_3': tf.Variable(tf.random.normal([n_hidden_2, n_hidden_3])),
 'encoder_4': tf.Variable(tf.random.normal([n_hidden_3, n_hidden_4])),


 'decoder_1': tf.Variable(tf.random.normal([n_hidden_4, n_hidden_3])),
 'decoder_2': tf.Variable(tf.random.normal([n_hidden_3, n_hidden_2])),
 'decoder_3': tf.Variable(tf.random.normal([n_hidden_2, n_hidden_1])),
 'decoder_4': tf.Variable(tf.random.normal([n_hidden_1, n_inputs]))
}

bais = {
 'encoder_1': tf.Variable(tf.random.normal([n_hidden_1])),
 'encoder_2': tf.Variable(tf.random.normal([n_hidden_2])),
 'encoder_3': tf.Variable(tf.random.normal([n_hidden_3])),
 'encoder_4': tf.Variable(tf.random.normal([n_hidden_4])),
 'decoder_1': tf.Variable(tf.random.normal([n_hidden_3])),
 'decoder_2': tf.Variable(tf.random.normal([n_hidden_2])),
 'decoder_3': tf.Variable(tf.random.normal([n_hidden_1])),
 'decoder_4': tf.Variable(tf.random.normal([n_inputs])),
}

def encoder(x):
 l1 = tf.nn.sigmoid(tf.matmul(x, weight['encoder_1']) + bais['encoder_1'])
 l2 = tf.nn.sigmoid(tf.matmul(l1, weight['encoder_2']) + bais['encoder_2'])
 l3 = tf.nn.sigmoid(tf.matmul(l2, weight['encoder_3']) + bais['encoder_3'])
 l4 = tf.nn.sigmoid(tf.matmul(l3, weight['encoder_4']) + bais['encoder_4'])
 return l4

def decoder(x):
 l1 = tf.nn.sigmoid(tf.matmul(x, weight['decoder_1']) + bais['decoder_1'])
 l2 = tf.nn.sigmoid(tf.matmul(l1, weight['decoder_2']) + bais['decoder_2'])
 l3 = tf.nn.sigmoid(tf.matmul(l2, weight['decoder_3']) + bais['decoder_3'])
 l4 = tf.nn.sigmoid(tf.matmul(l3, weight['decoder_4']) + bais['decoder_4'])
 return l4

x = tf.placeholder(tf.float32, shape=[None, n_inputs])
encoder_op = encoder(x)
decoder_op = decoder(encoder_op)
y_pred = decoder_op
y_true = x

cost = tf.reduce_mean(tf.square(y_true - y_pred))
train_op = tf.train.AdamOptimizer(learning_rate).minimize(cost)

with tf.Session() as sess:
 sess.run(tf.global_variables_initializer())
 batchs = int(mnist.train.num_examples/batch_size)
 re_ls = []
 for i in range(training_epoch):
 mean_ls = 0
 for j in range(batchs):
 batch_xs, _ = mnist.train.next_batch(batch_size)
 feed = {x: batch_xs}
 _, ls = sess.run([train_op, cost], feed_dict=feed)
 mean_ls += ls
 re_ls.append(mean_ls/batchs)

 plt.plot(np.linspace(0, training_epoch, training_epoch), re_ls, c='red')
 plt.show()
 
 ## 觀測編碼原始數據 與 原始數據標籤 構成的二維圖
 encoder_result = sess.run(encoder_op, feed_dict={x: mnist.test.images})
 print(mnist.test.labels.shape)
 plt.scatter(encoder_result[:, 0], encoder_result[:, 1], c=np.argmax(mnist.test.labels, axis=1))
 plt.colorbar()
 plt.show()
神經網絡圖像編碼與解碼


分享到:


相關文章: