1. 程式人生 > >ufldl 深度學習入門 第一發:基於BP網路實現稀疏自編碼器

ufldl 深度學習入門 第一發:基於BP網路實現稀疏自編碼器

目的:打算使用深度學習的方式實現人臉關鍵點的檢測,第一步是要學習深度學習。

步驟:第一步在ufldl上面學習深度學習的演算法基礎知識,然後找部落格上基於python呼叫theano庫實現人臉關鍵點檢測的演算法,看懂後基於C++實現,然後用java實現app,呼叫C++實現的演算法。

ufldl上的第一章是基於BP網路實現稀疏自編碼器,在matlab上實現。

稀疏自編碼器的實現:ufldl上已經給出了整體的框架,我們需要將三個地方補全。由於我對matlab各種函式不熟悉,所以採用的是參考別人實現的程式碼,然後去理解的方式,等到ufldl教程後面幾課越來越熟悉,再自己來實現。

首先是補全sampleIMAGES.m中的程式碼

,該程式碼從IMAGES.mat中隨機提取8×8×10000張sample patches,用來做輸入樣本。

    tic  
    image_size=size(IMAGES);  
    i=randi(image_size(1)-patchsize+1,1,numpatches);   %產生1*10000個隨機數 範圍在[1,image_size(1)-patchsize+1]之間  
    j=randi(image_size(2)-patchsize+1,1,numpatches);  
    k=randi(image_size(3),1,numpatches);              % 隨機的選取圖片 10000次  
    for num=1:numpatches  
            patches(:,num)=reshape(IMAGES(i(num):i(num)+patchsize-1,j(num):j(num)+patchsize-1,k(num)),1,patchsize*patchsize);  
    end  
    toc  
說明:

tic和toc用來計時,返回tic-toc之間程式碼執行花費的時間;

IMAGES是512×512×10的陣列,所以size(IMAGES)返回512 512 10的向量;

i=randi(512-8+1,1,10000),會返回一個1×10000的隨機陣列,陣列中的元素屬於(0,505],也就是[1,505];(ps:上面介紹randi函式說產生的是開區間,但是我試了發現並不是開區間,是可以取到505的,不過這裡並沒有什麼影響,就不去糾結這一點了)

所以i j k都是1×10000的陣列,元素大小位於1-505;

sample=IMAGES(i(num):i(num)+patchsize-1,j(num):j(num)+patchsize-1,k(num))
上面這句話採用全下標的方式訪問3維陣列IMAGES的元素,行從i(num)到i(num)+7,列從j(num)到j(num)+7,頁選擇k(num);

reshape(sample,1,64)將sample變成了1×64的行向量,然後賦值給了patches;

sample到圖片後又將圖片的資料全部歸一化到了[0.1,0.9]:patches = normalizeData(patches)

這裡的歸一化函式,之後再分析,之所以要歸一化到[0.1,0.9],是因為啟用函式sigmoid函式的輸出範圍是[0,1],所以需要將輸入歸一化到函式的輸出範圍內,這樣才能訓練。

其次是實現sparseAutoencoder.m,稀疏自編碼

%1.forward propagation
data_size=size(data);
              %獲得data的維數資訊,64×10000
active_value2=repmat(b1,1,data_size(2));     
               %擴充套件b1,得到結果為25×10000,之前b1為25×1,對應的是一個patch,現在有10000個patch,相應的變成10000columns
active_value3=repmat(b2,1,data_size(2));    
               %同上,對應b2
active_value2=sigmoid(W1*data+active_value2);     
               %計算中間隱藏層的啟用值,z=w1×data+b1 對應25×10000
active_value3=sigmoid(W2*active_value2+active_value3);     
               %計算輸出層的啟用值,z=w2×a2+b2 對應64×10000
%2.computing error term and cost
ave_square=sum(sum((active_value3-data).^2)./2)/data_size(2);     
               %計算均方誤差
weight_decay=lambda/2*(sum(sum(W1.^2))+sum(sum(W2.^2)));    
               %計算權重衰減項

p_real=sum(active_value2,2)./data_size(2);     
               %計算平均活躍度,sum(x,2)將每行相加,結果為25×1的列向量
p_para=repmat(sparsityParam,hiddenSize,1);    
               %將引數p,repmat為25×1的列向量
sparsity=beta.*sum(p_para.*log(p_para./p_real)+(1-p_para).*log((1-p_para)./(1-p_real)));     %求得稀疏性限制項
cost=ave_square+weight_decay+sparsity;     
               %3項求和得到總的代價函式,但是為什麼要求總的代價函式呢?
               %貌似並不需要啊,只需要求偏導就可以了啊,確實這4句話並非必須
               %其實是因為後面的computeNumercialGradient函式,需要總的代價cost
               %這樣就可以通過導數的定義來計算gradient了
delta3=(active_value3-data).*(active_value3).*(1-active_value3);     
               %計算輸出層的殘差,結果形式是64×10000
average_sparsity=repmat(sum(active_value2,2)./data_size(2),1,data_size(2));     
               %計算平均活躍度,並且repmat成25×10000的矩陣形式
default_sparsity=repmat(sparsityParam,hiddenSize,data_size(2));     
               %把預設引數p,repmat成計算需要的25×10000矩陣形式
sparsity_penalty=beta.*(-(default_sparsity./average_sparsity)+((1-default_sparsity)./(1-average_sparsity)));  
               %計算 計算delta時需要的稀疏懲罰項
delta2=(W2'*delta3+sparsity_penalty).*((active_value2).*(1-active_value2));     
               %計算中間隱藏層的殘差,這裡加入了稀疏懲罰項
%3.backword propagation 後向傳播,更新w和b的值
W2grad=delta3*active_value2'./data_size(2)+lambda.*W2;       
               %64×10000  ×   10000×25 然後求平均值得到64×25的W2grad
W1grad=delta2*data'./data_size(2)+lambda.*W1;        
               %25×10000  ×  10000×64 然後求平均值得到25×64的W1grad
b2grad=sum(delta3,2)./data_size(2);      
               %得到64×1
b1grad=sum(delta2,2)./data_size(2);     
               %得到25×1
               %可是問題是這裡的程式碼並沒有對w b進行更新迭代啊,
               %只是求了一遍,更新迭代的程式碼在哪裡? 
               %andrew ng 給出了後面要用的迭代求解的程式碼,會重複呼叫這個函式
               % minFunc函式就是通過LBFGS來快速迭代求解的 
最後數值計算導數,用作梯度檢驗,computeNumercialGradient.m
EPSILON=0.0001;
for i=1:size(theta)
               % for迴圈,從1到3289(25×64+64×25+25+64)
    theta_plus=theta;
    theta_minu=theta;
               % 將theta賦值給兩個計算中用到的變數
    theta_plus(i)=theta_plus(i)+EPSILON;
    theta_minu(i)=theta_minu(i)-EPSILON;
                % 將原有w1 w2 b1 b2 中的某個值做一個很小的更改
                % 通過更改後的cost的變化,根據導數的定義計算
    numgrad(i)=(J(theta_plus)-J(theta_minu))/(2*EPSILON);
                % j是一個函式控制代碼變數,可以用來呼叫函式sparseAutoencoderCost
                % numgrad is 3289×1 vector
                % 為什麼numgrad是3289×1的vector,J()的輸出是[cost,grad],這裡還沒有深究??
end
基於上面的三段程式,加上andrew ng提供的程式,就可以完成稀疏自編碼器的;

注意梯度檢驗這一段程式,用來檢驗前面寫的程式是否正確,在確認正確後,train時,將該段程式註釋掉

這樣才能比較快的完成train,否則梯度檢驗這一段程式很慢的;

最後給出訓練後的結果:


向量化程式設計:

由於前面程式碼的實現已經是向量化了,所以不需要大的更改,只需要改變讀取輸入資料的方式即可。

將STEP1 Implement sampleIMAGES 改成如下即可

images=loadMNISTImages('train-images-idx3-ubyte');   % image is 784*60000 matrix, 784=28*28
display_network(images(:,1:100));                    % Show the first 100 images
patches = images(:,1:10000);
最後得到的訓練結果如圖:


matlab中涉及到的函式如下,並附上使用簡介:

1 cumtrapz(a);計算陣列a的數值積分,比如a=[1 2 3 4 ],cumtrapz(a)=[0 1.5 4 7.5 ],因為a對應的圖形的面積在這4個點處分別是0  1.5  4  7.5,預設a的每個元素之間的間距是1。

2 ndims(a):返回陣列a的維數=2。a=[1 2 3 4 ]或者a=1,a的維數都是2,有行和列。

3 size(a):返回陣列a的所有維度的值,所以返回的是一個向量值。比如a=a=[1 2 3 4 ],a有兩個維度,第一維度是行維度=1,第二維度是列維度=4。

4 隨機函式

rand 生成均勻分佈的偽隨機數。分佈在(0~1)之間

 主要語法:rand(m,n)生成m行n列的均勻分佈的偽隨機數
          rand(m,n,'double')生成指定精度的均勻分佈的偽隨機數,引數還可以是'single'
          rand(RandStream,m,n)利用指定的RandStream(我理解為隨機種子)生成偽隨機數
randn 生成標準正態分佈的偽隨機數(均值為0,方差為1)
   主要語法:和上面一樣
randi 生成均勻分佈的偽隨機整數
  主要語法:randi(iMax)在開區間(0,iMax)生成均勻分佈的偽隨機整數
          randi(iMax,m,n)在開區間(0,iMax)生成mXn型隨機矩陣
           r =randi([iMin,iMax],m,n)在開區間(iMin,iMax)生成mXn型隨機矩陣

5 reshape(a,2,6),a=[1 2 3;4 5 6;7 8 9;10 11 12],reshape(a,2,6)=[1 7 2 8 3 9;4 10 5 11 6 12],具體的原理百度;按列拼接,然後抽取元素,組成2組行向量。

6 sum函式,sum(x,2)表示矩陣x的橫向相加,求每行的和,結果是列向量;而預設的sum(x)就是豎向相加,求每列的和,結果是行向量
disp()函式,用於顯示陣列。a=‘hello’,disp(a)=hello;a=[1 2],b=[3 4],disp([a,b])=1 2 3 4


相關推薦

ufldl 深度學習入門 一發基於BP網路實現稀疏編碼

目的:打算使用深度學習的方式實現人臉關鍵點的檢測,第一步是要學習深度學習。 步驟:第一步在ufldl上面學習深度學習的演算法基礎知識,然後找部落格上基於python呼叫theano庫實現人臉關鍵點檢測的演算法,看懂後基於C++實現,然後用java實現app,呼叫C++實現的

[TensorFlow深度學習入門]實戰十二·使用DNN網路實現自動編碼

[TensorFlow深度學習入門]實戰十二·使用DNN網路實現自動編碼器 測試程式碼 import os os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE" import tensorflow as tf from tensorflow

深度學習入門教程UFLDL學習實驗筆記一稀疏編碼

UFLDL即(unsupervised feature learning & deep learning)。這是斯坦福網站上的一篇經典教程。顧名思義,你將在這篇這篇文章中學習到無監督特徵學習和深度學習的主要觀點。 UFLDL全文出處在這:http://ufldl.stanford.edu/wiki/

深度學習入門筆記系列 ( 二 )——基於 tensorflow 的一些深度學習基礎知識

本系列將分為 8 篇 。今天是第二篇 。主要講講 TensorFlow 框架的特點和此係列筆記中涉及到的入門概念 。 1.Tensor 、Flow 、Session 、Graphs TensorFlow 從單詞上可以分成 Tensor 和 Flow 兩個單詞 。Ten

深度學習入門|五章 誤差反向傳播法

1.3 數學 輸出 向上 spa 傳遞 函數 -- 保存 誤差反向傳播法 前言 此為本人學習《深度學習入門》的學習筆記,詳情請閱讀原書 數值微分雖然簡單,也容易實現,但是缺點是計算上比較費時間,本章介紹一個高效計算權重參數的梯度的方法--誤差反向傳播法 一

深度學習入門|七章 卷積神經網絡(三)

soft 有序字典 layer .py 復雜 高效 fin predict cal 前言 本文為學習《深度學習入門》一書的學習筆記,詳情請閱讀原著 五、CNN的實現 搭建進行手寫數字識別的 CNN。這裏要實現如圖 7-23 所示的 CNN。 圖 7-23 簡單

1課__神經網路深度學習__2周__神經網路基礎

第1課__神經網路和深度學習__第2周__神經網路基礎 ======================= 目錄 2.1 二分分類 2.2 logistic迴歸 2.3 logistic迴歸代價函式 2.4 梯度下降法 2.5 導數 2.6 更多導數的例子 2.7 計算圖

深度學習筆記稀疏編碼(1)——神經元與神經網路

  筆者在很久以前就已經學習過UFLDL深度學習教程中的稀疏自編碼器,近期需要用到的時候發現有些遺忘,溫習了一遍之後決定在這裡做一下筆記,本文不是對神經元與神經網路的介紹,而是筆者學習之後做的歸納和整理,打算分為幾篇記錄。詳細教程請見UFLDL教程,看完教程之後

深度學習入門 ---稀疏編碼

在學習稀疏自編碼器之前,需要讀者有BP神經網路的基礎 1. 為什麼要用稀疏自編碼器   對於沒有帶類別標籤的資料,由於為其增加類別標記是一個非常麻煩的過程,因此我們希望機器能夠自己學習到樣本中的一些重要特徵。通過對隱藏層施加一些限制,能夠使得它在惡劣

吳恩達.深度學習系列-C1神經網路深度學習-w4-( 作業建立神經網路

前言 注意:coursera要求不要在網際網路公佈自己的作業。如果你在學習這個課程,建議你進入課程系統自行完成作業。我覺得程式碼有參考和保留的意義。 本週的作業包含兩個部分。Building your Deep Neural Network, De

基於TensorFlow理解三大降維技術PCA、t-SNE 和編碼

余弦相似度 應對 新的 問題 技術 編碼 http 壓縮 方法 在我們開始之前,先看一個問題:如果你要為以下案例選擇一種降維技術,你會怎麽選? 1. 你的系統可以使用余弦相似度測量距離,但你需要將其可視化,以便不懂技術的董事會成員也能理解,這些人可能甚至從來沒聽說過余弦相

UFLDL向量化程式設計練習用MNIST資料集的稀疏編碼訓練實現

     折騰了兩天,總算實現了用MNIST資料集的稀疏自編碼器訓練。發現了以下問題:      1,matlab程式設計所寫程式碼不能太奢侈。定義變數時要儘量節省記憶體資源,向量能解決的不要用方陣,int8型別能解決的不要用雙精度數;      2,UFLDL提供的min

系統學習深度學習(二) --編碼,DA演算法,SDA,稀疏編碼

轉自:http://www.cnblogs.com/neopenx/p/4370350.html,作者寫的很好,輕鬆易懂。 起源:PCA、特徵提取.... 隨著一些奇怪的高維資料出現,比如影象、語音,傳統的統計學-機器學習方法遇到了前所未有的挑戰。 資料維度過高,資料單

UFLDL稀疏編碼

吳恩達的 CS294A 是一門很好的深度學習入門課程,打算接下來的學習以這個課程的內容為主。UFLDL Tutorial 是 CS294A 課程的 wiki 頁,包含了課程講義和作業。如果你對 監督學習、邏輯迴歸、梯度下降 等基礎概念並不熟悉,可以先學習 之前的

DeepLearning學習隨記(一)稀疏編碼

                講義從稀疏自編碼(Sparse Autoencoder)這一章節開始講起。前面三節是神經網路、BP神經網路以及梯度檢驗的方法。由於還有點神經網路的相關知識,這部分不是太難懂。就從自編碼器和稀疏性(Autoencoders and sparisity)記起吧。稀疏自編碼器構建:假

基於tensorflow的棧式編碼實現

這周完全沒有想法要看棧式編碼器的,誰知誤入桃花源,就暫且把棧式自編碼器看了吧。由於手上有很多數值型的資料,僅僅是資料,沒有標籤,所以,迫切需要通過聚類抽出特徵。無意間看到別人家公司的推薦系統裡面用到sdae,於是,找了個ae程式,建了個sdae,跑一下自己的資料。希望sda

深度學習入門基於Python的理論與實現》高清中文版PDF+源代碼

mark 原理 col 外部 tps follow src term RoCE 下載:https://pan.baidu.com/s/1nk1IHMUYbcuk1_8tj6ymog 《深度學習入門:基於Python的理論與實現》高清中文版PDF+源代碼 高清中文版PDF,3

分享《深度學習入門基於Python的理論與實現 》中文版PDF和原始碼

下載:(https://pan.baidu.com/s/1agBctMG7HF45VwhYpQHDSQ) 《深度學習入門:基於Python的理論與實現》高清中文版PDF+原始碼 高清中文版PDF,314頁,帶目錄標籤,可複製貼上,高清晰。配套原始碼。 深度學習真正意義上的入門書,深入淺出地剖析了深度學習

深度學習入門基於Python的理論與實現》高清中文版PDF+原始碼

下載:https://pan.baidu.com/s/1nk1IHMUYbcuk1_8tj6ymog 《深度學習入門:基於Python的理論與實現》高清中文版PDF+原始碼 高清中文版PDF,314頁,帶目錄標籤,可複製貼上,高清晰。配套原始碼。 深度學習真正意義上的入門書,深入淺出地剖析了深度學習的原

深度學習入門基於Python的理論與實現》高清中文版PDF+原始碼 下載

本書是深度學習真正意義上的入門書,深入淺出地剖析了深度學習的原理和相關技術。書中使用Python3,儘量不依賴外部庫或工具,從基本的數學知識出發,帶領讀者從零建立一個經典的深度學習網路,使讀者在此過程中逐步理解深度學習。書中不僅介紹了深度學習和神經網路的概念、特徵等基礎知識,對誤差反向傳播法、