天天看點

UFLDL練習(Sparse Autoencoder)

最近開始學習UFLDL,一個deep learning的教程

這個練習的位址:http://deeplearning.stanford.edu/wiki/index.php/Exercise:Sparse_Autoencoder

Sparse Autoencoder是用神經網絡進行feature learning的一個算法,詳細的就見教程,我隻是貼貼代碼

從早上十點多一直debug到下午四點多,問題多多,究其原因還是對算法了解不夠深刻,雖然以前還寫過一個nn

是以收獲還是有的,了解算法嘛

最主要的部分就是sparseAutoencoderCost.m了

[python]  view plain  copy

  1. mm=size(data,2);  
  2. z2=(W1*data)+repmat(b1,1,mm);  
  3. a2=sigmoid(z2);  
  4. z3=(W2*a2)+repmat(b2,1,mm);  
  5. a3=sigmoid(z3);  
  6. rho=sum(a2,2)./mm;  
  7. cost=1/2/mm*sum(sum((a3-data).^2))+lambda/2*(sum(sum(W1.^2))+sum(sum(W2.^2)))+beta*sum(kldiverge(rho,sparsityParam));  
  8. for i=1:mm  
  9.  x=data(:,i);  
  10.  delta3=-(x-a3(:,i)).*sigmoidGradient(z3(:,i));  
  11.  delta2=(W2'*delta3+beta*(-sparsityParam./rho+(1-sparsityParam)./(1-rho))).*sigmoidGradient(z2(:,i));  
  12.  W1grad=W1grad+delta2*x';  
  13.  W2grad=W2grad+delta3*a2(:,i)';  
  14.  b1grad=b1grad+delta2;  
  15.  b2grad=b2grad+delta3;  
  16. end  
  17. b1grad=b1grad/mm;  
  18. b2grad=b2grad/mm;  
  19. W1grad=W1grad/mm+lambda*W1;  
  20. W2grad=W2grad/mm+lambda*W2;  

下面是完全vectorization後的代碼:

[python]  view plain  copy

  1. mm=size(data,2);  
  2. z2=(W1*data)+repmat(b1,1,mm);  
  3. a2=sigmoid(z2);  
  4. z3=(W2*a2)+repmat(b2,1,mm);  
  5. a3=sigmoid(z3);  
  6. rho=sum(a2,2)./mm;  
  7. cost=1/2/mm*sum(sum((a3-data).^2))+lambda/2*(sum(sum(W1.^2))+sum(sum(W2.^2)))+beta*sum(kldiverge(rho,sparsityParam));  
  8. sparityy=(-sparsityParam./rho+(1-sparsityParam)./(1-rho));  
  9.  x=data();  
  10.  delta3=-(x-a3).*sigmoidGradient(z3);  
  11.  delta2=(W2'*delta3+repmat(beta*sparityy,1,mm)).*a2.*(1-a2);  
  12.  W1grad=W1grad+delta2*x';  
  13.  W2grad=W2grad+delta3*a2';  
  14.  b1grad=b1grad+sum(delta2,2);  
  15.  b2grad=b2grad+sum(delta3,2);  
  16. b1grad=b1grad/mm;  
  17. b2grad=b2grad/mm;  
  18. W1grad=W1grad/mm+lambda*W1;  
  19. W2grad=W2grad/mm+lambda*W2;  

出錯這麼久的主要原因就是我按照文檔給的步驟計算:

UFLDL練習(Sparse Autoencoder)

但實際上這個步驟計算的是J(W,b;x,y),是針對某個訓練資料來的,即使你把所有的累積起來,并沒有滿足要求

因為真正的梯度計算式子是:

UFLDL練習(Sparse Autoencoder)

我們算的不過是求和符号的那一坨,還需要加入外面的部分

看起來不止我一個人犯了這樣的錯誤,因為微網誌上一人帖的代碼也有問題

訓練結果:

UFLDL練習(Sparse Autoencoder)

嗯嗯,就這樣了,話說matlab 2012挺好用的

繼續閱讀