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

参考Supervised Learning

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

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

代码主要分为五个部分

  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()函数参见torch.CmdLine()

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


  2. train_file = 'train_32x32.t7' 

  3. test_file = 'test_32x32.t7' 

  4. extra_file = 'extra_32x32.t7' 


  5. if not paths.filep(train_file) then 

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

  7. end 

  8. if not paths.filep(test_file) then 

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

  10. end 

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

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

  13. 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 

  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 结果

matlab结果

颜色不大一样,一个是在笔记本上跑的,一个是在台机上跑的,不知道是不是机器的原因还是什么原因

---------------------------------------------------------------------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. -- Name Channels for convenience 

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



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

  11. Mean={} 

  12. Std={} 

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

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

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

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

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

  18. end 


  19. for i=1,3 do 

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

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

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

  23. end 

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

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

  1. -- Define the normalization neighborhood: 

  2. neighborhood = image.gaussian1D(7) 


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

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

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


  6. -- Normalize all Y channels locally: 

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

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

  9. end 

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

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

  12. 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 

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

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


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

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


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

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


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

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

  10. 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 

result.png

结果见下图(Y通道)

github上给的结果(Y通道)

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

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

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

附件

torch7框架 深度学习(1)的更多相关文章

  1. 通过 DLPack 构建跨框架深度学习编译器

    通过 DLPack 构建跨框架深度学习编译器 深度学习框架,如Tensorflow, PyTorch, and ApacheMxNet,快速原型化和部署深度学习模型提供了强大的工具箱.不幸的是,易用性 ...

  2. 学习笔记︱Nvidia DIGITS网页版深度学习框架——深度学习版SPSS

    DIGITS: Deep Learning GPU Training System1,是由英伟达(NVIDIA)公司开发的第一个交互式深度学习GPU训练系统.目的在于整合现有的Deep Learnin ...

  3. ASP.NET Core框架深度学习(一) Hello World

    对于学习Core的框架,对我帮助最大的一篇文章是Artech的<200行代码,7个对象——让你了解ASP.NET Core框架的本质>,最近我又重新阅读了一遍该文.本系列文章就是结合我的阅 ...

  4. ASP.NET Core框架深度学习(四)宿主对象

    11.WebHost  第六个对象 到目前为止我们已经知道了由一个服务器和多个中间件构成的管道是如何完整针对请求的监听.接收.处理和最终响应的,接下来来讨论这样的管道是如何被构建出来的.管道是在作为应 ...

  5. ASP.NET Core框架深度学习(二) 管道对象

    4.HttpContext 第一个对象 我们的ASP.NET Core Mini由7个核心对象构建而成.第一个就是大家非常熟悉的HttpContext对象,它可以说是ASP.NET Core应用开发中 ...

  6. ASP.NET Core框架深度学习(三) Server对象

    8.Server   第五个对象 服务器在管道中的职责非常明确,当我们启动应用宿主的WebHost的时候,服务它被自动启动.启动后的服务器会绑定到指定的端口进行请求监听,一旦有请求抵达,服务器会根据该 ...

  7. 深度学习调用TensorFlow、PyTorch等框架

    深度学习调用TensorFlow.PyTorch等框架 一.开发目标目标 提供统一接口的库,它可以从C++和Python中的多个框架中运行深度学习模型.欧米诺使研究人员能够在自己选择的框架内轻松建立模 ...

  8. [源码解析] 深度学习分布式训练框架 horovod (7) --- DistributedOptimizer

    [源码解析] 深度学习分布式训练框架 horovod (7) --- DistributedOptimizer 目录 [源码解析] 深度学习分布式训练框架 horovod (7) --- Distri ...

  9. GitHub 上 57 款最流行的开源深度学习项目

    转载:https://www.oschina.net/news/79500/57-most-popular-deep-learning-project-at-github GitHub 上 57 款最 ...

随机推荐

  1. Cookie , Session ,Session 劫持简单总结

    cookie 机制: Cookies 是 服务器 在 本地机器 上存储的 小段文本,并伴随着 每一个请求,发送到 同一台 服务器. 网络服务器 用 HTTP头 向客户端发送 Cookies.在客户端, ...

  2. php.ini优化,,,php-fpm

    无论是apache还是nginx,php.ini都是合适的.而php-fpm.conf适合nginx+fcgi的配置. 1)打开PHP的安全模式 PHP的安全模式是个非常重要的PHP内嵌的安全机制,能 ...

  3. Silly Java-Final 关键字

    Final 关键字 adj. 最终的:最后的:决定性的:不可改变的 1.修饰变量 final variable 意味 [最后的变量,不可改变的变量即常量] Java中该关键字即代表常量 修饰基本类型的 ...

  4. vue我的总结+转原理

    我的总结 vue:1 mvvm模型,model,view,viewmodel,自底层向上,逐渐增加的模式2 .vue文件 包含html css js 有最近设计原则,将自己需要的放到最近,2 组件化 ...

  5. 服务器抓包命令:tcpdump详解

    官网地址:http://www.tcpdump.org/tcpdump_man.html 简介: tcpdump,就是:dump the traffic on a network,根据使用者的定义对网 ...

  6. 基于Node.js的爬虫工具 – Node Crawler

    Node Crawler的目标是成为最好的node.js爬虫工具,目前已经停止维护. 我们来抓取光合新知博客tech栏目中的文章信息.访问http://dev.guanghe.tv/category/ ...

  7. Jquery中val、text、html的区别

    html就是你可以添加像<a></a>.<p></p>等标记text只能写文本如果写了上面的标记则会以文本形式输出val是属性,只有有该属性的对象才能调 ...

  8. javascript 判断数据类型的几种方法

    javascript 判断数据类型的几种方法一.typeof 直接返回数据类型字段,但是无法判断数组.null.对象 typeof 1 "number" typeof NaN &q ...

  9. linux挂载iso,u盘,分区,squashfs压缩文件

    常见分区加载方法: mount挂载iso文件: #mkdir /mnt/iso1 #mount –o loop linuxsetup.iso /mnt/iso1 在linux 不需要虚拟光驱,就可以直 ...

  10. 20145327 实验四 Andoid开发基础

    20145327 实验四 Andoid开发基础 安装Android Studio 安装过程出现未找到SDK的错误,只需在打开界面找到右下角的设置按钮,将路径设置为如下就可以运行.(默认安装路径) 设计 ...