生活随笔
收集整理的這篇文章主要介紹了
深度学习(十二)稀疏自编码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
稀疏自編碼
原文地址:http://blog.csdn.net/hjimce/article/details/49106869
作者:hjimce
一、相關理論
以前剛開始學CNN的時候,就是通過閱讀theano的深度學習相關教程源碼,對于CNN的整個過程才有了深入理解。之前雖然懂CNN的原理,但是對于其源碼層的實現,到底要怎么搞,卻有點模糊,之后學了theano的cnn教程后,才知道原來是利用了四維矩陣進行操作。
理解了theano的CNN實現之后,對四維矩陣有了深刻的印象,后來閱讀caffe的源碼的時候,數據結構blob我就把它理解為了四維矩陣。在這里把自己以前閱讀theano的時候,對之前源碼的標注貼一下,以供大家學習,源碼來自于:http://deeplearning.net/tutorial/。學習這些源碼,同時我們也可以熟悉theano的使用,好處多多。所以建議剛入門深度學習的,一定要好好學theano的深度學習教程,好好解讀源碼。
本篇博文主要講解:《稀疏自編碼》算法,及其theano實現,屬于深度學習的基礎知識,高手請繞道。眾所周知,機器學習可以大體分為三大類:監督學習、非監督學習和半監督學習。自編碼神經網絡是一種無監督學習算法,其實如果我們已經對PCA降維、SVD簡化,比較熟悉的話,那么你會發現其實稀疏自編跟它們差不多,一樣的簡單,一樣的無聊……
開始前,我們需要知道什么叫無監督學習,說實話,一年前,我連這個都不懂,因為我本身不是學人工智能方向的、也不是計算機專業、信息專業的。以前雖然學過聚類算法,但是那都是自學,沒有系統的進行相關理論的學習,故而也不知道其實聚類算法就是無監督學習。說的簡單點吧,所謂的無監督學習,就是不需要標簽數據,也就是不需要我們對數據做標注,然后才能進行訓練,數據直接拿過來,就可以進行訓練了。
自編碼的網絡結構如下:
既然自編碼網絡是無標簽數據,是怎么進行訓練的呢?自編碼網絡很有意思,網絡的輸入是X,輸出也是X,這樣就相當于不需要進行數據標注了,屬于無監督學習。那么自編碼有什么用呢?你覺得讓一個網絡,輸入是input=x,輸出output=x,這樣有意思嗎?
? ? 從上面自編碼的網絡結構圖,可以看到一開始輸入特征是x1……x6,有六個特征,然后隱藏層的神經元只有3個,最后又用這3個神經元,要使得網絡的輸出盡量接近x1……x6。這就相當于我們輸入了一個6維的特征向量,我們先把它降維,降到3維,然后我們利用這三維的特征向量,進行重構原始的數據。這個跟PCA降維一模一樣,只不過PCA是通過求解特征向量,進行降維,是一種線性的降維方式,而自編碼可以利用神經網絡進行降維,是一種非線性降維,當然自編碼隱藏層可以很多個神經元,然后我們使用正則化約束項,進行稀疏約束。
? ? 這樣好玩嗎,有意思嗎,把x送進網絡中,結果啥也不干,這個便是我學習自編碼的時候,最大的疑問了,因為我不知道讓一個網絡的輸入是x,最后輸出也是x,這樣有什么意義?要解答上面的網絡有什么用,我們得從深度學習說起,我們知道,在深度學習中,一般網絡都有很多層,因為網絡層數一多,訓練網絡采用的梯度下降,在低層網絡會出現梯度彌散的現象,導致了深度網絡一直不招人待見。直到2006年的3篇論文改變了這種狀況,由Hinton提出了一種深層網絡的訓練方法,改變了人們對深度學習的態度。Hinton所提出的訓練思想,整體過程如下;
1、網絡各層參數預訓練。我們在以前的神經網絡中,參數的初始化都是用隨機初始化方法,然而這種方法,對于深層網絡,在低層中,參數很難被訓練,于是Hinton提出了參數預訓練,這個主要就是采用RBM、以及我們本篇博文要講的自編碼,對網絡的每一層進行參數初始化。也就是我們這邊要學的稀疏自編碼就是為了對網絡的每一層進行參數初始化,僅僅是為了獲得初始的參數值而已。
2、在一個時間里,一個層次的無監督訓練,接著之前訓練的層次。在每一層學習到的表示作為下一層的輸入,對每層網絡的進行訓練初始化。
3、用有監督訓練來調整所有層。
OK,我們回到本篇文章的主題,從上面的解釋中,我們知道稀疏自編碼僅僅只是為了獲得參數的初始值而已。而其實我們上面的網絡結構圖,僅僅只是為了獲取深度學習中,各層網絡的初始參數值而已,一般我們訓練完上后,就會把重構輸出層去掉,只留下隱藏層與輸入層的參數。而這些參數值,將作為本層網絡,與上層網絡的一個連接參數初始值。
二、源碼實現
下面還是把theano的相關代碼實現,貼一下:
[python]?view plaincopy
<span?style="font-family:Arial;">import?os?? import?sys?? import?timeit?? ?? import?numpy?? ?? import?theano?? import?theano.tensor?as?T?? ?? ?? from?logistic_sgd?import?load_data?? from?utils?import?tile_raster_images?? ?? try:?? ????import?PIL.Image?as?Image?? except?ImportError:?? ????import?Image?? ?? ''? ? ?? class?cA(object):?? ?? ????def?__init__(self,?numpy_rng,?input=None,?n_visible=784,?n_hidden=100,?? ?????????????????n_batchsize=1,?W=None,?bhid=None,?bvis=None):?? ????????? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ????????self.n_visible?=?n_visible?? ????????self.n_hidden?=?n_hidden?? ????????self.n_batchsize?=?n_batchsize?? ?????????? ????????if?not?W:?? ????????????''? ? ?? ????????????initial_W?=?numpy.asarray(?? ????????????????numpy_rng.uniform(?? ????????????????????low=-4?*?numpy.sqrt(6.?/?(n_hidden?+?n_visible)),?? ????????????????????high=4?*?numpy.sqrt(6.?/?(n_hidden?+?n_visible)),?? ????????????????????size=(n_visible,?n_hidden)?? ????????????????),?? ????????????????dtype=theano.config.floatX?? ????????????)?? ????????????W?=?theano.shared(value=initial_W,?name='W',?borrow=True)?? ?? ????????if?not?bvis:?? ????????????bvis?=?theano.shared(value=numpy.zeros(n_visible,?? ???????????????????????????????????????????????????dtype=theano.config.floatX),?? ?????????????????????????????????borrow=True)?? ?? ????????if?not?bhid:?? ????????????bhid?=?theano.shared(value=numpy.zeros(n_hidden,?? ???????????????????????????????????????????????????dtype=theano.config.floatX),?? ?????????????????????????????????name='b',?? ?????????????????????????????????borrow=True)?? ?? ????????self.W?=?W?? ?????????? ????????self.b?=?bhid?? ?????????? ????????self.b_prime?=?bvis?? ?????????? ????????self.W_prime?=?self.W.T?? ?? ?????????? ????????if?input?is?None:?? ????????????self.x?=?T.dmatrix(name='input')?? ????????else:?? ????????????self.x?=?input?? ?? ????????self.params?=?[self.W,?self.b,?self.b_prime]?? ?????? ????def?get_hidden_values(self,?input):?? ????????return?T.nnet.sigmoid(T.dot(input,?self.W)?+?self.b)?? ?????? ?????? ????def?get_reconstructed_input(self,?hidden):?? ????????return?T.nnet.sigmoid(T.dot(hidden,?self.W_prime)?+?self.b_prime)?? ?????? ????def?get_jacobian(self,?hidden,?W):?? ????????return?T.reshape(hidden?*?(1?-?hidden),(self.n_batchsize,?1,?self.n_hidden))*T.reshape(W,?(1,?self.n_visible,?self.n_hidden))?? ?? ?????? ????def?get_cost_updates(self,?contraction_level,?learning_rate):?? ????????y?=?self.get_hidden_values(self.x)?? ????????z?=?self.get_reconstructed_input(y)?? ????????J?=?self.get_jacobian(y,?self.W)?? ?????????? ????????self.L_rec?=?-?T.sum(self.x?*?T.log(z)?+(1?-?self.x)?*?T.log(1?-?z),axis=1)?? ?? ?????????? ????????self.L_jacob?=?T.sum(J?**?2)?/?self.n_batchsize?? ?????????? ?????????? ????????cost?=?T.mean(self.L_rec)?+?contraction_level?*?T.mean(self.L_jacob)?? ?? ?????????? ????????gparams?=?T.grad(cost,?self.params)?? ?????????? ????????updates?=?[]?? ????????for?param,?gparam?in?zip(self.params,?gparams):?? ????????????updates.append((param,?param?-?learning_rate?*?gparam))?? ?? ????????return?(cost,?updates)?? ?? ?? def?test_cA(learning_rate=0.01,?training_epochs=20,?? ????????????dataset='mnist.pkl.gz',?? ????????????batch_size=10,?output_folder='cA_plots',?contraction_level=.1):?? ????? ? ? ? ? ? ? ?? ?????? ????datasets?=?load_data(dataset)?? ????train_set_x,?train_set_y?=?datasets[0]?? ?? ?????? ????n_train_batches?=?train_set_x.get_value(borrow=True).shape[0]?/?batch_size?? ?? ?????? ????index?=?T.lscalar()?????? ????x?=?T.matrix('x')???? ?? ????if?not?os.path.isdir(output_folder):?? ????????os.makedirs(output_folder)?? ????os.chdir(output_folder)?? ?? ?? ????rng?=?numpy.random.RandomState(123)?? ?? ????ca?=?cA(numpy_rng=rng,?input=x,?? ????????????n_visible=28?*?28,?n_hidden=500,?n_batchsize=batch_size)?? ?? ????cost,?updates?=?ca.get_cost_updates(contraction_level=contraction_level,?? ????????????????????????????????????????learning_rate=learning_rate)?? ?????? ????train_ca?=?theano.function(?? ????????[index],?? ????????[T.mean(ca.L_rec),?ca.L_jacob],?? ????????updates=updates,?? ????????givens={?? ????????????x:?train_set_x[index?*?batch_size:?(index?+?1)?*?batch_size]?? ????????}?? ????)?? ?? ????start_time?=?timeit.default_timer()?? ?? ?????? ?????? ?????? ?? ?????? ????for?epoch?in?xrange(training_epochs):?? ?????????? ????????c?=?[]?? ????????for?batch_index?in?xrange(n_train_batches):?? ????????????c.append(train_ca(batch_index))?? ?? ????????c_array?=?numpy.vstack(c)?? ????????print?'Training?epoch?%d,?reconstruction?cost?'?%?epoch,?numpy.mean(?? ????????????c_array[0]),?'?jacobian?norm?',?numpy.mean(numpy.sqrt(c_array[1]))?? ?? ????end_time?=?timeit.default_timer()?? ?? ????training_time?=?(end_time?-?start_time)?? ?? ????print?>>?sys.stderr,?('The?code?for?file?'?+?os.path.split(__file__)[1]?+?? ??????????????????????????'?ran?for?%.2fm'?%?((training_time)?/?60.))?? ????image?=?Image.fromarray(tile_raster_images(?? ????????X=ca.W.get_value(borrow=True).T,?? ????????img_shape=(28,?28),?tile_shape=(10,?10),?? ????????tile_spacing=(1,?1)))?? ?? ????image.save('cae_filters.png')?? ?? ????os.chdir('../')?? ?? ?? if?__name__?==?'__main__':?? ????test_cA()</span>??
上面的代碼,來自:http://deeplearning.net/tutorial/。主要是根據文獻:《Contractive Auto-Encoder 》進行編寫的代碼,代碼中,我們需要知道tie-weight、以及文獻所提出的損失函數,所以要閱讀上面的源碼,還是需要把這篇文獻看一下。
參考文獻:
1、《Contractive Auto-Encoder》
2、http://deeplearning.net/tutorial/?
**********************作者:hjimce ? 時間:2015.10.13 ?聯系QQ:1393852684 ? 地址:http://blog.csdn.net/hjimce? ?原創文章,版權所有,轉載請保留本行信息(不允許刪除)
總結
以上是生活随笔為你收集整理的深度学习(十二)稀疏自编码的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。