torch 深度學習 (2)


torch 深度學習 (2)

前面我們完成了數據的下載和預處理,接下來就該搭建網絡模型了,CNN網絡的東西可以參考博主 zouxy09的系列文章Deep Learning (深度學習) 學習筆記整理系列之 (七)

  1. 加載包

  1. require 'torch' 
  2. require 'image' 
  3. require 'nn' 
  1. 函數運行參數的設置

  1. if not opt then 
  2. print "==> processing options" 
  3. cmd = torch.CmdLine() 
  4. cmd:text() 
  5. cmd:text('options:'
  6. -- 選擇構建何種結構:線性|MLP|ConvNet。默認:convnet 
  7. cmd:option('-model','convnet','type of model to construct: linear | mlp | convnet'
  8. -- 是否需要可視化 
  9. cmd:option('-visualize',true,'visualize input data and weights during training'
  10. -- 參數 
  11. opt = cmd:parse(arg or {}) 
  12. end 
  1. 設置網絡模型用到的一些參數

  1. -- 輸出類別數,也就是輸出節點個數 
  2. noutputs =10 
  3. -- 輸入節點的個數 
  4. nfeats = 3 -- YUV三個通道,可以認為是3個features map 
  5. width =32 
  6. height =32 
  7. -- Linear 和 mlp model下的輸入節點個數,就是將輸入圖像拉成列向量 
  8. ninputs = nfeats*width*height 
  9.  
  10. -- 為mlp定義隱層節點的個數 
  11. nhiddens = ninputs/2  
  12.  
  13. -- 為convnet定義隱層feature maps的個數以及濾波器的尺寸 
  14. nstates = {16,256,128} --第一個隱層有16個feature map,第二個隱層有256個特征圖,第三個隱層有128個節點 
  15. fanin = {1,4} -- 定義了卷積層的輸入和輸出對應關系,以fanin[2]舉例,表示該卷積層有16個map輸入,256個map輸出,每個輸出map是有fanin[2]個輸入map對應filters卷積得到的結果 
  16. filtsize =5 --濾波器的大小,方形濾波器 
  17. poolsize = 2 -- 池化池尺寸 
  18. normkernel = image.gaussian1D(7) --長度為7的一維高斯模板,用來local contrast normalization 
  1. 構建模型

  1. if opt.model == linear then  
  2. -- 線性模型 
  3. model = nn.Sequntial() 
  4. model:add(nn.Reshape(ninputs)) -- 輸入層 
  5. model:add(nn.Linear(ninputs,noutputs)) -- 線性模型 y=Wx+b 
  6. elseif opt.model == mlp then  
  7. -- 多層感知器 
  8. model = nn.Sequential() 
  9. model:add(nn.Reshape(ninputs)) --輸入層 
  10. model:add(nn.Linear(ninputs,nhiddens)) --線性層 
  11. model:add(nn.Tanh()) -- 非線性層 
  12. model:add(nn.Linear(nhiddens,noutputs)) -- 線性層 
  13. -- MLP 目標: `!$y=W_2 f(W_1X+b) + b $` 這里的激活函數采用的是Tanh(),MLP后面還可以接一層輸出層Tanh() 
  14. elseif opt.model == convnet then 
  15. -- 卷積神經網絡 
  16. model = nn.Sequential() 
  17. -- 第一階段 
  18. model:add(nn.SpatialConvolutionMap(nn.tables.random(nfeats,nstates[1],fanin[1]),filtsize,filtsize)) 
  19. -- 這一步直接輸入的是圖像進行卷積,所以沒有了 nn.Reshape(ninputs)輸入層。 參數:nn.tables.random(nfeats,nstates[1],fanin[1])指定了卷積層中輸入maps和輸出maps之間的對應關系,這里表示bstates[1]個輸出maps的每一map都是由fanin[1]個輸入maps得到的。filtsize則是卷積算子的大小 
  20. -- 所以該層的連接個數為(filtsize*filtsize*fanin[1]+1)*nstates[1],1是偏置。這里的fanin[1]連接是隨機的,也可以采用全連接 nn.tables.full(nfeats,nstates[1]), 當輸入maps和輸出maps個數相同時,還可以采用一對一連接 nn.tables.oneToOne(nfeats). 
  21. -- 參見解釋文檔 [Convolutional layers](https://github.com/torch/nn/blob/master/doc/concolution.md#nn.convlayers.dok) 
  22.  
  23. model:add(nn.Tanh()) --非線性變換層 
  24. model:SpatialLPPooling(nstates[1],2,poolsize,poolsize,poolsize,poolsize) 
  25. -- 參數(feature maps個數,Lp范數,池化尺寸大小(w,h), 滑動窗步長(dw,dh)) 
  26. model:SpatialSubtractiveNormalization(nstates[1],normalkernel) 
  27. -- local contrast normalization 
  28. -- 具體操作是先在每個map的local鄰域進行減法歸一化,然后在不同的feature map上進行除法歸一化。類似與圖像點的均值化和方差歸一化。參考[1^x][Nonlinear Image Representation Using Divisive Normalization], [Gaussian Scale Mixtures](stats.stackexchange.com/174502/what-are gaussian-scale-mixtures-and-how-to-generate-samples-of-gaussian-scale),還有解釋文檔 [Convolutional layers](https://github.com/torch/nn/blob/master/doc/concolution.md#nn.convlayers.dok) 
  29.  
  30. --[[ 
  31. 這里需要說的一點是傳統的CNN一般是先卷積再池化再非線性變換,但這兩年CNN一般都是先非線性變換再池化了 
  32. --]] 
  33. -- 第二階段 
  34. model:add(nn.SpatialConvolutionMap(nn.tables.random(nstates[1],nstates[2],fanin[2]),filtsize,filtsize)) 
  35. model:add(nn.Tanh()) 
  36. model:add(nn.SpatialLPPooling(nstates[2],2,poolsize,poolsize)) 
  37. model:add(nn.SpatialSubtractiveNormalization(nstates[2],kernel)) 
  38.  
  39. --第三階段 
  40. model:add(nn.Reshape(nstates[2]*filtsize*filtsize)) --矢量化,全連接 
  41. model:add(nn.Linear(nstates[2]*filtsize*filtsize,nstates[3])) 
  42. model:add(nn.Tanh()) 
  43. model:add(nn.Linear(nstates[3],noutputs)) 
  44. else 
  45. error('unknown -model'
  46. end 
  1. 顯示網絡結構以及參數

  1. print('==> here is the model'
  2. print(model) 

結果如下圖

 

enter description here

model.png

 

可以發現,可訓練參數分別在1,5部分,所以可以觀察權重矩陣的大小

  1. print('==> 權重矩陣的大小 '
  2. print(model:get(1).weight:size()) 
  3. print('==> 偏置的大小'
  4. print(model:get(1).bias:numel()) 

 

enter description here

weights numel.png

 

  1. 參數的可視化

  1. if opt.visualize then 
  2. image.display(image=model:get(1).weight, padding=2,zoom=4,legend='filters@ layer 1'
  3. image.diaplay(image=model:get(5).weight,padding=2,zoom=4,legend='filters @ layer 2'
  4. end 

 

enter description here

weights visualization.png

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM