最近开始学习UFLDL,一个deep learning的教程
这个练习的地址:http://deeplearning.stanford.edu/wiki/index.php/Exercise:Sparse_Autoencoder
Sparse Autoencoder是用神经网络进行feature learning的一个算法,详细的就见教程,我只是贴贴代码
从早上十点多一直debug到下午四点多,问题多多,究其原因还是对算法理解不够深刻,虽然以前还写过一个nn
所以收获还是有的,理解算法嘛
最主要的部分就是sparseAutoencoderCost.m了
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后的代码:
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挺好用的