博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
torch7框架 深度学习(1)
阅读量:6933 次
发布时间:2019-06-27

本文共 6994 字,大约阅读时间需要 23 分钟。

前面已经安装好了torch,下面就来看看如何在torch框架上搭建深度学习模型,我一直觉得源码结合原理是机器学习最好的学习途径。所以我们从分析一个简单的案例开始吧。

参考

这个例子呢,主要是以有监督的方式构建一个深度学习模型实现对数据集SVHN的分类。

SVHN是 The Street View House Numbers Dataset, 数据集介绍见

代码主要分为五个部分

  1. 数据的预处理

  2. 网络模型的构建

  3. 损失函数的定义

  4. 训练网络

  5. 测试数据

数据的预处理

  1. require 'torch' -- torch 

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

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

加载头文件

  1. if not opt then 

  2. print '==> processing options' 

  3. cmd = torch.CmdLine() 

  4. cmd:text() 

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

  6. cmd:text() 

  7. cmd:text('Options:') 

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

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

  10. cmd:text() 

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

  12. end 

文件的命令行参数。主要有两个参数(文件大小和是否可视化选项),torch.CmdLine()函数参见

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

  2.  

  3. train_file = 'train_32x32.t7' 

  4. test_file = 'test_32x32.t7' 

  5. extra_file = 'extra_32x32.t7' 

  6.  

  7. if not paths.filep(train_file) then 

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

  9. end 

  10. if not paths.filep(test_file) then 

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

  12. end 

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

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

  15. end 

用于数据集的下载,数据集,但是这个网址好像被墙了,访问不了。所以我自己令下载的数据集,其中只下载了 train_32x32.mat和 test_32x32.mat文件,因为数据太大机子跑得太慢。

顺便说一句上边代码中 os.execute(string)是执行string指令,wget是下载指令,参见

下载下来的数据是 mat格式的,要转换成 torch使用的t7格式,文档中说可以使用mattorch工具实现,但是我在虚拟机上没有装matlab,所以安装mattorch总是失败。 另外使用matio同样可以实现matlab和torch间数据转换。

下面是安装matio的指令

  1. sudo apt-get install libmatio2 

  2. 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' 

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

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

  4. trainData = { 

  5. data = tempData, 

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

  7. size = function() return trsize end 


数据存放在'/SVHN_Data'文件夹内

------------------------------------------------------下面一段是用来看数据转换的对不对 --------------------------------
torch 结果
enter description here
matlab结果
enter description here
颜色不大一样,一个是在笔记本上跑的,一个是在台机上跑的,不知道是不是机器的原因还是什么原因

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

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

  2. print '==> using extra training data' 

  3. trsize = 73257 + 531131 

  4. tesize = 26032 

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

  6. print '==> using regular, full training data' 

  7. trsize = 73257 

  8. tesize = 26032 

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

  10. print '==> using reduced training data, for fast experiments' 

  11. trsize = 10000 

  12. tesize = 2000 

  13. end 

上面这一段是设置训练集和测试集的大小。

================================================================= START ==================================================

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

  2. trainData = { 

  3. data = loaded.X:transpose(3,4), 

  4. labels = loaded.y[1], 

  5. size = function() return trsize end 


上面这段代码很容易理解,就是分别将数据和标签起别名data和labels方便后续使用,size返回的是训练样本的个数。唯一需要注意的是transpose()函数的使用,这是因为在matlab中数据的表达一般是先列后行,而在torch中数据的表达一般是先行后列,所以这里对后两维进行了转置

这段代码被上面自己下载数据并处理取代
====================================================== END ======================================================

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

  2. loaded = torch.load(extra_file,'ascii') 

  3. trdata = torch.Tensor(trsize,3,32,32) 

  4. trdata[{ {1,(#trainData.data)[1]} }] = trainData.data 

  5. trdata[{ {(#trainData.data)[1]+1,-1} }] = loaded.X:transpose(3,4) 

  6. trlabels = torch.Tensor(trsize) 

  7. trlabels[{ {1,(#trainData.labels)[1]} }] = trainData.labels 

  8. trlabels[{ {(#trainData.labels)[1]+1,-1} }] = loaded.y[1] 

  9. trainData = { 

  10. data = trdata, 

  11. labels = trlabels, 

  12. size = function() return trsize end 


  13. end 

当数据选择extra时,上面对训练集进行拼接。

同样加载测试集

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

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

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

  4. tempData = nil 

下面进行数据的预处理

数据的预处理包含三个trick
+ 图像从RGB空间映射到YUV空间
+ Y通道使用 contrastive normalization operator进行局部规范化
+ 对所有的数据在每个通道进行规范化到0,1之间

  1. -- RGB==>YUV 

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

  3. trainData.data[i] = image.rgb2yuv(trainData.data[i]) -- 等价于 trainData.data[{
    {i},{},{},{}}] 

  4. end 

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

  6. testData.data[i] = image.rgb2yuv(testData.data[i]) 

  7. end 

  8.  

  9. -- Name Channels for convenience 

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

  11.  

  12.  

  13. -- 单通道进行规范化 

  14. Mean={} 

  15. Std={} 

  16. for i=1, channel in ipairs(channels) do --此处和for i=1,3 do等价 

  17. Mean[i]= trainData.data[{
    {},{i},{},{}}]:mean() 

  18. Std[i] = trainData.data[{
    {},{i},{},{}}]:std() 

  19. trainData.data[{
    {},{i},{},{}}]=trainData.data[{
    {},{i},{},{}}]:csub(Mean[i]) 

  20. trainData.data[{
    {},{i},{},{}}]=trainData.data[{
    {},{i},{},{}}]:div(Std[i]) 

  21. end 

  22.  

  23. for i=1,3 do 

  24. testData.data[{
    {},{i},{},{}}]:add(-Mean[i]) -- add 和csub 

  25. -- 这个用法见Tensor的手册,改变后替代原来数据,所以和上面是一样的 

  26. testData.data[{
    {},{i},{},{}}]:div(Std[i]) 

  27. end 

  28. -- 至于为什么测试数据使用训练集的统计量归一化,参见机器学习相关理论 

Y通道局部的规范化需要使用nn包里的算子

  1. -- Define the normalization neighborhood: 

  2. neighborhood = image.gaussian1D(7) 

  3.  

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

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

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

  7.  

  8. -- Normalize all Y channels locally: 

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

  10. trainData.data[{ i,{1},{},{} }] = normalization:forward(trainData.data[{ i,{1},{},{} }]) --前向计算 

  11. end 

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

  13. testData.data[{ i,{1},{},{} }] = normalization:forward(testData.data[{ i,{1},{},{} }]) 

  14. end 

关于函数 nn.SpatialContrastiveNormalization(1, neighborhood) 参见

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

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

  2. trainMean = trainData.data[{ {},i }]:mean() 

  3. trainStd = trainData.data[{ {},i }]:std() 

  4.  

  5. testMean = testData.data[{ {},i }]:mean() 

  6. testStd = testData.data[{ {},i }]:std() 

  7.  

  8. print('training data, '..channel..'-channel, mean: ' .. trainMean) 

  9. print('training data, '..channel..'-channel, standard deviation: ' .. trainStd) 

  10.  

  11. print('test data, '..channel..'-channel, mean: ' .. testMean) 

  12. print('test data, '..channel..'-channel, standard deviation: ' .. testStd) 

  13. end 

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

最后是数据的可视化,显示了前256个数据Y,U,V通道上的效果

  1. if opt.visualize then 

  2. first256Samples_y = trainData.data[{ {1,256},1 }] 

  3. first256Samples_u = trainData.data[{ {1,256},2 }] 

  4. first256Samples_v = trainData.data[{ {1,256},3 }] 

  5. image.display{image=first256Samples_y, nrow=16, legend='Some training examples: Y channel'} 

  6. image.display{image=first256Samples_u, nrow=16, legend='Some training examples: U channel'} 

  7. image.display{image=first256Samples_v, nrow=16, legend='Some training examples: V channel'} 

  8. end 

具体的代码见附件

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

  1. qlua 1_data.lua 

 

enter description here
result.png
结果见下图(Y通道)
enter description here
github上给的结果(Y通道)
enter description here

 

================================================== 结论 ===================================

  1. torch 挺好用的,和我胃口-

  2. 在笔记本上安装虚拟机跑深度学习的代码。。。真是蛮拼的。。。这速度感人啊,直接在ubuntu系统上跑还是蛮快的

    ===========================================================================================
    =

转载于:https://www.cnblogs.com/YiXiaoZhou/p/6294150.html

你可能感兴趣的文章
你真的了解RPC吗?
查看>>
Composer简明教程
查看>>
jsonP格式接口实现
查看>>
INDIGO STUDIO神器!快速创建WEB、移动应用的交互原型工具【转】
查看>>
我的2017云栖之行
查看>>
HSQLDB安装与使用方法
查看>>
重拾C++之初始化
查看>>
maven nexus 下发布第三方构件;
查看>>
Java学习之深拷贝浅拷贝及对象拷贝的两种方式
查看>>
如何根据动态SQL代码自动生成DTO
查看>>
html input="file" 浏览时只显示指定文件类型 xls、xlsx、csv
查看>>
Android Export aborted because fatal error were fo
查看>>
在window平台下模拟Liunx使用GCC环境进行编译C的SO库。
查看>>
原来一直纠结MQ的用法,今天看到了一个最经典的例子。
查看>>
Resource is out of sync with the file system的解决办法
查看>>
交叉编译openssl不修改Makefile的方法
查看>>
linux 常用流量查看命令
查看>>
VMware ESXi Windows虚拟机磁盘扩展小结
查看>>
Linux常用命令
查看>>
方便的将数字转成字符串类型并在前面补0
查看>>