Tensorflow Day16 Autoencoder 實作

本文介绍了使用TensorFlow实现自编码器的过程,并探讨了不同维度的编码层对重构效果的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今日目標

  • 實作 Autoencoder
  • 比較輸入以及輸出

Github Ipython Notebook 好讀完整版

實作

定義 weight 以及 bias 函數

     
1
2
3
4
     
def weight_variable(shape, name):
return tf.Variable(tf.truncated_normal(shape = shape, stddev = 0.1), name)
def bias_variable(shape, name):
return tf.Variable(tf.constant( 0.1, shape = shape), name)

autoencoder 架構

初步的構想是建立一個七層的神經網路,在 encoder 維度會從 784 逐步變成 300, 100, 5 (code layer), decoder 的時候再逐步轉回 100, 300, 784.而這個想法在現在對 tensorflow 比較熟悉的情形下是很容易實現的,以下就是我實現的程式碼片段

input -> 784 -> 300 -> 100 -> 5 (code layer) -> 100 -> 300 -> 784 -> output

     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
     
x = tf.placeholder(tf.float32, shape = [ None, 784])
e_W_1 = weight_variable([ 784, 300], "e_W_1")
e_b_1 = bias_variable([ 300], "e_b_1")
e_layer1 = tf.nn.relu(tf.matmul(x, e_W_1) + e_b_1)
e_W_2 = weight_variable([ 300, 100], "e_W_2")
e_b_2 = bias_variable([ 100], "e_b_2")
e_layer2 = tf.nn.relu(tf.matmul(e_layer1, e_W_2) + e_b_2)
e_W_3 = weight_variable([ 100, 20], "e_W_3")
e_b_3 = bias_variable([ 20], "e_b_3")
code_layer = tf.nn.relu(tf.matmul(e_layer2, e_W_3) + e_b_3)
d_W_1 = weight_variable([ 20, 100], "d_W_1")
d_b_1 = bias_variable([ 100], "d_b_1")
d_layer1 = tf.nn.relu(tf.matmul(code_layer, d_W_1) + d_b_1)
d_W_2 = weight_variable([ 100, 300], "d_W_2")
d_b_2 = bias_variable([ 300], "d_b_2")
d_layer2 = tf.nn.relu(tf.matmul(d_layer1, d_W_2) + d_b_2)
d_W_3 = weight_variable([ 300, 784], "d_W_3")
d_b_3 = bias_variable([ 784], "d_b_3")
output_layer = tf.nn.relu(tf.matmul(d_layer2, d_W_3) + d_b_3)

loss

loss 函數我使用了 mean square error,而 optimizer 原本是使用 GradientDescentOptimizer,但是做出來的 decode 結果變得非常糟糕 (如下).後來上網搜尋了以後改用 RMSPropOptimizer,以下會隨機選出數個數字來看看所做出來的結果.

     
1
2
3
     
loss = tf.reduce_mean(tf.pow(output_layer - x, 2))
optimizer = tf.train.RMSPropOptimizer( 0.01).minimize(loss)
init_op = tf.global_variables_initializer()

training

     
1
2
3
4
5
6
7
8
9
     
sess = tf.InteractiveSession()
sess.run(init_op)
for i in range( 20000):
batch = mnist.train.next_batch( 50)
if i% 100 == 0:
print( "step %d, loss %g"%(i, loss.eval(feed_dict={x:batch[ 0]})))
optimizer.run(feed_dict={x: batch[ 0]})
print( "final loss %g" % loss.eval(feed_dict={x: mnist.test.images}))

final loss 0.031768

成果

     
1
2
3
4
5
6
7
8
9
10
11
12
     
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
trainimg = mnist.train.images
trainlabel = mnist.train.labels
output_nd = output_layer.eval(feed_dict = {x: mnist.train.images})
for i in [ 0, 1, 2, 3, 4]:
curr_img = np.reshape(trainimg[i, :], ( 28, 28)) # 28 by 28 matrix
ae_img = np.reshape(output_nd[i,:], ( 28, 28))
curr_label = np.argmax(trainlabel[i, :] ) # Label
plt.matshow(curr_img, cmap=plt.get_cmap( 'gray'))
plt.matshow(ae_img, cmap=plt.get_cmap( 'gray'))

調整 code layer 維度

而接下來當我想嘗試把 code layer 的維度調整為 2 維來看看

我們可以發現完全糊掉了,只用二維來表示輸入數字是不太夠的.更進一步仔細看 code layer 的值,都已經接近零,表示這個網路已經算是死掉了,因此還要想想為什麼會造成這樣的結果.

今日心得

用 tensorflow 實作了 autoencoder,但是在降成兩維的效果並不好,需要再找找看有什麼方法可以幫助解決這個情形, google 上看到說 sparse autoencoder 可能可以幫助這個情形.

原文: https://blog.c1mone.com.tw/2017/01/02/tensorflow-note-day-18/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值