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

 

原文地址:https://www.cnblogs.com/YiXiaoZhou/p/6297888.html