摘要:本篇文章將分享無監督學習Autoencoder的原理知識,然后用MNIST手寫數字案例進行對比實驗及聚類分析。
本文分享自華為雲社區《[Python人工智能] 十五.無監督學習Autoencoder原理及聚類可視化案例詳解》,作者: eastmount。
一.什么是Autoencoder
首先,什么是自編碼(Autoencoder)?自編碼是一種神經網絡的形式,注意它是無監督學習算法。例如現在有一張圖片,需要給它打碼,然后又還原圖片的過程,如下圖所示:
一張圖片經過壓縮再解壓的工序,當壓縮時原有的圖片質量被縮減,當解壓時用信息量小卻包含所有關鍵性文件恢復出原來的圖片。為什么要這么做呢?有時神經網絡需要輸入大量的信息,比如分析高清圖片時,輸入量會上千萬,神經網絡從上千萬中學習是非常難的一個工作,此時需要進行壓縮,提取原圖片中具有代表性的信息或特征,壓縮輸入的信息量,再把壓縮的信息放入神經網絡中學習。這樣學習就變得輕松了,所以自編碼就在這個時候發揮作用。
如下圖所示,將原數據白色的X壓縮解壓成黑色的X,然后通過對比兩個X,求出誤差,再進行反向的傳遞,逐步提升自編碼的准確性。
訓練好的自編碼,中間那部分就是原數據的精髓,從頭到尾我們只用到了輸入變量X,並沒有用到輸入變量對應的標簽,所以自編碼是一種無監督學習算法。
但是真正使用自編碼時,通常只用到它的前半部分,叫做編碼器,能得到原數據的精髓。然后只需要創建小的神經網絡進行訓練,不僅減小了神經網絡的負擔,而且同樣能達到很好的效果。
下圖是自編碼整理出來的數據,它能總結出每類數據的特征,如果把這些數據放在一張二維圖片上,每一種數據都能很好的用其精髓把原數據區分開來。自編碼能類似於PCA(主成分分析)一樣提取數據特征,也能用來降維,其降維效果甚至超越了PCA。
二.Autoencoder分析MNIST數據
Autoencoder算法屬於非監督學習,它是把數據特征壓縮,再把壓縮后的特征解壓的過程,跟PCA降維壓縮類似。
本篇文章的代碼包括兩部分內容:
- 第一部分:使用MNIST數據集,通過feature的壓縮和解壓,對比解壓后的圖片和壓縮之前的圖片,看看是否一致,實驗想要的效果是和圖片壓縮之前的差不多。
- 第二部分:輸出encoder的結果,壓縮至兩個元素並可視化顯示。在顯示圖片中,相同顏色表示同一類型圖片,比如類型為1(數字1),類型為2(數字2)等等,最終實現無監督的聚類。
有監督學習和無監督學習的區別
(1) 有監督學習方法必須要有訓練集與測試樣本。在訓練集中找規律,而對測試樣本使用這種規律。而非監督學習沒有訓練集,只有一組數據,在該組數據集內尋找規律。
(2) 有監督學習的方法就是識別事物,識別的結果表現在給待識別數據加上了標簽。因此訓練樣本集必須由帶標簽的樣本組成。而非監督學習方法只有要分析的數據集的本身,預先沒有什么標簽。 如果發現數據集呈現某種聚集性,則可按自然的聚集性分類,但不予以某種預先分類標簽對上號為目的。
讓我們開始編寫代碼吧!
第一步,打開Anaconda,然后選擇已經搭建好的“tensorflow”環境,運行Spyder。
第二步,導入擴展包。
import numpy as np import tensorflow as tf import matplotlib.pyplot as plt from tensorflow.examples.tutorials.mnist import input_data
第三步,下載數據集。
由於MNIST數據集是TensorFlow的示例數據,所以我們只需要下面一行代碼,即可實現數據集的讀取工作。如果數據集不存在它會在線下載,如果數據集已經被下載,它會被直接調用。
# 下載手寫數字圖像數據集 mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
第四步,定義參數。
MNIST圖片是28*28的像素,其n_input輸入特征為784,feature不斷壓縮,先壓縮成256個,再經過一層隱藏層壓縮到128個。然后把128個放大,解壓256個,再解壓縮784個。最后對解壓的784個和原始的784個特征進行cost對比,並根據cost提升Autoencoder的准確率。
#-------------------------------------初始化設置------------------------------------------- # 基礎參數設置 learning_rate = 0.01 #學習效率 training_epochs = 5 #5組訓練 batch_size = 256 #batch大小 display_step = 1 examples_to_show = 10 #顯示10個樣本 # 神經網絡輸入設置 n_input = 784 #MNIST輸入數據集(28*28) # 隱藏層設置 n_hidden_1 = 256 #第一層特征數量 n_hidden_2 = 128 #第二層特征數量 weights = { 'encoder_h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])), 'encoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])), 'decoder_h1': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_1])), 'decoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_input])) } biases = { 'encoder_b1': tf.Variable(tf.random_normal([n_hidden_1])), 'encoder_b2': tf.Variable(tf.random_normal([n_hidden_2])), 'decoder_b1': tf.Variable(tf.random_normal([n_hidden_1])), 'decoder_b2': tf.Variable(tf.random_normal([n_input])) }
第五步,編寫核心代碼,即定義encoder和decoder函數來實現壓縮和解壓操作。
encoder就是兩層Layer,分別壓縮成256個元素和128個元素。decoder同樣包括兩層Layer,對應解壓成256和784個元素。
#---------------------------------壓縮和解壓函數定義--------------------------------------- # Building the encoder def encoder(x): # 第一層Layer壓縮成256個元素 壓縮函數為sigmoid(壓縮值為0-1范圍內) layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']), biases['encoder_b1'])) # 第二層Layer壓縮成128個元素 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): # 解壓隱藏層調用sigmoid激活函數 layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']), biases['decoder_b1'])) # 第二層Layer解壓成784個元素 layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['decoder_h2']), biases['decoder_b2'])) return layer_2 #-----------------------------------壓縮和解壓操作--------------------------------------- # 壓縮:784 => 128 encoder_op = encoder(X) # 解壓:784 => 128 decoder_op = decoder(encoder_op)
需要注意,在MNIST數據集中,xs數據的最大值是1,最小值是0,而不是圖片的最大值255,因為它已經被這里的sigmoid函數歸一化了。
batch_xs, batch_ys = mnist.train.next_batch(batch_size) # max(x) = 1, min(x) = 0
第六步,定義誤差計算方式。
其中,y_pred表示預測的結果,調用decoder_op解壓函數,decoder_op又繼續調用decoder解壓和encoder壓縮函數,對圖像數據集X進行處理。
#--------------------------------對比預測和真實結果--------------------------------------- # 預測 y_pred = decoder_op # 輸入數據的類標(Labels) y_true = X # 定義loss誤差計算 最小化平方差 cost = tf.reduce_mean(tf.pow(y_true - y_pred, 2)) optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost)
第七步,定義訓練和可視化代碼,該部分為神經網絡運行的核心代碼。
首先進行init初始化操作,然后分5組實驗進行訓練,batch_x為獲取的圖片數據集,通過 sess.run([optimizer, cost], feed_dict={X: batch_xs}) 計算真實圖像與預測圖像的誤差。
#-------------------------------------訓練及可視化------------------------------------- # 初始化 init = tf.initialize_all_variables() # 訓練集可視化操作 with tf.Session() as sess: sess.run(init) total_batch = int(mnist.train.num_examples/batch_size) # 訓練數據 training_epochs為5組實驗 for epoch in range(training_epochs): # Loop over all batches for i in range(total_batch): batch_xs, batch_ys = mnist.train.next_batch(batch_size) # max(x)=1 min(x)=0 # 運行初始化和誤差計算操作 _, c = sess.run([optimizer, cost], feed_dict={X: batch_xs}) # 每個epoch顯示誤差值 if epoch % display_step == 0: print("Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(c)) print("Optimization Finished!")
第八步,調用matplotlib庫畫圖,可視化對比原始圖像和預測圖像。
# 壓縮和解壓測試集 encode_decode = sess.run( y_pred, feed_dict={X: mnist.test.images[:examples_to_show]}) # 比較原始圖像和預測圖像數據 f, a = plt.subplots(2, 10, figsize=(10, 2)) # 顯示結果 上面10個樣本是真實數據 下面10個樣本是預測結果 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()
第九步,運行代碼並分析結果。
輸出結果如下圖所示,誤差在不斷減小,表示我們的無監督神經網絡學習到了知識。
Extracting MNIST_data\train-images-idx3-ubyte.gz Extracting MNIST_data\train-labels-idx1-ubyte.gz Extracting MNIST_data\t10k-images-idx3-ubyte.gz Extracting MNIST_data\t10k-labels-idx1-ubyte.gz Epoch: 0001 cost= 0.097888887 Epoch: 0002 cost= 0.087600455 Epoch: 0003 cost= 0.083100438 Epoch: 0004 cost= 0.078879632 Epoch: 0005 cost= 0.069106154 Optimization Finished!
通過5批訓練,顯示結果如下圖所示,上面是真實的原始圖像,下面是壓縮之后再解壓的圖像數據。注意,其實5批訓練是非常少的,正常情況需要更多的訓練。
完整代碼:
# -*- coding: utf-8 -*- """ Created on Wed Jan 15 15:35:47 2020 @author: xiuzhang Eastmount CSDN """ import numpy as np import tensorflow as tf import matplotlib.pyplot as plt from tensorflow.examples.tutorials.mnist import input_data #-----------------------------------初始化設置--------------------------------------- # 基礎參數設置 learning_rate = 0.01 #學習效率 training_epochs = 5 #5組訓練 batch_size = 256 #batch大小 display_step = 1 examples_to_show = 10 #顯示10個樣本 # 神經網絡輸入設置 n_input = 784 #MNIST輸入數據集(28*28) # 輸入變量(only pictures) X = tf.placeholder("float", [None, n_input]) # 隱藏層設置 n_hidden_1 = 256 #第一層特征數量 n_hidden_2 = 128 #第二層特征數量 weights = { 'encoder_h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])), 'encoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])), 'decoder_h1': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_1])), 'decoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_input])) } biases = { 'encoder_b1': tf.Variable(tf.random_normal([n_hidden_1])), 'encoder_b2': tf.Variable(tf.random_normal([n_hidden_2])), 'decoder_b1': tf.Variable(tf.random_normal([n_hidden_1])), 'decoder_b2': tf.Variable(tf.random_normal([n_input])) } # 導入MNIST數據 mnist = input_data.read_data_sets("MNIST_data", one_hot=False) #---------------------------------壓縮和解壓函數定義--------------------------------------- # Building the encoder def encoder(x): # 第一層Layer壓縮成256個元素 壓縮函數為sigmoid(壓縮值為0-1范圍內) layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']), biases['encoder_b1'])) # 第二層Layer壓縮成128個元素 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): # 解壓隱藏層調用sigmoid激活函數(范圍內為0-1區間) layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']), biases['decoder_b1'])) # 第二層Layer解壓成784個元素 layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['decoder_h2']), biases['decoder_b2'])) return layer_2 #-----------------------------------壓縮和解壓操作--------------------------------------- # Construct model # 壓縮:784 => 128 encoder_op = encoder(X) # 解壓:784 => 128 decoder_op = decoder(encoder_op) #--------------------------------對比預測和真實結果--------------------------------------- # 預測 y_pred = decoder_op # 輸入數據的類標(Labels) y_true = X # 定義loss誤差計算 最小化平方差 cost = tf.reduce_mean(tf.pow(y_true - y_pred, 2)) optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost) #-------------------------------------訓練及可視化------------------------------------- # 初始化 init = tf.initialize_all_variables() # 訓練集可視化操作 with tf.Session() as sess: sess.run(init) total_batch = int(mnist.train.num_examples/batch_size) # 訓練數據 training_epochs為5組實驗 for epoch in range(training_epochs): # Loop over all batches for i in range(total_batch): batch_xs, batch_ys = mnist.train.next_batch(batch_size) # max(x)=1 min(x)=0 # 運行初始化和誤差計算操作 _, c = sess.run([optimizer, cost], feed_dict={X: batch_xs}) # 每個epoch顯示誤差值 if epoch % display_step == 0: print("Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(c)) print("Optimization Finished!") # 壓縮和解壓測試集 encode_decode = sess.run( y_pred, feed_dict={X: mnist.test.images[:examples_to_show]}) # 比較原始圖像和預測圖像數據 f, a = plt.subplots(2, 10, figsize=(10, 2)) # 顯示結果 上面10個樣本是真實數據 下面10個樣本是預測結果 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()
三.特征聚類分析
第一部分實驗完成,它對比了10張原始圖像和預測圖像。我們接着分享第二部分的實驗,生成聚類圖。
第一步,修改參數。
修改如下,學習效率設置為0.001,訓練批次設置為20。
# 基礎參數設置 learning_rate = 0.001 #學習效率 training_epochs = 20 #20組訓練 batch_size = 256 #batch大小 display_step = 1
第二步,增加encoder和decoder層數,並修改參數。
我們將隱藏層設置為4層,這樣的效果會更好。首先從784壓縮到128,再壓縮到64、10,最后壓縮到只有2個元素(特征),從而顯示在二維圖像上。同時更新weights值和biases值,encoder和decoder都設置為4層。
# 隱藏層設置 n_hidden_1 = 128 #第一層特征數量 n_hidden_2 = 64 #第二層特征數量 n_hidden_3 = 10 #第三層特征數量 n_hidden_4 = 2 #第四層特征數量 weights = { 'encoder_h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])), 'encoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])), 'encoder_h3': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_3])), 'encoder_h4': tf.Variable(tf.random_normal([n_hidden_3, n_hidden_4])), 'decoder_h1': tf.Variable(tf.random_normal([n_hidden_4, n_hidden_3])), 'decoder_h2': tf.Variable(tf.random_normal([n_hidden_3, n_hidden_2])), 'decoder_h3': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_1])), 'decoder_h4': tf.Variable(tf.random_normal([n_hidden_1, n_input])) } biases = { 'encoder_b1': tf.Variable(tf.random_normal([n_hidden_1])), 'encoder_b2': tf.Variable(tf.random_normal([n_hidden_2])), 'encoder_b3': tf.Variable(tf.random_normal([n_hidden_3])), 'encoder_b4': tf.Variable(tf.random_normal([n_hidden_4])), 'decoder_b1': tf.Variable(tf.random_normal([n_hidden_3])), 'decoder_b2': tf.Variable(tf.random_normal([n_hidden_2])), 'decoder_b3': tf.Variable(tf.random_normal([n_hidden_1])), 'decoder_b4': tf.Variable(tf.random_normal([n_input])), }
第三步,修改壓縮和解壓定義函數,也是增加到四層。
#---------------------------------壓縮和解壓函數定義--------------------------------------- # Building the encoder def encoder(x): # 壓縮隱藏層調用函數sigmoid(壓縮值為0-1范圍內) layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']), biases['encoder_b1'])) layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['encoder_h2']), biases['encoder_b2'])) layer_3 = tf.nn.sigmoid(tf.add(tf.matmul(layer_2, weights['encoder_h3']), biases['encoder_b3'])) # 輸出范圍為負無窮大到正無窮大 調用matmul函數 layer_4 = tf.add(tf.matmul(layer_3, weights['encoder_h4']), biases['encoder_b4']) return layer_4 # Building the decoder def decoder(x): # 解壓隱藏層調用sigmoid激活函數(范圍內為0-1區間) layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']), biases['decoder_b1'])) layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['decoder_h2']), biases['decoder_b2'])) layer_3 = tf.nn.sigmoid(tf.add(tf.matmul(layer_2, weights['decoder_h3']), biases['decoder_b3'])) layer_4 = tf.nn.sigmoid(tf.add(tf.matmul(layer_3, weights['decoder_h4']), biases['decoder_b4'])) return layer_4
第四步,最后修改訓練代碼,我們不再觀看它的訓練結果,而是觀察它解壓前的結果。
# 觀察解壓前的結果 encoder_result = sess.run(encoder_op, feed_dict={X: mnist.test.images}) # 顯示encoder壓縮成2個元素的預測結果 plt.scatter(encoder_result[:, 0], encoder_result[:, 1], c=mnist.test.labels) plt.colorbar() plt.show()
完整代碼如下:
# -*- coding: utf-8 -*- """ Created on Wed Jan 15 15:35:47 2020 @author: xiuzhang Eastmount CSDN """ import numpy as np import tensorflow as tf import matplotlib.pyplot as plt from tensorflow.examples.tutorials.mnist import input_data #-----------------------------------初始化設置--------------------------------------- # 基礎參數設置 learning_rate = 0.001 #學習效率 training_epochs = 20 #20組訓練 batch_size = 256 #batch大小 display_step = 1 examples_to_show = 10 #顯示10個樣本 # 神經網絡輸入設置 n_input = 784 #MNIST輸入數據集(28*28) # 輸入變量(only pictures) X = tf.placeholder("float", [None, n_input]) # 隱藏層設置 n_hidden_1 = 128 #第一層特征數量 n_hidden_2 = 64 #第二層特征數量 n_hidden_3 = 10 #第三層特征數量 n_hidden_4 = 2 #第四層特征數量 weights = { 'encoder_h1': tf.Variable(tf.random_normal([n_input, n_hidden_1])), 'encoder_h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])), 'encoder_h3': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_3])), 'encoder_h4': tf.Variable(tf.random_normal([n_hidden_3, n_hidden_4])), 'decoder_h1': tf.Variable(tf.random_normal([n_hidden_4, n_hidden_3])), 'decoder_h2': tf.Variable(tf.random_normal([n_hidden_3, n_hidden_2])), 'decoder_h3': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_1])), 'decoder_h4': tf.Variable(tf.random_normal([n_hidden_1, n_input])) } biases = { 'encoder_b1': tf.Variable(tf.random_normal([n_hidden_1])), 'encoder_b2': tf.Variable(tf.random_normal([n_hidden_2])), 'encoder_b3': tf.Variable(tf.random_normal([n_hidden_3])), 'encoder_b4': tf.Variable(tf.random_normal([n_hidden_4])), 'decoder_b1': tf.Variable(tf.random_normal([n_hidden_3])), 'decoder_b2': tf.Variable(tf.random_normal([n_hidden_2])), 'decoder_b3': tf.Variable(tf.random_normal([n_hidden_1])), 'decoder_b4': tf.Variable(tf.random_normal([n_input])), } # 導入MNIST數據 mnist = input_data.read_data_sets("MNIST_data", one_hot=False) #---------------------------------壓縮和解壓函數定義--------------------------------------- # Building the encoder def encoder(x): # 壓縮隱藏層調用函數sigmoid(壓縮值為0-1范圍內) layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['encoder_h1']), biases['encoder_b1'])) layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['encoder_h2']), biases['encoder_b2'])) layer_3 = tf.nn.sigmoid(tf.add(tf.matmul(layer_2, weights['encoder_h3']), biases['encoder_b3'])) # 輸出范圍為負無窮大到正無窮大 調用matmul函數 layer_4 = tf.add(tf.matmul(layer_3, weights['encoder_h4']), biases['encoder_b4']) return layer_4 # Building the decoder def decoder(x): # 解壓隱藏層調用sigmoid激活函數(范圍內為0-1區間) layer_1 = tf.nn.sigmoid(tf.add(tf.matmul(x, weights['decoder_h1']), biases['decoder_b1'])) layer_2 = tf.nn.sigmoid(tf.add(tf.matmul(layer_1, weights['decoder_h2']), biases['decoder_b2'])) layer_3 = tf.nn.sigmoid(tf.add(tf.matmul(layer_2, weights['decoder_h3']), biases['decoder_b3'])) layer_4 = tf.nn.sigmoid(tf.add(tf.matmul(layer_3, weights['decoder_h4']), biases['decoder_b4'])) return layer_4 #-----------------------------------壓縮和解壓操作--------------------------------------- # Construct model # 壓縮:784 => 128 encoder_op = encoder(X) # 解壓:784 => 128 decoder_op = decoder(encoder_op) #--------------------------------對比預測和真實結果--------------------------------------- # 預測 y_pred = decoder_op # 輸入數據的類標(Labels) y_true = X # 定義loss誤差計算 最小化平方差 cost = tf.reduce_mean(tf.pow(y_true - y_pred, 2)) optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost) #-------------------------------------訓練及可視化------------------------------------- # 初始化 init = tf.initialize_all_variables() # 訓練集可視化操作 with tf.Session() as sess: sess.run(init) total_batch = int(mnist.train.num_examples/batch_size) # 訓練數據 for epoch in range(training_epochs): # Loop over all batches for i in range(total_batch): batch_xs, batch_ys = mnist.train.next_batch(batch_size) # max(x)=1 min(x)=0 # 運行初始化和誤差計算操作 _, c = sess.run([optimizer, cost], feed_dict={X: batch_xs}) # 每個epoch顯示誤差值 if epoch % display_step == 0: print("Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(c)) print("Optimization Finished!") # 觀察解壓前的結果 encoder_result = sess.run(encoder_op, feed_dict={X: mnist.test.images}) # 顯示encoder壓縮成2個元素的預測結果 plt.scatter(encoder_result[:, 0], encoder_result[:, 1], c=mnist.test.labels) plt.colorbar() plt.show()
這個訓練過程需要一點時間,運行結果如下圖所示:
聚類顯示結果如下圖所示,它將不同顏色的分在一堆,對應不同的數字。比如左下角數據集被無監督學習聚類為數字0,而另一邊又是其他的數據。
但其聚類結果還有待改善,因為這只是Autoencoder的一個簡單例子。希望這篇文章能夠幫助博友們理解和認識無監督學習和Autoencoder算法,后續作者會更深入的分享好案例。
參考文獻:
[1] 楊秀璋, 顏娜. Python網絡數據爬取及分析從入門到精通(分析篇)[M]. 北京:北京航天航空大學出版社, 2018.
[2] “莫煩大神” 網易雲視頻地址
[3] https://study.163.com/course/courseLearn.htm?courseId=1003209007
[4] https://github.com/siucaan/CNN_MNIST
[5] https://github.com/eastmountyxz/AI-for-TensorFlow
[6]《機器學習》周志華
[7] 深度學習(07)RNN-循環神經網絡-02-Tensorflow中的實現 - 莫失莫忘Lawlite
[8] https://github.com/lawlite19/DeepLearning_Python