Torch7 教程 Supervised Learning CNN
分类: 机器学习 2014-08-08 15:59 1426人阅读 评论(0) 收藏 举报
全部代码放在:https://github.com/guoyilin/CNN_Torch7
在搭建好Torch7之后,我们开始进行监督式Supervised Learning for CNN, Torch7提供了代码和一些说明文件:
http://code.madbits.com/wiki/doku.php?id=tutorial_supervised_1_data 和http://torch.cogbits.com/doc/tutorials_supervised/说的比较详细。
结合http://ufldl.stanford.edu/wiki/index.php/Feature_extraction_using_convolution了解CNN的做法,最关键的是要熟悉http://ufldl.stanford.edu/wiki/index.php/Backpropagation_Algorithm 算法的主要做法。bp算法的目的是为了一次性计算所有的参数导数,该算法利用了chain rule进行error的后向传播。这篇文章写了bp算法: http://neuralnetworksanddeeplearning.com/chap2.html, 写的比较详细。
如果背景不熟悉,可以看看Linear Classification, Neutral Network, SGD算法。
由于该教程使用了torch自己的数据格式,因此如果你要使用自己的数据,需要预先转换下。这里我训练的是图像分类,因此可以使用
https://github.com/clementfarabet/graphicsmagick 进行数据的加载。
如下是加载图像的代码:
[plain] view plaincopyprint?
- height = 200
- width = 200
- --see if the file exists
- function file_exists(file)
- local f = io.open(file, "rb")
- if f then f:close() end
- return f ~= nil
- end
- function read_file (file)
- if not file_exists(file) then return {} end
- lines = {}
- for line in io.lines(file) do
- lines[#lines + 1] = line
- end
- return lines
- end
- -- read all label name. hash them to id.
- labels_id = {}
- label_lines = read_file(‘labels.txt‘)
- for i = 1, #label_lines do
- labels_id[label_lines[i]] = i
- end
- -- read train data. iterate train.txt
- local train_lines = read_file("train.txt")
- local train_features = torch.Tensor(#train_lines, 3, height, width) -- dimension: sample number, YUV, height, width
- local train_labels = torch.Tensor(#train_lines) -- dimension: sample number
- for i = 1, #train_lines do
- local image = gm.Image("/train_images/" .. train_lines[i])
- image:size(width, height)
- img_yuv = image:toTensor(‘float‘, ‘YUV‘, ‘DHW‘)
- --print(img_yuv:size())
- --print(img_yuv:size())
- train_features[i] = img_yuv
- local label_name = train_lines[i]:match("([^,]+)/([^,]+)")
- train_labels[i] = labels_id[label_name]
- --print(train_labels[i])
- if(i % 100 == 0) then
- print("train data: " .. i)
- end
- end
- trainData = {
- data = train_features:transpose(3,4),
- labels = train_labels,
- --size = function() return #train_lines end
- size = function() return #train_lines end
- }
- -- read test data. iterate test.txt
- local test_lines = read_file("test.txt")
- local test_features = torch.Tensor(#test_lines, 3, height, width) -- dimension: sample number, YUV, height, width
- local test_labels = torch.Tensor(#test_lines) -- dimension: sample number
- for i = 1, #test_lines do
- -- if image size is zero, gm.Imge may throw error, we need to dispose it later.
- local image = gm.Image("test_images/" .. test_lines[i])
- --print(test_lines[i])
- image:size(width, height)
- local img_yuv = image:toTensor(‘float‘, ‘YUV‘, ‘DHW‘)
- --print(img_yuv:size())
- test_features[i] = img_yuv
- local label_name = test_lines[i]:match("([^,]+)/([^,]+)")
- test_labels[i] = labels_id[label_name]
- --print(test_labels[i])
- if(i % 100 == 0) then
- print("test data: " .. i)
- end
- end
- testData = {
- data = test_features:transpose(3,4),
- labels = test_labels,
- --size = function() return #test_lines end
- size = function() return #test_lines end
- }
- trsize = #train_lines
- tesize = #test_lines
height = 200 width = 200 --see if the file exists function file_exists(file) local f = io.open(file, "rb") if f then f:close() end return f ~= nil end function read_file (file) if not file_exists(file) then return {} end lines = {} for line in io.lines(file) do lines[#lines + 1] = line end return lines end -- read all label name. hash them to id. labels_id = {} label_lines = read_file(‘labels.txt‘) for i = 1, #label_lines do labels_id[label_lines[i]] = i end -- read train data. iterate train.txt local train_lines = read_file("train.txt") local train_features = torch.Tensor(#train_lines, 3, height, width) -- dimension: sample number, YUV, height, width local train_labels = torch.Tensor(#train_lines) -- dimension: sample number for i = 1, #train_lines do local image = gm.Image("/train_images/" .. train_lines[i]) image:size(width, height) img_yuv = image:toTensor(‘float‘, ‘YUV‘, ‘DHW‘) --print(img_yuv:size()) --print(img_yuv:size()) train_features[i] = img_yuv local label_name = train_lines[i]:match("([^,]+)/([^,]+)") train_labels[i] = labels_id[label_name] --print(train_labels[i]) if(i % 100 == 0) then print("train data: " .. i) end end trainData = { data = train_features:transpose(3,4), labels = train_labels, --size = function() return #train_lines end size = function() return #train_lines end } -- read test data. iterate test.txt local test_lines = read_file("test.txt") local test_features = torch.Tensor(#test_lines, 3, height, width) -- dimension: sample number, YUV, height, width local test_labels = torch.Tensor(#test_lines) -- dimension: sample number for i = 1, #test_lines do -- if image size is zero, gm.Imge may throw error, we need to dispose it later. local image = gm.Image("test_images/" .. test_lines[i]) --print(test_lines[i]) image:size(width, height) local img_yuv = image:toTensor(‘float‘, ‘YUV‘, ‘DHW‘) --print(img_yuv:size()) test_features[i] = img_yuv local label_name = test_lines[i]:match("([^,]+)/([^,]+)") test_labels[i] = labels_id[label_name] --print(test_labels[i]) if(i % 100 == 0) then print("test data: " .. i) end end testData = { data = test_features:transpose(3,4), labels = test_labels, --size = function() return #test_lines end size = function() return #test_lines end } trsize = #train_lines tesize = #test_lines
由于图像的大小从32*32变成了200*200, 因此需要修改相应的model中的每一层的大小。
假定其他层没有变化,最后一层需要修改:
[plain] view plaincopyprint?
- -- stage 3 : standard 2-layer neural network
- model:add(nn.Reshape(nstates[2]*47*47))
- model:add(nn.Linear(nstates[2]*47*47, nstates[3]))
- model:add(nn.Tanh())
- model:add(nn.Linear(nstates[3], noutputs))