最近開始學習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
- mm=size(data,2);
- z2=(W1*data)+repmat(b1,1,mm);
- a2=sigmoid(z2);
- z3=(W2*a2)+repmat(b2,1,mm);
- a3=sigmoid(z3);
- rho=sum(a2,2)./mm;
- cost=1/2/mm*sum(sum((a3-data).^2))+lambda/2*(sum(sum(W1.^2))+sum(sum(W2.^2)))+beta*sum(kldiverge(rho,sparsityParam));
- for i=1:mm
- x=data(:,i);
- delta3=-(x-a3(:,i)).*sigmoidGradient(z3(:,i));
- delta2=(W2'*delta3+beta*(-sparsityParam./rho+(1-sparsityParam)./(1-rho))).*sigmoidGradient(z2(:,i));
- W1grad=W1grad+delta2*x';
- W2grad=W2grad+delta3*a2(:,i)';
- b1grad=b1grad+delta2;
- b2grad=b2grad+delta3;
- end
- b1grad=b1grad/mm;
- b2grad=b2grad/mm;
- W1grad=W1grad/mm+lambda*W1;
- W2grad=W2grad/mm+lambda*W2;
下面是完全vectorization後的代碼:
[python] view plain copy
- mm=size(data,2);
- z2=(W1*data)+repmat(b1,1,mm);
- a2=sigmoid(z2);
- z3=(W2*a2)+repmat(b2,1,mm);
- a3=sigmoid(z3);
- rho=sum(a2,2)./mm;
- cost=1/2/mm*sum(sum((a3-data).^2))+lambda/2*(sum(sum(W1.^2))+sum(sum(W2.^2)))+beta*sum(kldiverge(rho,sparsityParam));
- sparityy=(-sparsityParam./rho+(1-sparsityParam)./(1-rho));
- x=data();
- delta3=-(x-a3).*sigmoidGradient(z3);
- delta2=(W2'*delta3+repmat(beta*sparityy,1,mm)).*a2.*(1-a2);
- W1grad=W1grad+delta2*x';
- W2grad=W2grad+delta3*a2';
- b1grad=b1grad+sum(delta2,2);
- b2grad=b2grad+sum(delta3,2);
- b1grad=b1grad/mm;
- b2grad=b2grad/mm;
- W1grad=W1grad/mm+lambda*W1;
- W2grad=W2grad/mm+lambda*W2;
出錯這麼久的主要原因就是我按照文檔給的步驟計算:
但實際上這個步驟計算的是J(W,b;x,y),是針對某個訓練資料來的,即使你把所有的累積起來,并沒有滿足要求
因為真正的梯度計算式子是:
我們算的不過是求和符号的那一坨,還需要加入外面的部分
看起來不止我一個人犯了這樣的錯誤,因為微網誌上一人帖的代碼也有問題
訓練結果:
嗯嗯,就這樣了,話說matlab 2012挺好用的