前面已經安裝好了torch,下面就來看看如何在torch框架上搭建深度學習模型,我一直覺得源碼結合原理是機器學習最好的學習途徑。所以我們從分析一個簡單的案例開始吧。

參考Supervised Learning

這個例子呢,主要是以有監督的方式構建一個深度學習模型實現對數據集SVHN的分類。

SVHN是 The Street View House Numbers Dataset, 數據集介紹見 SVHN數據集

代碼主要分為五個部分

  1. 數據的預處理
  2. 網絡模型的構建
  3. 損失函數的定義
  4. 訓練網絡
  5. 測試數據

數據的預處理



  1. require 'torch' -- torch 

  1. require 'image' -- to visualize the dataset 

  1. require 'nn' -- provides a normalization operator 



加載頭文件



  1. if not opt then 

  1. print '==> processing options' 

  1. cmd = torch.CmdLine() 

  1. cmd:text() 

  1. cmd:text('SVHN Dataset Preprocessing') 

  1. cmd:text() 

  1. cmd:text('Options:') 

  1. cmd:option('-size', 'small', 'how many samples do we load: small | full | extra') 

  1. cmd:option('-visualize', true, 'visualize input data and weights during training') 

  1. cmd:text() 

  1. opt = cmd:parse(arg or {}) 

  1. end 



文件的命令行參數。主要有兩個參數(文件大小和是否可視化選項),torch.CmdLine()函數參見torch.CmdLine()



  1. www = 'http://data.neuflow.org/data/housenumbers/' 


  1. train_file = 'train_32x32.t7' 

  1. test_file = 'test_32x32.t7' 

  1. extra_file = 'extra_32x32.t7' 


  1. if not paths.filep(train_file) then 

  1. os.execute('wget ' .. www .. train_file) 

  1. end 

  1. if not paths.filep(test_file) then 

  1. os.execute('wget ' .. www .. test_file) 

  1. end 

  1. if opt.size == 'extra' and not paths.filep(extra_file) then 

  1. os.execute('wget ' .. www .. extra_file)  

  1. end 



用於數據集的下載,數據集網址,但是這個網址好像被牆了,訪問不了。所以我自己令下載的數據集SVHN,其中只下載了 train_32x32.mat和 test_32x32.mat文件,因為數據太大機子跑得太慢。

順便説一句上邊代碼中 os.execute(string)是執行string指令,wget是下載指令,參見linux 應用之wget 命令詳解

下載下來的數據是 mat格式的,要轉換成 torch使用的t7格式,文檔中説可以使用mattorch工具實現,但是我在虛擬機上沒有裝matlab,所以安裝mattorch總是失敗。 另外使用matio同樣可以實現matlab和torch間數據轉換。

下面是安裝matio的指令matio-ffi



  1. sudo apt-get install libmatio2 

  1. sudo luarocks install matio 



此時下載的數據是 columns x rows x channels x num ,但image.display()要求的數據組織形式是: num x channels x columns x rows,所以需要進行重組織,由於我也是個剛開始使用torch沒一週的人,所以就用較原始的辦法重組織了,誰有好辦法希望教教我!下面是數據轉換的代碼



  1. matio = require'matio' 

  1. loaded = matio.load('/SVHN_Data/train_32x32.mat') 

  1. tempData=loaded.X:permute(4,3,1,2) 

  1. trainData = { 

  1. data = tempData, 

  1. labels = loaded.y[{{},{1}}], -- loaded.y:size() --> 26032 x 1 

  1. size = function() return trsize end 



數據存放在'/SVHN_Data'文件夾內

------------------------------------------------------下面一段是用來看數據轉換的對不對 --------------------------------

torch 結果

深度學習torch包_數據


matlab結果

深度學習torch包_數據集_02


顏色不大一樣,一個是在筆記本上跑的,一個是在台機上跑的,不知道是不是機器的原因還是什麼原因

---------------------------------------------------------------------END---------------------------------------------------------


  1. if opt.size == 'extra' then 




  1. elseif opt.size == 'full' then 




  1. elseif opt.size == 'small' then 




  1. end 


上面這一段是設置訓練集和測試集的大小。
================================================================= START ==================================================


  1. loaded = torch.load(train_file,'ascii') 

  1. trainData = { 






上面這段代碼很容易理解,就是分別將數據和標籤起別名data和labels方便後續使用,size返回的是訓練樣本的個數。唯一需要注意的是transpose()函數的使用,這是因為在matlab中數據的表達一般是先列後行,而在torch中數據的表達一般是先行後列,所以這裏對後兩維進行了轉置
這段代碼被上面自己下載數據並處理取代
====================================================== END ======================================================


  1. if opt.size == 'extra' then 













  1. end 


當數據選擇extra時,上面對訓練集進行拼接。

同樣加載測試集


  1. loaded = matio.load('/SVHN_Data/test_32x32.mat') 

  1. tempData = loaded.X:permute(4,3,1,2) 

  1. testData = {data = tempData, labels =loaded.y, size = function() return tesize end} 

  1. tempData = nil 


下面進行數據的預處理
數據的預處理包含三個trick
+ 圖像從RGB空間映射到YUV空間
+ Y通道使用 contrastive normalization operator進行局部規範化
+ 對所有的數據在每個通道進行規範化到0,1之間


  1. -- RGB==>YUV 

  1. for i=1,trainData:size() do  


  1. end 

  1. for i=1,testData:size() do 


  1. end 


  1. -- Name Channels for convenience 

  1. channels = {'y','u','v'} 



  1. -- 單通道進行規範化 

  1. Mean={} 

  1. Std={} 

  1. for i=1, channel in ipairs(channels) do --此處和for i=1,3 do等價 





  1. end 


  1. for i=1,3 do 




  1. end 

  1. -- 至於為什麼測試數據使用訓練集的統計量歸一化,參見機器學習相關理論 


Y通道局部的規範化需要使用nn包裏的算子


  1. -- Define the normalization neighborhood: 

  1. neighborhood = image.gaussian1D(7) 


  1. -- Define our local normalization operator (It is an actual nn module,  

  1. -- which could be inserted into a trainable model): 

  1. normalization = nn.SpatialContrastiveNormalization(1, neighborhood):float() 


  1. -- Normalize all Y channels locally: 

  1. for i = 1,trainData:size() do 


  1. end 

  1. for i = 1,testData:size() do 


  1. end 


關於函數 nn.SpatialContrastiveNormalization(1, neighborhood) 參見 torch/nn/SpatialContrastiveNormalization.lua

===================== It's always good practice to verify that data is properly normalized ========================


  1. for i,channel in ipairs(channels) do 












  1. end 


================================================= END ======================================

最後是數據的可視化,顯示了前256個數據Y,U,V通道上的效果


  1. if opt.visualize then 







  1. end 


具體的代碼見附件

命令行執行: (1_data.lua)是文件名


  1. qlua 1_data.lua 


 


深度學習torch包_Data_03


result.png


結果見下圖(Y通道)

深度學習torch包_Data_04


github上給的結果(Y通道)

深度學習torch包_數據集_05


 

================================================== 結論 ===================================

  1. torch 挺好用的,和我胃口-
  2. 在筆記本上安裝虛擬機跑深度學習的代碼。。。真是蠻拼的。。。這速度感人啊,直接在ubuntu系統上跑還是蠻快的
    ===========================================================================================
    =