UFLDL即(unsupervised feature learning & deep learning)。這是斯坦福網站上的一篇經典教程。顧名思義,你將在這篇這篇文章中學習到無監督特征學習和深度學習的主要觀點。
UFLDL全文出處在這:http://ufldl.stanford.edu/wiki/index.php/UFLDL%E6%95%99%E7%A8%8B,本文為本人原創,參考了UFLDL的教程,是我自己個人對於這一系列教程的理解以及自己的實驗結果。非盈利性質網站轉載請在文章開頭處著名本文作者:77695,來源http://www.cnblogs.com/cj695/。盈利性質網站轉載請與作者聯系,聯系方式在文章后面。如未聯系,本人將通過一切可能且合法的途徑追繳相應稿酬。請在轉載時保留此聲明。
神經網絡
一個神經網絡由一系列神經元組成,一個神經元由一系列參數x1,x2。。。及偏置量+1作為輸入,將輸入與對應權值W(與x1,x2。。。相乘),(與1相乘)相乘后求和,並將和放入激活函數,即可得到該神經元的輸出。我們稱這個神經元的輸入-輸出映射關系其實就是一個邏輯回歸(logistic regression)
在這里激活函數我們用:
這是sigmoid函數的圖像
整個神經元可以用一個公式表示:
神經網絡就是很多個神經元組合在一起,一個神經元的輸出,也可以是另外一個神經元的輸入,如下圖:
具體請直接查看UFLDL相應教程,這里不再贅述,下文一樣。
反向傳導算法
一個神經網絡向前傳導,其神經元的參數可以是各種各樣的,這樣也會導致各種各樣的借,而我希望我整個神經網絡的輸出,是與我預期的輸出越相近越好,為了描述相近的程度,我們計算神經網絡輸出與預計輸出的差值的平方和。這個和越小,即輸出與預期越接近,我們稱這個叫做代價函數。但使得輸出與預期接近的W參數組合有很多,並不是每一種組合都好,也不是說越接近越好,當W參數太大的時候,會發生過擬合,使得泛化能力不夠,因此我們引入所有W的平方和,加入到代價函數中,我們稱它叫懲罰項。我們使用梯度下降法,求得最優的W,b這就是機器學習的整個過程。梯度下降中,其實就是求得代價函數對W,b的偏導值。在計算偏導的時候,因為復合函數的求導法則:
可以看到,要求整個懲罰函數的導數首先就要計算從懲罰函數開始向后求導,具體公式這里就不貼了。
梯度檢驗
要檢測自己反向傳導得到的偏導函數是否正確,這里有一種簡單粗暴的方法,就是梯度檢驗,通過對某一個參數加以及減一個較小的值的差除以2倍較小的值即可近似算出該點偏導值,因此可以用來檢驗偏導是否計算正確。但為什么我們不直接用這個計算代替求偏導函數,因為太慢了!
在這里我們用L-BFGS算法快速計算偏導數
自編碼算法與稀疏性
使得輸出盡可能與輸入一致我們稱之為自編碼。比如,若隱藏層神經元數目小於輸入層,則這個網絡就要學習怎么去壓縮這些數據。使得神經元大部分的時間都是被抑制的限制則被稱作稀疏性限制。其懲罰函數如下:
可視化自編碼器訓練結果
實現
生成數據集:即從所有10副512x512的圖片中取8x8的塊,一共取10000塊。
這是數據集的一些圖片,可以看到這主要是一些自然圖片。
這里只粘貼所有自己實現部分的代碼。
[w,h,n]=size(IMAGES);
randx=randi(w-patchsize,1,numpatches);
randy=randi(h-patchsize,1,numpatches);
randIdx=randi(n,1,numpatches);
for i=1 : numpatches
pc=IMAGES(randx(i):randx(i)+patchsize-1,randy(i):randy(i)+patchsize-1,randIdx(i));
patches(:,i)=pc(:);
end
生成結果如下:
實現懲罰函數以及梯度函數:按照之前的公式計算,大家直接看代碼吧。
[l,n]=size(data);
dataHidden=sigmoid(W1*data+b1*ones(1,n));
dataOut=sigmoid(W2*dataHidden+b2*ones(1,n));
rou=sum(dataHidden,2)/n;
spCost=beta*(sum((sparsityParam*log(sparsityParam*ones(size(rou))./rou)...
+(1-sparsityParam)*log(((1-sparsityParam)*ones(size(rou)))./(1-rou)))));
xyCost=(sum(sum((dataOut-data).*(dataOut-data))))/2/n;
wCost=(lambda/2)*((sum(sum(W1.*W1))+sum(sum(W2.*W2))));
cost=wCost+xyCost+spCost;
delta3=-(data-dataOut).*dataOut.*(1-dataOut);
spDt=beta*((-sparsityParam*ones(size(rou))./rou)+(((1-sparsityParam)...
*ones(size(rou)))./(ones(size(rou))-rou)));
delta2=((W2')*delta3+spDt*ones(1,n)).*dataHidden.*(1-dataHidden);
W2grad=(delta3*(dataHidden'))/n+lambda*W2;
W1grad=(delta2*(data'))/n+lambda*W1;
b2grad=delta3*ones(n,1)/n;
b1grad=delta2*ones(n,1)/n;
實現時候出了一個問題,算梯度的時候少加了lambda*W1,粗心害死人啊!
梯度檢驗:按照公式實現梯度檢驗,檢驗實現的梯度是否正確。
for i=1 :(size(theta,1))
e = zeros(size(theta));
e(i)=EPSILON;
cha=(J(theta+e)-J(theta-e));
numgrad(i)=cha/(2*EPSILON);
end
看到運行結果
只差10^-12數量級,說明梯度檢驗的實現沒錯
訓練以及結果:
最后運行得到結果如下:
可以看到學習出來的結果基本是圖片相互正交的部分,相當於傅立葉變換中不同頻率正弦波,相當於很多正交的基,這些“基”以一定的權重相加,就能夠近似組成任何一個8x8的圖片塊。
另外值得一提的是,對於梯度下降算法,在這里使用的是L-BFGS算法,對於這個算法,我們不能將它用於商業用途,若用與商業用途的話,可以使用fminlbfgs函數,他比L-BFGS慢但可用於商業用途。
















