Keras搭建自編碼器操作
簡介:
傳統機器學習任務任務很大程度上依賴於好的特徵工程,但是特徵工程往往耗時耗力,在視訊、語音和視訊中提取到有效特徵就更難了,工程師必須在這些領域有非常深入的理解,並且需要使用專業演算法提取這些資料的特徵。深度學習則可以解決人工難以提取有效特徵的問題,大大緩解機器學習模型對特徵工程的依賴。
深度學習在早期一度被認為是一種無監督的特徵學習過程,模仿人腦對特徵逐層抽象的過程。這其中兩點很重要:一是無監督學習;二是逐層訓練。例如在影象識別問題中,假定我們有許多汽車圖片,要如何利用計算機進行識別任務呢?如果從畫素級開始進行訓練分類器,那麼絕大多數演算法很難工作。如果我們提取高階特徵,比如汽車的車輪、汽車的車窗、車身等。那麼就可以使用這些高階特徵非常準確的對影象進行分類。不過高階特徵都是由底層特徵組成,這便是深度學習訓練過程中所做的特徵學習。
早年有學者發現,可以使用少量的基本特徵進行組合拼裝得到更高層抽象的特徵,這其實就是我們常說的特徵的稀疏表達。對影象任務來說,一張原始圖片可以由較少的圖片碎片組合得到。對語音識別任務來講,絕大多數的聲音也可以由一些基本的結構線性組合得到。對人臉識別任務來說,根據不同的器官,如:鼻子、嘴、眉毛、眼睛瞪,這些器官可以向上拼出不同樣式的人臉,最後模型通過在圖片中匹配這些不同樣式的人臉來進行識別。在深度神經網路中,對每一層神經網路來說前一層的輸出都是未加工的畫素,而這一層則是對畫素進行加工組織成更高階的特徵的過程(即前面提到過的圖片碎片進行線性組合加工的過程)。
根據上述基本概念的描述,特徵是可以不斷抽象轉為高一層特徵的,那我們如何找到這些基本結構,然後如何抽象?這裡引出無監督的自編碼器來提取特徵。自編碼器--顧名思義,可以使用自身高階特徵編碼自己。它的輸入和輸出是一致的。因此,它的基本思想是使用稀疏一些高階特徵重新組合來重構自己。自編碼器的剛開始提出是Hinton在Science上發表文章,用來解決資料降維問題。此外,Hinton還提出了基於深度信念網路的無監督逐層訓練的貪心演算法,為訓練很深的網路提供了一個可行的方案。深度信念網路的提出是使用逐層訓練的方式提取特徵,使得在有監督學習任務之前,使得網路權重初始化到一個比較好的位置。其思想與自編碼器的非常相似。在此基礎上,國內外學者又提出了自編碼器的各種版本,如:稀疏自編碼器、去噪自編碼器等。
本文使用Keras深度學習開發庫,在MNIST資料集上實現了簡單自編碼器、深度稀疏自編碼器和卷積自編碼器。
自編碼器用途:
目前自編碼器的應用主要有兩個方面,第一是資料去噪,第二是為進行視覺化而降維。配合適當的維度和稀疏約束,自編碼器可以學習到比PCA等技術更有意思的資料投影。此外,在資料共有特徵建模方面,也有叫廣泛的應用。
1、簡單自編碼器
簡單自編碼器
from keras.layers import Input,Dense from keras.models import Model from keras.datasets import mnist import numpy as np import matplotlib.pyplot as plt (x_train,_),(x_test,_) = mnist.load_data() x_train = x_train.astype('float32') / 255. x_test = x_test.astype('float32') / 255. x_train = x_train.reshape((len(x_train),np.prod(x_train.shape[1:]))) x_test = x_test.reshape((len(x_test),np.prod(x_test.shape[1:]))) print(x_train.shape) print(x_test.shape) encoding_dim = 32 input_img = Input(shape=(784,)) encoded = Dense(encoding_dim,activation='relu')(input_img) decoded = Dense(784,activation='sigmoid')(encoded) autoencoder = Model(inputs=input_img,outputs=decoded) encoder = Model(inputs=input_img,outputs=encoded) encoded_input = Input(shape=(encoding_dim,)) decoder_layer = autoencoder.layers[-1] decoder = Model(inputs=encoded_input,outputs=decoder_layer(encoded_input)) autoencoder.compile(optimizer='adadelta',loss='binary_crossentropy') autoencoder.fit(x_train,x_train,epochs=50,batch_size=256,shuffle=True,validation_data=(x_test,x_test)) encoded_imgs = encoder.predict(x_test) decoded_imgs = decoder.predict(encoded_imgs) n = 10 # how many digits we will display plt.figure(figsize=(20,4)) for i in range(n): ax = plt.subplot(2,n,i + 1) plt.imshow(x_test[i].reshape(28,28)) plt.gray() ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) ax = plt.subplot(2,i + 1 + n) plt.imshow(decoded_imgs[i].reshape(28,28)) plt.gray() ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) plt.show()
測試效果:
2、深度自編碼器、稀疏自編碼器
為解決自編碼重構損失大的問題,使用多層網路搭建自編碼器。對隱層單元施加稀疏性約束的話,會得到更為緊湊的表達,只有一小部分神經元會被啟用。在Keras中,我們可以通過新增一個activity_regularizer達到對某層啟用值進行約束的目的
import numpy as np np.random.seed(1337) # for reproducibility from keras.datasets import mnist from keras.models import Model #泛型模型 from keras.layers import Dense,Input import matplotlib.pyplot as plt # X shape (60,000 28x28),y shape (10,000,) (x_train,y_test) = mnist.load_data() # 資料預處理 x_train = x_train.astype('float32') / 255. # minmax_normalized x_test = x_test.astype('float32') / 255. # minmax_normalized x_train = x_train.reshape((x_train.shape[0],-1)) x_test = x_test.reshape((x_test.shape[0],-1)) print(x_train.shape) print(x_test.shape) # 壓縮特徵維度至2維 encoding_dim = 2 # this is our input placeholder input_img = Input(shape=(784,)) # 編碼層 encoded = Dense(128,activation='relu')(input_img) encoded = Dense(64,activation='relu')(encoded) encoded = Dense(10,activation='relu')(encoded) encoder_output = Dense(encoding_dim)(encoded) # 解碼層 decoded = Dense(10,activation='relu')(encoder_output) decoded = Dense(64,activation='relu')(decoded) decoded = Dense(128,activation='relu')(decoded) decoded = Dense(784,activation='tanh')(decoded) # 構建自編碼模型 autoencoder = Model(inputs=input_img,outputs=decoded) # 構建編碼模型 encoder = Model(inputs=input_img,outputs=encoder_output) # compile autoencoder autoencoder.compile(optimizer='adam',loss='mse') autoencoder.summary() encoder.summary() # training autoencoder.fit(x_train,epochs=10,shuffle=True) # plotting encoded_imgs = encoder.predict(x_test) plt.scatter(encoded_imgs[:,0],encoded_imgs[:,1],c=y_test,s=3) plt.colorbar() plt.show() decoded_imgs = autoencoder.predict(x_test) # use Matplotlib (don't ask) import matplotlib.pyplot as plt n = 10 # how many digits we will display plt.figure(figsize=(20,4)) for i in range(n): # display original ax = plt.subplot(2,28)) plt.gray() ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) # display reconstruction ax = plt.subplot(2,28)) plt.gray() ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) plt.show()
執行結果:
3、卷積自編碼器
卷積自編碼器的編碼器部分由卷積層和MaxPooling層構成,MaxPooling負責空域下采樣。而解碼器由卷積層和上取樣層構成。
from keras.layers import Input,Dense,Convolution2D,MaxPooling2D,UpSampling2D from keras.models import Model from keras.datasets import mnist import numpy as np (x_train,_) = mnist.load_data() x_train = x_train.astype('float32') / 255. x_test = x_test.astype('float32') / 255. print('---> x_train shape: ',x_train.shape) x_train = np.reshape(x_train,(len(x_train),28,1)) x_test = np.reshape(x_test,(len(x_test),1)) print('---> xtrain shape: ',x_train.shape) print('---> x_test shape: ',x_test.shape) input_img = Input(shape=(28,1)) x = Convolution2D(16,(3,3),activation='relu',padding='same')(input_img) x = MaxPooling2D((2,2),padding='same')(x) x = Convolution2D(8,padding='same')(x) x = MaxPooling2D((2,padding='same')(x) encoded = MaxPooling2D((2,padding='same')(x) x = Convolution2D(8,padding='same')(encoded) x = UpSampling2D((2,2))(x) x = Convolution2D(8,padding='same')(x) x = UpSampling2D((2,2))(x) x = Convolution2D(16,activation='relu')(x) x = UpSampling2D((2,2))(x) decoded = Convolution2D(1,activation='sigmoid',padding='same')(x) autoencoder = Model(inputs=input_img,outputs=decoded) autoencoder.compile(optimizer='adadelta',loss='binary_crossentropy') # 開啟一個終端並啟動TensorBoard,終端中輸入 tensorboard --logdir=/autoencoder autoencoder.fit(x_train,x_test)) decoded_imgs = autoencoder.predict(x_test) import matplotlib.pyplot as plt decoded_imgs = autoencoder.predict(x_test) n = 10 plt.figure(figsize=(20,4)) for i in range(1,n+1): # display original ax = plt.subplot(2,i) plt.imshow(x_test[i].reshape(28,i + n) plt.imshow(decoded_imgs[i].reshape(28,28)) plt.gray() ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) plt.show()
訓練結果展示:
以上這篇Keras搭建自編碼器操作就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。