这里演示一个ImageNet模型的效果,模型来自CCV项目。
wget -c http://static.libccv.org/image-net-2012-vgg-d.sqlite3
wget -c https://raw.githubusercontent.com/liuliu/ccv/stable/samples/image-net-2012.words
loadccv is tool which convert libccv model to Torch. This tool is coming from github (https://github.com/deltheil/loadccv).
loadccv ./image-net-2012-vgg-d.sqlite3
这样我们可以Torch下使用的模型文件net.bin
以及meta.bin
首先我们来看一下VGG模型的结构:
nn.Sequential {
[input -> (1) -> (2) -> (3) -> (4) -> (5) -> (6) -> (7) -> (8) -> (9) -> (10) -> (11) -> (12) -> (13) -> (14) -> (15) -> (16) -> (17) -> (18) -> (19) -> (20) -> (21) -> (22) -> (23) -> (24) -> (25) -> (26) -> (27) -> (28) -> (29) -> (30) -> (31) -> (32) -> (33) -> (34) -> (35) -> (36) -> (37) -> (38) -> output]
(1): nn.SpatialConvolutionMM(3 -> 64, 3x3, 1,1)
(2): nn.ReLU
(3): nn.SpatialConvolutionMM(64 -> 64, 3x3, 1,1)
(4): nn.ReLU
(5): nn.SpatialMaxPooling(3,3,2,2)
(6): nn.SpatialConvolutionMM(64 -> 128, 3x3, 1,1)
(7): nn.ReLU
(8): nn.SpatialConvolutionMM(128 -> 128, 3x3, 1,1)
(9): nn.ReLU
(10): nn.SpatialMaxPooling(3,3,2,2)
(11): nn.SpatialConvolutionMM(128 -> 256, 3x3, 1,1)
(12): nn.ReLU
(13): nn.SpatialConvolutionMM(256 -> 256, 3x3, 1,1)
(14): nn.ReLU
(15): nn.SpatialConvolutionMM(256 -> 256, 3x3, 1,1)
(16): nn.ReLU
(17): nn.SpatialMaxPooling(3,3,2,2)
(18): nn.SpatialConvolutionMM(256 -> 512, 3x3, 1,1)
(19): nn.ReLU
(20): nn.SpatialConvolutionMM(512 -> 512, 3x3, 1,1)
(21): nn.ReLU
(22): nn.SpatialConvolutionMM(512 -> 512, 3x3, 1,1)
(23): nn.ReLU
(24): nn.SpatialMaxPooling(3,3,2,2)
(25): nn.SpatialConvolutionMM(512 -> 512, 3x3, 1,1)
(26): nn.ReLU
(27): nn.SpatialConvolutionMM(512 -> 512, 3x3, 1,1)
(28): nn.ReLU
(29): nn.SpatialConvolutionMM(512 -> 512, 3x3, 1,1)
(30): nn.ReLU
(31): nn.SpatialMaxPooling(3,3,2,2)
(32): nn.Transpose
(33): nn.Reshape(18432)
(34): nn.Linear(18432 -> 4096)
(35): nn.ReLU
(36): nn.Linear(4096 -> 4096)
(37): nn.ReLU
(38): nn.Linear(4096 -> 1000)
}
In [1]:
-- 首先载入Meta信息
require('nn')
meta = torch.load('./meta.bin')
print(meta)
-- 载入分类文本
local fc = io.open("image-net-2012.words")
local classText = {}
while true do
local line = fc:read()
if line == nil then break end
table.insert(classText, line)
end
fc:close()
-- 列出分类文本信息
for i=500,510 do
print('==>' .. classText[i])
end
meta.classText = classText
Out[1]:
Out[1]:
In [2]:
-- 装载最后的Torch模型
model = torch.load('net.bin')
In [3]:
require('image')
orignalImages = {}
for i=1,10 do
local img = image.loadPNG('./images/'..i..'.png', 3)
orignalImages[i] = img:float()
end
-- 进行数据的预处理
testImages = {}
local imageMean = meta.mean:sub(1, 3, 1,256, 1,256)
for i=1,#orignalImages do
local img = orignalImages[i] * 256
img = img - imageMean
img = image.crop(img, 10, 10, 235, 235)
testImages[i] = img
end
In [4]:
itorch.image( orignalImages)
local tb = sys.clock()
for i=1, #testImages do
local scores = model:forward(testImages[i])
local _, results = torch.sort(scores, true)
print(i .. "------------------------")
for j = 1, 5 do
print(j .. "==> " .. meta.classText[ results[j] ] )
end
end
local totalTime = sys.clock() - tb
print("### 总用时:" .. totalTime)
Out[4]:
Out[4]:
Out[4]:
Out[4]:
Out[4]:
Out[4]:
Out[4]:
Out[4]:
Out[4]:
Out[4]:
Out[4]:
Out[4]:
Out[4]:
In [5]:
require('cunn')
require('cutorch')
model:cuda()
for i=1, #testImages do
testImages[i] = testImages[i]:float():cuda()
end
local tb = sys.clock()
for i=1, #testImages do
local scores = model:forward(testImages[i])
scores:float()
local _, results = torch.sort(scores, true)
--print(i .. "------------------------")
--for j = 1, 5 do
-- print(j .. "==> " .. meta.classText[ results[j] ] )
--end
end
local totalTime = sys.clock() - tb
print("### 总用时:" .. totalTime)
Out[5]:
In [ ]: