自编码器Autoencoders
生活随笔
收集整理的這篇文章主要介紹了
自编码器Autoencoders
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
深度學習有一個重要的概念叫autoencoder,這是個什么東西呢,本文通過一個例子來普及這個術語。
????
????簡單來說autoencoder是一個壓縮編碼器,也就是對input的一坨東西通過變換,輸出和input一樣的東西。例如input是一個雞,ouput也是一個雞,input是一個鴨,output也是一個鴨。學術一點說就是找到一個函數能夠使得 Function(input) = input,叫做identity function。如上圖所示,即學習Hw,b(x)=x。
????但這和深度學習有什么關系呢? 這就要說到壓縮編碼,我們都知道input需要有一種編碼形式,如果我們能在函數內部找到一個更簡潔的編碼形式,那么這個變換過程就等價于學習到了一種壓縮表示的函數,能夠少量的存儲形式來表示原本較復雜的但信息冗余較大的表示形式。
????我們下面的代碼中舉了一個精彩的例子(這個例子是從同學的一次實驗中直接受啟發,我只是按照自己的理解實現了一把,例子非原創)。在這個例子中,input是4個不同的數字,分別是 ????(0,0,0,1)可以看作1 ????(0,0,1,0)可以看作2 ????(0,1,0,0)可以看作3 ????(1,0,0,0)可以看作4 ????因為所有的input只有這4種,因此其實用4個bit是不經濟的,存在壓縮表示的可能性,比如2個bit就可以表示這4個不同的數。
????那么我們設計了輸入層是4+1(4個腳接受4bit編碼的input,1個腳是常數項,這個用來做先驗的);隱藏層2+1(因為我們實現已經知道2個bit就夠了,所以2個隱藏層,具有足夠的表達能力);輸出層4(為了能讓輸出和輸入保持一致) ?? ????通過數輪迭代,我們看到如下的情況 ????(0,0,0,1)->(0.99,0.09)->(0.06,0.00,0.01,0.91) ????(0,0,1,0)->(0.85,0.99)->(0.00,0.07,0.90,0.07) ????(0,1,0,0)->(0.01,0.67)->(0.06,0.87,0.11,0.00) ????(1,0,0,0)->(0.12,0.00)->(0.89,0.10,0.00,0.02) ?????input_layer ?hidden_layer ????output_layer ???? ?????hidden層的編碼恰好可以看作是 ?????(0.99,0.09) ?1,0 ?????(0.85,0.99) ?1,1 ?????(0.01,0.67) ?0,1 ?????(0.12,0.00) ?0,0
?????也就是說輸入的(0,0,0,1)可以被1,0 壓縮表示,最終4bit的信息,可以用2bit表示,當然還需要保持邊的權重,但這些邊權重只需要一份,在輸入足夠復雜的時候,壓縮表示是有價值的。
?????那壓縮表示有什么價值呢?比如一組廣告,一條新聞,人看了挺好,壓縮表示后,人看起來就不爽了,恰恰是人看著不爽了,機器就好處理了,下回再說。。
???????其他相關可參見美軍參考資料: ???????http://ufldl.stanford.edu/wiki/index.php/Autoencoders_and_Sparsity
????但這和深度學習有什么關系呢? 這就要說到壓縮編碼,我們都知道input需要有一種編碼形式,如果我們能在函數內部找到一個更簡潔的編碼形式,那么這個變換過程就等價于學習到了一種壓縮表示的函數,能夠少量的存儲形式來表示原本較復雜的但信息冗余較大的表示形式。
????我們下面的代碼中舉了一個精彩的例子(這個例子是從同學的一次實驗中直接受啟發,我只是按照自己的理解實現了一把,例子非原創)。在這個例子中,input是4個不同的數字,分別是 ????(0,0,0,1)可以看作1 ????(0,0,1,0)可以看作2 ????(0,1,0,0)可以看作3 ????(1,0,0,0)可以看作4 ????因為所有的input只有這4種,因此其實用4個bit是不經濟的,存在壓縮表示的可能性,比如2個bit就可以表示這4個不同的數。
????那么我們設計了輸入層是4+1(4個腳接受4bit編碼的input,1個腳是常數項,這個用來做先驗的);隱藏層2+1(因為我們實現已經知道2個bit就夠了,所以2個隱藏層,具有足夠的表達能力);輸出層4(為了能讓輸出和輸入保持一致) ?? ????通過數輪迭代,我們看到如下的情況 ????(0,0,0,1)->(0.99,0.09)->(0.06,0.00,0.01,0.91) ????(0,0,1,0)->(0.85,0.99)->(0.00,0.07,0.90,0.07) ????(0,1,0,0)->(0.01,0.67)->(0.06,0.87,0.11,0.00) ????(1,0,0,0)->(0.12,0.00)->(0.89,0.10,0.00,0.02) ?????input_layer ?hidden_layer ????output_layer ???? ?????hidden層的編碼恰好可以看作是 ?????(0.99,0.09) ?1,0 ?????(0.85,0.99) ?1,1 ?????(0.01,0.67) ?0,1 ?????(0.12,0.00) ?0,0
?????也就是說輸入的(0,0,0,1)可以被1,0 壓縮表示,最終4bit的信息,可以用2bit表示,當然還需要保持邊的權重,但這些邊權重只需要一份,在輸入足夠復雜的時候,壓縮表示是有價值的。
?????那壓縮表示有什么價值呢?比如一組廣告,一條新聞,人看了挺好,壓縮表示后,人看起來就不爽了,恰恰是人看著不爽了,機器就好處理了,下回再說。。
???????其他相關可參見美軍參考資料: ???????http://ufldl.stanford.edu/wiki/index.php/Autoencoders_and_Sparsity
以下是實驗代碼,水平有限,僅供參考。
#include <iostream> #include "math.h" using namespace std; double d = 0.4; double function_g(double x) {double ex = pow(2.718281828,x);return ex/(1+ex); }double input[4][5]={{0,0,0,1,1}, //{0,0,0,1} {1}{0,0,1,0,1},{0,1,0,0,1},{1,0,0,0,1}};double edge_1[2][5]; double edge_2[4][3]; double first_layer[5]; double hidden_layer[3]={0,0,1}; double output_layer[4];double diff() {double ret = 0.0;for(int i=0;i<4;++i){ret += (output_layer[i]-first_layer[i])*(output_layer[i]-first_layer[i]);}return ret; } void count_second_l( ) {for(int i=0;i<2;++i){hidden_layer[i] = 0;for(int j=0;j<5;++j){hidden_layer[i] += first_layer[j]*edge_1[i][j];}hidden_layer[i] = function_g(hidden_layer[i]);}return; } void count_last_l() {for(int i=0;i<4;++i){output_layer[i] = 0;for(int j=0;j<3;++j){output_layer[i] += hidden_layer[j]*edge_2[i][j];}output_layer[i] = function_g(output_layer[i]);}return; } double total_diff() {double ret = 0.0;for( int j=0;j<4;++j){first_layer[0]=input[j][0];first_layer[1]=input[j][1];first_layer[2]=input[j][2];first_layer[3]=input[j][3];first_layer[4]=input[j][4];count_second_l();count_last_l();ret += diff();}return ret; }int main(void) {for(int i=0;i<2;++i)for(int j=0;j<5;++j)edge_1[i][j] = ((i+j)%4+0.1)/10; //initialize each edges between first_layers and hidden layersfor(int i=0;i<4;++i)for(int j=0;j<3;++j)edge_2[i][j] = ((i+j)%4+0.1)/10; //initialize each edges between hidden_layers and output_layersfor(int i=0;i<40000;++i) //iterate 40000 times{double origin_diff=total_diff();double direction_1[2][5],direction_2[4][3];for(int i=0;i<2;++i)for(int j=0;j<5;++j){double tmp = edge_1[i][j] ;edge_1[i][j] += d * origin_diff;count_second_l();count_last_l();double diff2 = total_diff();direction_1[i][j] = origin_diff - diff2;edge_1[i][j] = tmp;}for(int i=0;i<4;++i)for(int j=0;j<3;++j){double tmp = edge_2[i][j] ;edge_2[i][j] += d * origin_diff;count_second_l();count_last_l();double diff2 = total_diff();direction_2[i][j] = origin_diff - diff2;edge_2[i][j] = tmp;}for(int i=0;i<2;++i)for(int j=0;j<5;++j){edge_1[i][j] += d * origin_diff * direction_1[i][j];}for(int i=0;i<4;++i)for(int j=0;j<3;++j){edge_2[i][j] += d * origin_diff * direction_2[i][j];}double d = 0.0; for( int j=0;j<4;++j){first_layer[0]=input[j][0];first_layer[1]=input[j][1];first_layer[2]=input[j][2];first_layer[3]=input[j][3];first_layer[4]=input[j][4];count_second_l();count_last_l();d += diff();cout<<"####################"<<endl;cout<<"input:\t"<<first_layer[0]<<"\t"<<first_layer[1]<<"\t"<<first_layer[2]<<"\t"<<first_layer[3]<<endl;cout<<"output:\t"<<output_layer[0]<<"\t"<<output_layer[1]<<"\t"<<output_layer[2]<<"\t"<<output_layer[3]<<endl;cout<<"hidden:\t"<<hidden_layer[0]<<"\t"<<hidden_layer[1]<<endl;cout<<"####################"<<endl;}cout<<"diff_sum:"<<d<<endl;} }
from:?http://blog.sina.com.cn/s/blog_593af2a70101endk.html
總結
以上是生活随笔為你收集整理的自编码器Autoencoders的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 条件随机场CRF简介Introducti
- 下一篇: BP反向传播算法浅谈(Error Bac