matlab svhn,torch7框架 深度学习(1)

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

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

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

代码主要分为五个部分

数据的预处理

网络模型的构建

损失函数的定义

训练网络

测试数据

数据的预处理

require ‘torch‘ -- torch

require ‘image‘ -- to visualize the dataset

require ‘nn‘ -- provides a normalization operator

加载头文件

if not opt then

print ‘==> processing options‘

cmd = torch.CmdLine()

cmd:text()

cmd:text(‘SVHN Dataset Preprocessing‘)

cmd:text()

cmd:text(‘Options:‘)

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

cmd:option(‘-visualize‘, true, ‘visualize input data and weights during training‘)

cmd:text()

opt = cmd:parse(arg or {})

end

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

www = ‘http://data.neuflow.org/data/housenumbers/‘

train_file = ‘train_32x32.t7‘

test_file = ‘test_32x32.t7‘

extra_file = ‘extra_32x32.t7‘

if not paths.filep(train_file) then

os.execute(‘wget ‘ .. www .. train_file)

end

if not paths.filep(test_file) then

os.execute(‘wget ‘ .. www .. test_file)

end

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

os.execute(‘wget ‘ .. www .. extra_file)

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

sudo apt-get install libmatio2

sudo luarocks install matio

此时下载的数据是 columns x rows x channels x num ,但image.display()要求的数据组织形式是: num x channels x columns x rows,所以需要进行重组织,由于我也是个刚开始使用torch没一周的人,所以就用较原始的办法重组织了,谁有好办法希望教教我!下面是数据转换的代码

matio = require‘matio‘

loaded = matio.load(‘/SVHN_Data/train_32x32.mat‘)

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

trainData = {

data = tempData,

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

size = function() return trsize end

}

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

------------------------------------------------------下面一段是用来看数据转换的对不对 --------------------------------

torch 结果

5611a32bb1e3d8dafb1c1bc5f8c2e3d1.png

matlab结果

6718292a0231737ad2552ef6ee49e486.png

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

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

if opt.size == ‘extra‘ then

print ‘==> using extra training data‘

trsize = 73257 + 531131

tesize = 26032

elseif opt.size == ‘full‘ then

print ‘==> using regular, full training data‘

trsize = 73257

tesize = 26032

elseif opt.size == ‘small‘ then

print ‘==> using reduced training data, for fast experiments‘

trsize = 10000

tesize = 2000

end

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

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

loaded = torch.load(train_file,‘ascii‘)

trainData = {

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

labels = loaded.y[1],

size = function() return trsize end

}

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

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

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

if opt.size == ‘extra‘ then

loaded = torch.load(extra_file,‘ascii‘)

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

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

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

trlabels = torch.Tensor(trsize)

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

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

trainData = {

data = trdata,

labels = trlabels,

size = function() return trsize end

}

end

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

同样加载测试集

loaded = matio.load(‘/SVHN_Data/test_32x32.mat‘)

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

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

tempData = nil

下面进行数据的预处理

数据的预处理包含三个trick

+ 图像从RGB空间映射到YUV空间

+ Y通道使用 contrastive normalization operator进行局部规范化

+ 对所有的数据在每个通道进行规范化到0,1之间

-- RGB==>YUV

for i=1,trainData:size() do

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

end

for i=1,testData:size() do

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

end

-- Name Channels for convenience

channels = {‘y‘,‘u‘,‘v‘}

-- 单通道进行规范化

Mean={}

Std={}

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

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

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

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

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

end

for i=1,3 do

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

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

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

end

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

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

-- Define the normalization neighborhood:

neighborhood = image.gaussian1D(7)

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

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

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

-- Normalize all Y channels locally:

for i = 1,trainData:size() do

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

end

for i = 1,testData:size() do

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

end

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

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

for i,channel in ipairs(channels) do

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

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

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

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

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

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

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

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

end

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

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

if opt.visualize then

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

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

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

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

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

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

end

具体的代码见附件

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

qlua 1_data.lua

d1fdf105577e22bde708c047ab81eff5.png

result.png

结果见下图(Y通道)

d68ca83af23a058cf02589538bdfebac.png

github上给的结果(Y通道)

aa3c72f0276bd33df2d1cac6b97c99a5.png

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

torch 挺好用的,和我胃口-

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

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

=

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值