Commit f9552033 authored by Benjamin Thomas Graham's avatar Benjamin Thomas Graham
Browse files

initial commit

parents
-- Copyright 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the license found in the
-- LICENSE file in the root directory of this source tree.
return function(sparseconvnet)
local C = sparseconvnet.C
local Convolution, parent = torch.class(
'sparseconvnet.ValidConvolution', 'nn.Module', sparseconvnet)
function Convolution:__init(dimension, nInputPlanes, nOutputPlanes,
filterSize, bias)
parent.__init(self)
self.dimension = dimension
self.nInputPlanes = nInputPlanes
self.nOutputPlanes = nOutputPlanes
self.filterSize = sparseconvnet.toLongTensor(filterSize,dimension)
self.filterStride = sparseconvnet.toLongTensor(1,dimension)
self.filterVolume = self.filterSize:prod()
for i = 1, dimension do
assert(self.filterSize[i]%2==1)
end
self.weight = torch.Tensor(nInputPlanes*self.filterVolume,nOutputPlanes)
self.gradWeight = torch.Tensor(nInputPlanes*self.filterVolume,nOutputPlanes)
if (type(bias) ~= 'boolean') or bias then
self.bias = torch.Tensor(nOutputPlanes)
self.gradBias = torch.Tensor(nOutputPlanes)
end
self.output = {
features = torch.Tensor(),
}
self.gradInput = {
features = torch.Tensor()
}
self:reset()
end
function Convolution:reset()
local stdv = math.sqrt(2/self.nInputPlanes/self.filterVolume)
self.weight:normal(0, stdv)
if self.bias then
self.bias:zero()
end
return self
end
function Convolution:updateOutput(input)
assert(input.features:size(2)==self.nInputPlanes)
self.output.metadata = input.metadata
self.output.spatialSize = input.spatialSize
self.shared.forwardPassMultiplyAddCount=
self.shared.forwardPassMultiplyAddCount+
C.dimTypedFn(self.dimension, self._type, 'ValidConvolution_updateOutput')(
input.spatialSize:cdata(),
self.filterSize:cdata(),
input.metadata.ffi,
input.features:cdata(),
self.output.features:cdata(),
self.weight:cdata(),
self.bias and self.bias:cdata(),
self.filterVolume,
self.shared.rulesBuffer and self.shared.rulesBuffer:cdata())
self.shared.forwardPassHiddenStates=
self.shared.forwardPassHiddenStates + self.output.features:nElement()
return self.output
end
function Convolution:backward(input, gradOutput)
C.dimTypedFn(self.dimension, self._type, 'ValidConvolution_backward')(
input.spatialSize:cdata(),
self.filterSize:cdata(),
input.metadata.ffi,
input.features:cdata(),
self.gradInput.features:cdata(),
gradOutput.features:cdata(),
self.weight:cdata(),
self.gradWeight:cdata(),
self.gradBias and self.gradBias:cdata() ,
self.filterVolume,
self.shared.rulesBuffer and self.shared.rulesBuffer:cdata())
return self.gradInput
end
function Convolution:type(type,tensorCache)
if type==nil then
return self._type
else
self._type=type
self.weight = self.weight:type(type)
self.gradWeight =self.gradWeight:type(type)
if self.bias then
self.bias = self.bias:type(type)
self.gradBias =self.gradBias:type(type)
end
self.output.features=self.output.features:type(type)
self.gradInput.features=self.gradInput.features:type(type)
end
end
function Convolution:__tostring()
local s = 'ValidConvolution ' .. self.nInputPlanes .. '->' .. self.nOutputPlanes..' C'
if self.filterSize:max()==self.filterSize:min() and
self.filterStride:max()==self.filterStride:min() then
s=s..self.filterSize[1] ..(self.filterStride[1]==1 and
'' or '/'..self.filterStride[1])
else
s=s..'('..self.filterSize[1]
for i=2,self.dimension do
s=s..','..self.filterSize[i]
end
s=s..')/('..self.filterStride[1]
for i=2,self.dimension do
s=s..','..self.filterStride[i]
end
s=s..')'
end
return s
end
function Convolution:clearState()
self.output={features=self.output.features:set()}
self.gradInput={features=self.gradInput.features:set()}
self.rules=nil
end
function Convolution:suggestInputSize(nOut)
return nOut
end
end
-- Copyright 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the license found in the
-- LICENSE file in the root directory of this source tree.
local sparseconvnet = {}
sparseconvnet.nn=require 'nn'
sparseconvnet.optim=require 'optim'
sparseconvnet.cutorch = pcall(require , 'cutorch')
sparseconvnet.cunn = pcall(require , 'cunn')
sparseconvnet.cudnn = pcall(require, 'cudnn')
for _,module in ipairs({
'sparseconvnet.C',
'sparseconvnet.AffineReluTrivialConvolution',
'sparseconvnet.AveragePooling',
'sparseconvnet.BatchNormalization',
'sparseconvnet.BatchNormalizationInTensor',
'sparseconvnet.BatchwiseDropout',
'sparseconvnet.CAddTable',
'sparseconvnet.ClassificationTrainValidate',
'sparseconvnet.ConcatTable',
'sparseconvnet.Convolution',
'sparseconvnet.DataLoader',
'sparseconvnet.Deconvolution',
'sparseconvnet.DenseNetBlock',
'sparseconvnet.Identity',
'sparseconvnet.InputBatch',
'sparseconvnet.JoinTable',
'sparseconvnet.LeakyReLU',
'sparseconvnet.MaxPooling',
'sparseconvnet.Metadata',
'sparseconvnet.NetworkArchitectures',
'sparseconvnet.NetworkInNetwork',
'sparseconvnet.ReLU',
'sparseconvnet.Sequential',
'sparseconvnet.SparseToDense',
'sparseconvnet.ValidConvolution',
}) do
require(module)(sparseconvnet)
end
function sparseconvnet.initializeDenseModel(model)
--Following https://github.com/facebook/fb.resnet.torch/blob/master/models/preresnet.lua
local function ConvInit(name)
for k,v in pairs(model:findModules(name)) do
local n = v.kW*v.kH*v.nInputPlane --use nInputPlane instead of nOutputPlane
v.weight:normal(0,math.sqrt(2/n))
if cudnn.version >= 4000 then
v.bias = nil
v.gradBias = nil
else
v.bias:zero()
end
end
end
local function BNInit(name)
for k,v in pairs(model:findModules(name)) do
v.weight:fill(1)
v.bias:zero()
end
end
ConvInit('cudnn.SpatialConvolution')
ConvInit('nn.SpatialConvolution')
BNInit('fbnn.SpatialBatchNormalization')
BNInit('cudnn.SpatialBatchNormalization')
BNInit('nn.SpatialBatchNormalization')
for k,v in pairs(model:findModules('nn.Linear')) do
v.bias:zero()
end
return model
end
function sparseconvnet.toLongTensor(x,dimension)
if type(x) == 'number' then
return torch.LongTensor(dimension):fill(x)
elseif type(x) == 'table' then
return torch.LongTensor(x)
else
assert(x:size(1) == dimension)
return x
end
end
function sparseconvnet.toDoubleTensor(x,dimension)
if type(x) == 'number' then
return torch.DoubleTensor(dimension):fill(x)
elseif type(x) == 'table' then
return torch.DoubleTensor(x)
else
return x
end
end
function sparseconvnet.shareShared(mod)
mod.shared = mod.shared or
{forwardPassMultiplyAddCount=0, forwardPassHiddenStates=0}
if mod._type:sub(7,10) == 'Cuda' then --only needed on the GPU
if sparseconvnet.ruleBookBits==64 then
mod.shared.rulesBuffer = torch.CudaLongTensor()
else
mod.shared.rulesBuffer = torch.CudaIntTensor()
end
else
mod.shared.rulesBuffer = nil
end
local function walk(module)
module.shared=mod.shared
if module.modules then
for _,module in ipairs(module.modules) do
walk(module)
end
end
end
walk(mod)
end
return sparseconvnet
-- Copyright 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the license found in the
-- LICENSE file in the root directory of this source tree.
package = "sparseconvnet"
version = "0.1-0"
source = {
url = "",
tag = "master"
}
description = {
summary = "Submanifold Sparse ConvNets for Torch",
detailed = [[
]],
homepage = "",
license = "CC-BY-NC"
}
dependencies = {
"torch >= 7.0",
"nn",
}
build = {
type = "command",
build_command = [[
cmake -E make_directory build;
cd build;
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="$(LUA_BINDIR)/.." -DCMAKE_INSTALL_PREFIX="$(PREFIX)"
]],
install_command = "cd build && $(MAKE) install"
}
-- Copyright 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the license found in the
-- LICENSE file in the root directory of this source tree.
local sparseconvnet=require 'sparseconvnet'
local tensortype = sparseconvnet.cutorch
and 'torch.CudaTensor' or 'torch.FloatTensor'
-- two-dimensional SparseConvNet
local model = nn.Sequential()
local sparseModel = sparseconvnet.Sequential()
local denseModel = nn.Sequential()
model:add(sparseModel):add(denseModel)
sparseModel
:add(sparseconvnet.ValidConvolution(2,3,16,3,false))
:add(sparseconvnet.SparseDenseNet(2,16,{
{'MP',compression=0},
{nExtraLayers=2, growthRate=16},
{'BN-R-C-AP',compression=0},
{nExtraLayers=2, growthRate=16},
{'BN-R-C-AP',compression=0},
{nExtraLayers=2, growthRate=16},
{'BN-R-C-AP',compression=0},
{nExtraLayers=2, growthRate=16},
}))
local nOut=sparseModel.modules[2].nOutputPlanes
sparseModel:add(sparseconvnet.BatchNormReLU(nOut))
sparseModel:add(sparseconvnet.Convolution(2,nOut,64,6,1,false))
sparseModel:add(sparseconvnet.BatchNormReLU(64))
sparseModel:add(sparseconvnet.SparseToDense(2))
denseModel:add(nn.View(64):setNumInputDims(3))
denseModel:add(nn.Linear(64, 3755))
sparseconvnet.initializeDenseModel(denseModel)
model:type(tensortype)
print(model)
inputSpatialSize=sparseModel:suggestInputSize(torch.LongTensor{1,1})
print("inputSpatialSize",inputSpatialSize)
local dataset = dofile('data.lua')(inputSpatialSize,64,2)
sparseconvnet.ClassificationTrainValidate(model,dataset,
{nEpochs=100,initial_LR=0.1, LR_decay=0.05,weightDecay=1e-4})
# Copyright 2016-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.
import torch
import torch.legacy.nn as nn
import sparseconvnet.legacy as scn
from data import getIterators
# Use the GPU if there is one, otherwise CPU
dtype = 'torch.cuda.FloatTensor' if torch.cuda.is_available() else 'torch.FloatTensor'
# two-dimensional SparseConvNet
model = nn.Sequential()
sparseModel = scn.Sequential()
denseModel = nn.Sequential()
model.add(sparseModel).add(denseModel)
sparseModel.add(scn.ValidConvolution(2, 3, 8, 3, False))\
.add(scn.SparseDenseNet(2, 8, [
{'pool': 'MP', 'compression': 0},
{'nExtraLayers': 2, 'growthRate': 8},
{'pool': 'BN-R-C-AP', 'compression': 0},
{'nExtraLayers': 2, 'growthRate': 8},
{'pool': 'BN-R-C-AP', 'compression': 0},
{'nExtraLayers': 2, 'growthRate': 8},
{'pool': 'BN-R-C-AP', 'compression': 0},
{'nExtraLayers': 2, 'growthRate': 8}]))
n_out = sparseModel.modules[-1].nOutputPlanes
sparseModel.add(scn.Convolution(2, n_out, 64, 6, 1, False))
sparseModel.add(scn.BatchNormReLU(64))
sparseModel.add(scn.SparseToDense(2))
denseModel.add(nn.View(-1, 64))
denseModel.add(nn.Linear(64, 183))
model.type(dtype)
print(model)
spatial_size = sparseModel.suggestInputSize(torch.LongTensor([1, 1]))
print('input spatial size', spatial_size)
dataset = getIterators(spatial_size, 63, 2)
scn.ClassificationTrainValidate(
model, dataset,
{'nEpochs': 100, 'initial_LR': 0.1, 'LR_decay': 0.05, 'weightDecay': 1e-4})
-- Copyright 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the license found in the
-- LICENSE file in the root directory of this source tree.
local sparseconvnet=require 'sparseconvnet'
local tensortype = sparseconvnet.cutorch
and 'torch.CudaTensor' or 'torch.FloatTensor'
-- two-dimensional SparseConvNet
local model = nn.Sequential()
local sparseModel = sparseconvnet.Sequential()
local denseModel = nn.Sequential()
model:add(sparseModel):add(denseModel)
sparseModel
:add(sparseconvnet.ValidConvolution(2,3,8,3,false))
:add(sparseconvnet.MaxPooling(2,3,2))
:add(sparseconvnet.SparseResNet(
2,8,{
{'b', 8, 2, 1},
{'b', 16, 2, 2},
{'b', 24, 2, 2},
{'b', 32, 2, 2},}))
sparseModel:add(sparseconvnet.Convolution(2,32,64,5,1,false))
sparseModel:add(sparseconvnet.BatchNormReLU(64))
sparseModel:add(sparseconvnet.SparseToDense(2))
denseModel:add(nn.View(64):setNumInputDims(3))
denseModel:add(nn.Linear(64, 183))
sparseconvnet.initializeDenseModel(denseModel)
model:type(tensortype)
print(model)
inputSpatialSize=sparseModel:suggestInputSize(torch.LongTensor{1,1})
print("inputSpatialSize",inputSpatialSize)
local dataset = dofile('data.lua')(inputSpatialSize,63,3)
sparseconvnet.ClassificationTrainValidate(model,dataset,
{nEpochs=100,initial_LR=0.1, LR_decay=0.05,weightDecay=1e-4})
# Copyright 2016-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.
import torch
import torch.legacy.nn as nn
import sparseconvnet.legacy as scn
from data import getIterators
# Use the GPU if there is one, otherwise CPU
dtype = 'torch.cuda.FloatTensor' if torch.cuda.is_available() else 'torch.FloatTensor'
# two-dimensional SparseConvNet
model = nn.Sequential()
sparseModel = scn.Sequential()
denseModel = nn.Sequential()
model.add(sparseModel).add(denseModel)
sparseModel.add(scn.ValidConvolution(2, 3, 8, 3, False))
sparseModel.add(scn.MaxPooling(2, 3, 2))
sparseModel.add(scn.SparseResNet(2, 8, [
['b', 8, 2, 1],
['b', 16, 2, 2],
['b', 24, 2, 2],
['b', 32, 2, 2]]))
sparseModel.add(scn.Convolution(2, 32, 64, 5, 1, False))
sparseModel.add(scn.BatchNormReLU(64))
sparseModel.add(scn.SparseToDense(2))
denseModel.add(nn.View(-1, 64))
denseModel.add(nn.Linear(64, 183))
model.type(dtype)
print(len(model.parameters()[0]))
print([x.size() for x in model.parameters()[0]])
spatial_size = sparseModel.suggestInputSize(torch.LongTensor([1, 1]))
print('input spatial size', spatial_size)
dataset = getIterators(spatial_size, 63, 3)
scn.ClassificationTrainValidate(
model, dataset,
{'nEpochs': 100, 'initial_LR': 0.1, 'LR_decay': 0.05, 'weightDecay': 1e-4})
-- Copyright 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the license found in the
-- LICENSE file in the root directory of this source tree.
local sparseconvnet=require 'sparseconvnet'
local tensortype = sparseconvnet.cutorch
and 'torch.CudaTensor' or 'torch.FloatTensor'
-- two-dimensional SparseConvNet
local model = nn.Sequential()
local sparseModel = sparseconvnet.Sequential()
local denseModel = nn.Sequential()
model:add(sparseModel):add(denseModel)
sparseModel:add(sparseconvnet.SparseVggNet(2,3,{
{'C', 8,}, {'C', 8}, 'MP',
{'C', 16}, {'C', 16}, 'MP',
{'C', 16, 8}, {'C', 16, 8}, 'MP',
{'C', 24, 8}, {'C', 24, 8}, 'MP'}))
sparseModel:add(sparseconvnet.Convolution(2,32,64,5,1,false))
sparseModel:add(sparseconvnet.BatchNormReLU(64))
sparseModel:add(sparseconvnet.SparseToDense(2))
denseModel:add(nn.View(64):setNumInputDims(3))
denseModel:add(nn.Linear(64, 183))
sparseconvnet.initializeDenseModel(denseModel)
model:type(tensortype)
print(model)
inputSpatialSize=sparseModel:suggestInputSize(torch.LongTensor{1,1})
print("inputSpatialSize",inputSpatialSize)
local dataset = dofile('data.lua')(inputSpatialSize,63,3)
sparseconvnet.ClassificationTrainValidate(model,dataset,
{nEpochs=100,initial_LR=0.1, LR_decay=0.05,weightDecay=1e-4})
# Copyright 2016-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.
import torch
import torch.legacy.nn as nn
import sparseconvnet.legacy as scn
from data import getIterators
# Use the GPU if there is one, otherwise CPU
dtype = 'torch.cuda.FloatTensor' if torch.cuda.is_available() else 'torch.FloatTensor'
# two-dimensional SparseConvNet
model = nn.Sequential()
sparseModel = scn.Sequential()
denseModel = nn.Sequential()
model.add(sparseModel).add(denseModel)
sparseModel.add(scn.SparseVggNet(2, 3, [
['C', 8, ], ['C', 8], 'MP',
['C', 16], ['C', 16], 'MP',
['C', 16, 8], ['C', 16, 8], 'MP',
['C', 24, 8], ['C', 24, 8], 'MP']))
sparseModel.add(scn.Convolution(2, 32, 64, 5, 1, False))
sparseModel.add(scn.BatchNormReLU(64))
sparseModel.add(scn.SparseToDense(2))
denseModel.add(nn.View(-1, 64))
denseModel.add(nn.Linear(64, 183))
model.type(dtype)
print(model)
spatial_size = sparseModel.suggestInputSize(torch.LongTensor([1, 1]))
print('input spatial size', spatial_size)
dataset = getIterators(spatial_size, 63, 3)
scn.ClassificationTrainValidate(
model, dataset,
{'nEpochs': 100, 'initial_LR': 0.1, 'LR_decay': 0.05, 'weightDecay': 1e-4})
-- Copyright 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the license found in the
-- LICENSE file in the root directory of this source tree.
tnt=require 'torchnet'
scn=require 'sparseconvnet'
require 'paths'
if not paths.dirp('t7/') then
print('Downloading and preprocessing data ...')
os.execute('bash process.sh')
dofile('process.lua')
end
function train(spatialSize,Scale,precomputeStride)
local d=torch.load('t7/train.t7')
print('Replicating training set 10 times (1 epoch = 10 iterations through the training set = 10x6588 training samples)')
for i=1,9 do
for j=1,6588 do
d[#d+1]=d[j]
end
end
d=tnt.ListDataset(d,function(x) return x end):shuffle()
function d:manualSeed(seed) torch.manualSeed(seed) end
d=tnt.BatchDataset(d,108,function(idx, size) return idx end,function (tbl)
input=scn.InputBatch(2,spatialSize)
local center=spatialSize:float():view(1,2)/2
local p=torch.LongTensor(2)
local v=torch.FloatTensor({1,0,0})
for _,char in ipairs(tbl.input) do
input:addSample()
local m=torch.eye(2):float()
local r=torch.random(3)
local alpha=torch.uniform(-0.2,0.2)
if alpha==1 then
m[1][2]=alpha
elseif alpha==2 then
m[2][1]=alpha
else
m=torch.mm(m,torch.FloatTensor({
{math.cos(alpha),math.sin(alpha)},
{-math.sin(alpha),math.cos(alpha)}}))
end
c=(center+torch.FloatTensor(1,2):uniform(-8,8))
for _,stroke in ipairs(char) do
stroke=stroke:float()/255-0.5
stroke=c:expandAs(stroke)+stroke*m*(Scale-0.01)
--------------------------------------------------------------
-- Draw pen stroke:
scn.C.dimensionFn(2,'drawCurve')(
input.metadata.ffi,input.features:cdata(),stroke:cdata())
--------------------------------------------------------------
-- Above is equivalent to :
-- local x1,x2,y1,y2,l=0,stroke[1][1],0,stroke[1][2],0
-- for i=2,stroke:size(1) do
-- x1=x2
-- y1=y2
-- x2=stroke[i][1]
-- y2=stroke[i][2]
-- l=1e-10+((x2-x1)^2+(y2-y1)^2)^0.5
-- v[2]=(x2-x1)/l
-- v[3]=(y2-y1)/l
-- l=math.max(x2-x1,y2-y1,x1-x2,y1-y2,0.9)
-- for j=0,1,1/l do
-- p[1]=math.floor(x1*j+x2*(1-j))
-- p[2]=math.floor(y1*j+y2*(1-j))
-- input:setLocation(p,v,false)
-- end
-- end
--------------------------------------------------------------
end
end
input:precomputeMetadata(precomputeStride)
return {input=input,target=torch.LongTensor(tbl.target)}
end
)
d=tnt.ParallelDatasetIterator({
init = function() require 'torchnet'; scn=require 'sparseconvnet' end,
nthread = 10,
closure = function() return d end,
ordered = true})
return function(epoch)
d:exec('manualSeed', epoch)
d:exec('resample')
return d()
end
end
function val(spatialSize,Scale,precomputeStride)
local d=torch.load('t7/test.t7')
d=tnt.ListDataset(d,function(x) return x end)
d=tnt.BatchDataset(d,183,function(idx, size) return idx end,function (tbl)
input=scn.InputBatch(2,spatialSize)
local center=spatialSize:float():view(1,2)/2
local p=torch.LongTensor(2)
local v=torch.FloatTensor({1,0,0})
for _,char in ipairs(tbl.input) do
input:addSample()
for _,stroke in ipairs(char) do
stroke=stroke:float()/255-0.5
stroke=center:expandAs(stroke)+stroke*(Scale-0.01)
scn.C.dimensionFn(2,'drawCurve')(input.metadata.ffi,input.features:cdata(),stroke:cdata())
end
end
input:precomputeMetadata(precomputeStride)
return {input=input,target=torch.LongTensor(tbl.target)}
end
)
d=tnt.ParallelDatasetIterator({
init = function() require 'torchnet'; scn=require 'sparseconvnet' end,
nthread = 10,
closure = function() return d end,
ordered = true})
return function()
return d()
end
end
return function(...)
return {train=train(...), val=val(...)}
end
# Copyright 2016-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.
import torch
import torchnet
import sparseconvnet.legacy as scn
import pickle
import math
import random
import numpy
import os
if not os.path.exists('pickle/'):
print('Downloading and preprocessing data ...')
os.system('bash process.sh')
import process
def train(spatial_size, Scale, precomputeStride):
d = pickle.load(open('pickle/train.pickle', 'rb'))
print('Replicating training set 10 times (1 epoch = 10 iterations through the training set = 10x6588 training samples)')
for i in range(9):
for j in range(6588):
d.append(d[j])
d = torchnet.dataset.ListDataset(d)
randperm = torch.randperm(len(d))
def perm(idx, size):
return randperm[idx]
def merge(tbl):
inp = scn.InputBatch(2, spatial_size)
center = spatial_size.float().view(1, 2) / 2
p = torch.LongTensor(2)
v = torch.FloatTensor([1, 0, 0])
for char in tbl['input']:
inp.addSample()
m = torch.eye(2)
r = random.randint(1, 3)
alpha = random.uniform(-0.2, 0.2)
if alpha == 1:
m[0][1] = alpha
elif alpha == 2:
m[1][0] = alpha
else:
m = torch.mm(m, torch.FloatTensor(
[[math.cos(alpha), math.sin(alpha)],
[-math.sin(alpha), math.cos(alpha)]]))
c = center + torch.FloatTensor(1, 2).uniform_(-8, 8)
for stroke in char:
stroke = stroke.float() / 255 - 0.5
stroke = c.expand_as(stroke) + \
torch.mm(stroke, m * (Scale - 0.01))
###############################################################
# To avoid GIL problems use a helper function:
scn.dim_fn(
2,
'drawCurve')(
inp.metadata.ffi,
inp.features,
stroke)
###############################################################
# Above is equivalent to :
# x1,x2,y1,y2,l=0,stroke[0][0],0,stroke[0][1],0
# for i in range(1,stroke.size(0)):
# x1=x2
# y1=y2
# x2=stroke[i][0]
# y2=stroke[i][1]
# l=1e-10+((x2-x1)**2+(y2-y1)**2)**0.5
# v[1]=(x2-x1)/l
# v[2]=(y2-y1)/l
# l=max(x2-x1,y2-y1,x1-x2,y1-y2,0.9)
# for j in numpy.arange(0,1,1/l):
# p[0]=math.floor(x1*j+x2*(1-j))
# p[1]=math.floor(y1*j+y2*(1-j))
# inp.setLocation(p,v,False)
###############################################################
inp.precomputeMetadata(precomputeStride)
return {'input': inp, 'target': torch.LongTensor(tbl['target']) - 1}
bd = torchnet.dataset.BatchDataset(d, 108, perm=perm, merge=merge)
tdi = scn.threadDatasetIterator(bd)
def iter():
randperm = torch.randperm(len(d))
return tdi()
return iter
def val(spatial_size, Scale, precomputeStride):
d = pickle.load(open('pickle/test.pickle', 'rb'))
d = torchnet.dataset.ListDataset(d)
randperm = torch.randperm(len(d))
def perm(idx, size):
return randperm[idx]
def merge(tbl):
inp = scn.InputBatch(2, spatial_size)
center = spatial_size.float().view(1, 2) / 2
p = torch.LongTensor(2)
v = torch.FloatTensor([1, 0, 0])
for char in tbl['input']:
inp.addSample()
for stroke in char:
stroke = stroke.float() * (Scale - 0.01) / 255 - 0.5 * (Scale - 0.01)
stroke += center.expand_as(stroke)
scn.dim_fn(
2,
'drawCurve')(
inp.metadata.ffi,
inp.features,
stroke)
inp.precomputeMetadata(precomputeStride)
return {'input': inp, 'target': torch.LongTensor(tbl['target']) - 1}
bd = torchnet.dataset.BatchDataset(d, 183, perm=perm, merge=merge)
tdi = scn.threadDatasetIterator(bd)
def iter():
randperm = torch.randperm(len(d))
return tdi()
return iter
def getIterators(*args):
return {'train': train(*args), 'val': val(*args)}
-- Copyright 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the license found in the
-- LICENSE file in the root directory of this source tree.
train={}
test={}
torch.manualSeed(0)
p=torch.randperm(45)
function rescaleCharacter(c)
local cc=torch.cat(c,1)
local m=cc:min(1)
local s=(cc:max(1)-m):float()
for i=1,#c do
c[i]=(torch.cdiv((c[i]-m:expandAs(c[i])):float(),s:expandAs(c[i]))*255.99):byte()
end
return c
end
for char = 1,183 do
for writer = 1,36 do
train[#train+1]={input=rescaleCharacter(dofile('tmp/' .. char .. '.' .. p[writer] .. '.lua')),target=char}
end
end
for char = 1,183 do
for writer = 37,45 do
test[#test+1]={input=rescaleCharacter(dofile('tmp/' .. char .. '.' .. p[writer] .. '.lua')),target=char}
end
end
print(#train,#test)
os.execute('mkdir t7/')
torch.save('t7/train.t7',train)
torch.save('t7/test.t7',test)
# Copyright 2016-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.
import torch
import os
import pickle
train = []
test = []
p = [
45,
9,
3,
34,
31,
25,
23,
17,
22,
37,
27,
2,
10,
13,
7,
42,
4,
8,
33,
11,
12,
1,
39,
38,
36,
20,
14,
21,
40,
24,
32,
5,
35,
18,
44,
41,
30,
28,
29,
19,
15,
26,
6,
16,
43]
def rescaleCharacter(c):
cc = torch.cat(c, 0)
m = cc.min(0)[0]
s = (cc.max(0)[0] - m).float()
for i in range(len(c)):
c[i] = (
torch.div(
(c[i] -
m.expand_as(
c[i])).float(),
s.expand_as(
c[i])) *
255.99).byte()
return c
for char in range(1, 183 + 1):
for writer in range(0, 36):
exec('c=' + open('tmp/' + str(char) + '.' +
str(p[writer]) + '.py', 'r').read())
train.append({'input': rescaleCharacter(c), 'target': char})
for char in range(1, 183 + 1):
for writer in range(36, 45):
exec('c=' + open('tmp/' + str(char) + '.' +
str(p[writer]) + '.py', 'r').read())
test.append({'input': rescaleCharacter(c), 'target': char})
print(len(train), len(test))
os.mkdir('pickle')
pickle.dump(train, open('pickle/train.pickle', 'wb'))
pickle.dump(test, open('pickle/test.pickle', 'wb'))
# Copyright 2016-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.
#!/bin/bash
wget https://archive.ics.uci.edu/ml/machine-learning-databases/00208/Online%20Handwritten%20Assamese%20Characters%20Dataset.rar
unrar e -cl -y "Online Handwritten Assamese Characters Dataset.rar"
mkdir tmp
for char in `seq 1 183`; do
for writer in `seq 1 45`; do
echo 'return {f{' > z
tail -n+5 $char.$writer.txt|head -n-1 |grep -v 'PEN_UP'|uniq|sed 's/PEN_DOWN/},f{/'|sed 's/ /,/g'|cut -c1-12 >> z
echo '}}' >>z
echo 'f=function(x) return torch.LongTensor(x):view(-1,2) end' > tmp/$char.$writer.lua
cat z |tr -d '\n' |sed 's/f{},//'>> tmp/$char.$writer.lua
echo '[f([' > z
tail -n+5 $char.$writer.txt|head -n-1 |grep -v 'PEN_UP'|uniq|sed 's/PEN_DOWN/]).v,f([/'|sed 's/ /,/g'|cut -c1-12 >> z
echo ']).v]' >>z
cat z |tr -d '\n' |sed 's/f(\[\]).v,//g'|sed 's/v/view(-1,2)/g'|sed 's/f/torch.LongTensor/g'> tmp/$char.$writer.py
rm $char.$writer.txt z
done
done
-- Copyright 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the license found in the
-- LICENSE file in the root directory of this source tree.
local sparseconvnet=require 'sparseconvnet'
local tensortype = sparseconvnet.cutorch
and 'torch.CudaTensor' or 'torch.FloatTensor'
-- two-dimensional SparseConvNet
local sparseModel = sparseconvnet.Sequential()
local denseModel = nn.Sequential()
local model = nn.Sequential():add(sparseModel):add(denseModel)
sparseModel
:add(sparseconvnet.ValidConvolution(2,3,16,3,false))
:add(sparseconvnet.SparseDenseNet(2,16,{
{'MP',compression=0},
{nExtraLayers=2, growthRate=16},
{'BN-R-C-AP',compression=0},
{nExtraLayers=2, growthRate=16},
{'BN-R-C-AP',compression=0},
{nExtraLayers=2, growthRate=16},
{'BN-R-C-AP',compression=0},
{nExtraLayers=2, growthRate=16},
}))
local nOut=sparseModel.modules[2].nOutputPlanes
sparseModel:add(sparseconvnet.BatchNormReLU(nOut))
sparseModel:add(sparseconvnet.Convolution(2,nOut,256,4,1,false))
sparseModel:add(sparseconvnet.BatchNormReLU(256))
sparseModel:add(sparseconvnet.SparseToDense(2))
denseModel:add(nn.View(256):setNumInputDims(3))
denseModel:add(nn.Linear(256, 3755))
sparseconvnet.initializeDenseModel(denseModel)
model:type(tensortype)
print(model)
inputSpatialSize=sparseModel:suggestInputSize(torch.LongTensor{1,1})
print("inputSpatialSize",inputSpatialSize)
local dataset = dofile('data.lua')(inputSpatialSize,64,2)
sparseconvnet.ClassificationTrainValidate(model,dataset,
{nEpochs=100,initial_LR=0.1, LR_decay=0.05,weightDecay=1e-4})
# Copyright 2016-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.
import torch
import torch.legacy.nn as nn
import sparseconvnet.legacy as scn
from data import getIterators
# Use the GPU if there is one, otherwise CPU
dtype = 'torch.cuda.FloatTensor' if torch.cuda.is_available() else 'torch.FloatTensor'
# two-dimensional SparseConvNet
model = nn.Sequential()
sparseModel = scn.Sequential()
denseModel = nn.Sequential()
model.add(sparseModel).add(denseModel)
sparseModel.add(scn.ValidConvolution(2, 3, 16, 3, False))\
.add(scn.SparseDenseNet(2, 16, [
{'pool': 'MP', 'compression': 0},
{'nExtraLayers': 2, 'growthRate': 16},
{'pool': 'BN-R-C-AP', 'compression': 0},
{'nExtraLayers': 2, 'growthRate': 16},
{'pool': 'BN-R-C-AP', 'compression': 0},
{'nExtraLayers': 2, 'growthRate': 16},
{'pool': 'BN-R-C-AP', 'compression': 0},
{'nExtraLayers': 2, 'growthRate': 16}]))
n_out = sparseModel.modules[-1].nOutputPlanes
sparseModel.add(scn.Convolution(2, n_out, 256, 4, 1, False))
sparseModel.add(scn.BatchNormReLU(256))
sparseModel.add(scn.SparseToDense(2))
denseModel.add(nn.View(-1, 256))
denseModel.add(nn.Linear(256, 3755))
model.type(dtype)
print(model)
spatial_size = sparseModel.suggestInputSize(torch.LongTensor([1, 1]))
print('input spatial size', spatial_size)
dataset = getIterators(spatial_size, 64, 2)
scn.ClassificationTrainValidate(
model, dataset,
{'nEpochs': 100, 'initial_LR': 0.1, 'LR_decay': 0.05, 'weightDecay': 1e-4})
-- Copyright 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the license found in the
-- LICENSE file in the root directory of this source tree.
local sparseconvnet=require 'sparseconvnet'
local tensortype = sparseconvnet.cutorch
and 'torch.CudaTensor' or 'torch.FloatTensor'
-- two-dimensional SparseConvNet
local sparseModel = sparseconvnet.Sequential()
local denseModel = nn.Sequential()
local model = nn.Sequential():add(sparseModel):add(denseModel)
sparseModel
:add(sparseconvnet.ValidConvolution(2,3,16,3,false))
:add(sparseconvnet.SparseDenseNet(2,16,{
{'MP',compression=0},
{nExtraLayers=4, growthRate=16},
{'BN-R-C-AP',compression=0.5},
{nExtraLayers=4, growthRate=16},
{'BN-R-C-AP',compression=0.5},
{nExtraLayers=4, growthRate=16},
{'BN-R-C-AP',compression=0.5},
{nExtraLayers=4, growthRate=16},
}))
local nOut=sparseModel.modules[2].nOutputPlanes
sparseModel:add(sparseconvnet.BatchNormReLU(nOut))
sparseModel:add(sparseconvnet.Convolution(2,nOut,256,4,1,false))
sparseModel:add(sparseconvnet.BatchNormReLU(256))
sparseModel:add(sparseconvnet.SparseToDense(2))
denseModel:add(nn.View(256):setNumInputDims(3))
denseModel:add(nn.Linear(256, 3755))
sparseconvnet.initializeDenseModel(denseModel)
model:type(tensortype)
print(model)
inputSpatialSize=sparseModel:suggestInputSize(torch.LongTensor{1,1})
print("inputSpatialSize",inputSpatialSize)
local dataset = dofile('data.lua')(inputSpatialSize,64,2)
sparseconvnet.ClassificationTrainValidate(model,dataset,
{nEpochs=100,initial_LR=0.1, LR_decay=0.05,weightDecay=1e-4})
-- Copyright 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the license found in the
-- LICENSE file in the root directory of this source tree.
local sparseconvnet=require 'sparseconvnet'
local tensortype = sparseconvnet.cutorch
and 'torch.CudaTensor' or 'torch.FloatTensor'
if tensortype == 'torch.CudaTensor' then
cutorch.setDevice(1)
print(cutorch.getDeviceCount() .. " GPU device(s)")
print(" . . . . free memory . . memory")
for i=1,cutorch.getDeviceCount() do
io.write(i==cutorch.getDevice() and " * " or " . ")
print('(' .. i .. ') ', cutorch.getMemoryUsage(i))
end
end
-- two-dimensional SparseConvNet
local sparseModel = sparseconvnet.Sequential()
local denseModel = nn.Sequential()
local model = nn.Sequential():add(sparseModel):add(denseModel)
sparseModel
:add(sparseconvnet.ValidConvolution(2,3,16,3,false))
:add(sparseconvnet.MaxPooling(2,2,2))
:add(sparseconvnet.SparseResNet(
2,16,{
{'b', 16, 2, 1},
{'b', 32, 2, 2},
{'b', 48, 2, 2},
{'b', 96, 2, 2},}))
sparseModel:add(sparseconvnet.Convolution(2,96,128,4,1,false))
sparseModel:add(sparseconvnet.BatchNormReLU(128))
sparseModel:add(sparseconvnet.SparseToDense(2))
denseModel:add(nn.View(128):setNumInputDims(3))
denseModel:add(nn.Linear(128, 3755))
sparseconvnet.initializeDenseModel(denseModel)
model:type(tensortype)
print(model)
inputSpatialSize=sparseModel:suggestInputSize(torch.LongTensor{1,1})
print("inputSpatialSize",inputSpatialSize)
local dataset = dofile('data.lua')(inputSpatialSize,64,3)
sparseconvnet.ClassificationTrainValidate(model,dataset,
{nEpochs=100,initial_LR=0.1, LR_decay=0.05,weightDecay=1e-4})
# Copyright 2016-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.
import torch
import torch.legacy.nn as nn
import sparseconvnet.legacy as scn
from data import getIterators
# Use the GPU if there is one, otherwise CPU
dtype = 'torch.cuda.FloatTensor' if torch.cuda.is_available() else 'torch.FloatTensor'
# two-dimensional SparseConvNet
model = nn.Sequential()
sparseModel = scn.Sequential()
denseModel = nn.Sequential()
model.add(sparseModel).add(denseModel)
sparseModel.add(scn.ValidConvolution(2, 3, 16, 3, False))
sparseModel.add(scn.MaxPooling(2, 3, 2))
sparseModel.add(scn.SparseResNet(2, 16, [
['b', 16, 2, 1],
['b', 32, 2, 2],
['b', 48, 2, 2],
['b', 96, 2, 2]]))
sparseModel.add(scn.Convolution(2, 96, 128, 4, 1, False))
sparseModel.add(scn.BatchNormReLU(128))
sparseModel.add(scn.SparseToDense(2))
denseModel.add(nn.View(-1, 128))
denseModel.add(nn.Linear(128, 3755))
model.type(dtype)
print(model)
spatial_size = sparseModel.suggestInputSize(torch.LongTensor([1, 1]))
print('input spatial size', spatial_size)
dataset = getIterators(spatial_size, 63, 3)
scn.ClassificationTrainValidate(
model, dataset,
{'nEpochs': 100, 'initial_LR': 0.1, 'LR_decay': 0.05, 'weightDecay': 1e-4})
-- Copyright 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the license found in the
-- LICENSE file in the root directory of this source tree.
local sparseconvnet=require 'sparseconvnet'
local tensortype = sparseconvnet.cutorch
and 'torch.CudaTensor' or 'torch.FloatTensor'
-- two-dimensional SparseConvNet
local sparseModel = sparseconvnet.Sequential()
local denseModel = nn.Sequential()
local model = nn.Sequential():add(sparseModel):add(denseModel)
sparseModel
:add(sparseconvnet.ValidConvolution(2,3,16,3,false))
:add(sparseconvnet.MaxPooling(2,2,2))
:add(sparseconvnet.SparseResNet(
2,16,{
{'b', 16, 2, 1},
{'b', 32, 2, 2},
{'b', 64, 2, 2},
{'b', 128, 2, 2},}))
sparseModel:add(sparseconvnet.Convolution(2,128,256,4,1,false,false))
sparseModel:add(sparseconvnet.BatchNormReLU(256))
sparseModel:add(sparseconvnet.SparseToDense(2))
denseModel:add(nn.View(256):setNumInputDims(3))
denseModel:add(nn.Linear(256, 3755))
sparseconvnet.initializeDenseModel(denseModel)
model:type(tensortype)
print(model)
inputSpatialSize=sparseModel:suggestInputSize(torch.LongTensor{1,1})
print("inputSpatialSize",inputSpatialSize)
local dataset = dofile('data.lua')(inputSpatialSize,64,3)
sparseconvnet.ClassificationTrainValidate(model,dataset,
{nEpochs=100,initial_LR=0.1, LR_decay=0.05,weightDecay=1e-4})
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment