热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

torch7框架深度学习(1)

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

前面已经安装好了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.  
  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 

用于数据集的下载,数据集网址,但是这个网址好像被墙了,访问不了。所以我自己令下载的数据集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 结果
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) 参见 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.  
  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系统上跑还是蛮快的
    ===========================================================================================
    =

附件


推荐阅读
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • VueCLI多页分目录打包的步骤记录
    本文介绍了使用VueCLI进行多页分目录打包的步骤,包括页面目录结构、安装依赖、获取Vue CLI需要的多页对象等内容。同时还提供了自定义不同模块页面标题的方法。 ... [详细]
  • 本文介绍了一个视频转换软件MyVideoConverter,该软件支持将mpg转换成swf格式,支持多种格式的转换,转换速度快,还能转换成3GP格式,同时具有音频分离提取功能。欢迎使用MyVideoConverter进行视频转换和音频提取。 ... [详细]
  • 如何使用Python从工程图图像中提取底部的方法?
    本文介绍了使用Python从工程图图像中提取底部的方法。首先将输入图片转换为灰度图像,并进行高斯模糊和阈值处理。然后通过填充潜在的轮廓以及使用轮廓逼近和矩形核进行过滤,去除非矩形轮廓。最后通过查找轮廓并使用轮廓近似、宽高比和轮廓区域进行过滤,隔离所需的底部轮廓,并使用Numpy切片提取底部模板部分。 ... [详细]
  • Jboss的EJB部署描述符standardjaws.xml配置步骤详解
    本文详细介绍了Jboss的EJB部署描述符standardjaws.xml的配置步骤,包括映射CMP实体EJB、数据源连接池的获取以及数据库配置等内容。 ... [详细]
author-avatar
求道金林
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有