Commit 1df7b845 authored by Benjamin Thomas Graham's avatar Benjamin Thomas Graham
Browse files

3d segmantation

parent f2e3800b
-- 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.SubmanifoldConvolution',
}) 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-1"
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.
import numpy as np
import torch
import torchnet
import glob, math, os
import scipy, scipy.ndimage
import sparseconvnet as scn
if not os.path.exists('train_val/'):
print('Downloading data ...')
os.system('bash download_and_split_data.sh')
categories=["02691156", "02773838", "02954340", "02958343",
"03001627", "03261776", "03467517", "03624134",
"03636649", "03642806", "03790512", "03797390",
"03948459", "04099429", "04225987", "04379243"]
classes=['Airplane', 'Bag', 'Cap', 'Car',
'Chair', 'Earphone', 'Guitar', 'Knife',
'Lamp', 'Laptop', 'Motorbike', 'Mug',
'Pistol', 'Rocket', 'Skateboard', 'Table']
nClasses=[4, 2, 2, 4, 4, 3, 3, 2, 4, 2, 6, 2, 3, 3, 3, 3]
classOffsets=np.cumsum([0]+nClasses)
def init(c,resolution=50,sz=50*8+8,batchSize=16):
globals()['categ']=c
globals()['resolution']=resolution
globals()['batchSize']=batchSize
globals()['spatialSize']=torch.LongTensor([sz]*3)
if categ==-1:
print('All categories: 50 classes')
globals()['nClassesTotal']=int(classOffsets[-1])
else:
print('categ ',categ,classes[categ])
globals()['nClassesTotal']=int(nClasses[categ])
def load(xF, c, classOffset, nc):
xl=np.loadtxt(xF[0])
xl/= ((xl**2).sum(1).max()**0.5)
y = np.loadtxt(xF[0][:-9]+'seg').astype('int64')+classOffset-1
return (xF[0], xl, y, c, classOffset, nc, np.random.randint(1e6))
def train():
d=[]
if categ==-1:
for c in range(16):
for x in torch.utils.data.DataLoader(
glob.glob('train_val/'+categories[c]+'/*.pts.train'),
collate_fn=lambda x: load(x, c, classOffsets[c],nClasses[c]),
num_workers=12):
d.append(x)
else:
for x in torch.utils.data.DataLoader(
glob.glob('train_val/'+categories[categ]+'/*.pts.train'),
collate_fn=lambda x: load(x, categ, 0, nClasses[categ]),
num_workers=12):
d.append(x)
print(len(d))
def merge(tbl):
xl_=[]
xf_=[]
y_=[]
categ_=[]
mask_=[]
classOffset_=[]
nClasses_=[]
nPoints_=[]
np_random=np.random.RandomState([x[-1] for x in tbl])
for _, xl, y, categ, classOffset, nClasses, idx in tbl:
m=np.eye(3,dtype='float32')
m[0,0]*=np_random.randint(0,2)*2-1
m=np.dot(m,np.linalg.qr(np_random.randn(3,3))[0])
xl=np.dot(xl,m)
xl+=np_random.uniform(-1,1,(1,3)).astype('float32')
xl=np.floor(resolution*(4+xl)).astype('int64')
xf=np.ones((xl.shape[0],1)).astype('float32')
xl_.append(xl)
xf_.append(xf)
y_.append(y)
categ_.append(np.ones(y.shape[0],dtype='int64')*categ)
classOffset_.append(classOffset)
nClasses_.append(nClasses)
mask=np.zeros((y.shape[0],nClassesTotal),dtype='float32')
mask[:,classOffset:classOffset+nClasses]=1
mask_.append(mask)
nPoints_.append(y.shape[0])
xl_=[np.hstack([x,idx*np.ones((x.shape[0],1),dtype='int64')]) for idx,x in enumerate(xl_)]
return {'x': [torch.from_numpy(np.vstack(xl_)),torch.from_numpy(np.vstack(xf_))],
'y': torch.from_numpy(np.hstack(y_)),
'categ': torch.from_numpy(np.hstack(categ_)),
'classOffset': classOffset_,
'nClasses': nClasses_,
'mask': torch.from_numpy(np.vstack(mask_)),
'xf': [x[0] for x in tbl],
'nPoints': nPoints_}
return torch.utils.data.DataLoader(d,batch_size=batchSize, collate_fn=merge, num_workers=10, shuffle=True)
def valid():
d=[]
if categ==-1:
for c in range(16):
for x in torch.utils.data.DataLoader(
glob.glob('train_val/'+categories[c]+'/*.pts.valid'),
collate_fn=lambda x: load(x, c, classOffsets[c],nClasses[c]),
num_workers=12):
d.append(x)
else:
for x in torch.utils.data.DataLoader(
glob.glob('train_val/'+categories[categ]+'/*.pts.valid'),
collate_fn=lambda x: load(x, categ, 0, nClasses[categ]),
num_workers=12):
d.append(x)
print(len(d))
def merge(tbl):
xl_=[]
xf_=[]
y_=[]
categ_=[]
mask_=[]
classOffset_=[]
nClasses_=[]
nPoints_=[]
np_random=np.random.RandomState([x[-1] for x in tbl])
for _, xl, y, categ, classOffset, nClasses, idx in tbl:
m=np.eye(3,dtype='float32')
m[0,0]*=np_random.randint(0,2)*2-1
m=np.dot(m,np.linalg.qr(np_random.randn(3,3))[0])
xl=np.dot(xl,m)
xl+=np_random.uniform(-1,1,(1,3)).astype('float32')
xl=np.floor(resolution*(4+xl)).astype('int64')
xl_.append(xl)
xf=np.ones((xl.shape[0],1)).astype('float32')
xf_.append(xf)
y_.append(y)
categ_.append(np.ones(y.shape[0],dtype='int64')*categ)
classOffset_.append(classOffset)
nClasses_.append(nClasses)
mask=np.zeros((y.shape[0],nClassesTotal),dtype='float32')
mask[:,classOffset:classOffset+nClasses]=1
mask_.append(mask)
nPoints_.append(y.shape[0])
xl_=[np.hstack([x,idx*np.ones((x.shape[0],1),dtype='int64')]) for idx,x in enumerate(xl_)]
return {'x': [torch.from_numpy(np.vstack(xl_)),torch.from_numpy(np.vstack(xf_))],
'y': torch.from_numpy(np.hstack(y_)),
'categ': torch.from_numpy(np.hstack(categ_)),
'classOffset': classOffset_,
'nClasses': nClasses_,
'mask': torch.from_numpy(np.vstack(mask_)),
'xf': [x[0] for x in tbl],
'nPoints': nPoints_}
return torch.utils.data.DataLoader(d,batch_size=batchSize, collate_fn=merge, num_workers=10, shuffle=True)
# 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
#Download https://shapenet.cs.stanford.edu/iccv17/ competition data.
#We re-split the Train/Validation data 50-50 to increase the size of the validation set.
wget https://shapenet.cs.stanford.edu/iccv17/partseg/train_data.zip
wget https://shapenet.cs.stanford.edu/iccv17/partseg/train_label.zip
wget https://shapenet.cs.stanford.edu/iccv17/partseg/val_data.zip
wget https://shapenet.cs.stanford.edu/iccv17/partseg/val_label.zip
wget https://shapenet.cs.stanford.edu/iccv17/partseg/test_data.zip
wget https://shapenet.cs.stanford.edu/iccv17/partseg/test_label.zip
unzip train_data.zip
unzip train_label.zip
unzip val_data
unzip val_label
unzip test_data.zip
unzip test_label.zip
for x in train_val test; do
for y in 02691156 02773838 02954340 02958343 03001627 03261776 03467517 03624134 03636649 03642806 03790512 03797390 03948459 04099429 04225987 04379243; do
mkdir -p $x/$y
done
done
for x in 02691156 02773838 02954340 02958343 03001627 03261776 03467517 03624134 03636649 03642806 03790512 03797390 03948459 04099429 04225987 04379243; do
mv train_*/$x/* val_*/$x/* train_val/$x/; cp test_*/$x/* test/$x/
done
rm -rf train_data train_label val_data val_label test_data test_label
for x in train_val/*/*.pts; do
y=`md5sum $x|cut -c 1|tr -d 89abcdef`
if [ $y ]; then
mv $x $x.train
else
mv $x $x.valid
fi
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.
import torch, data
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import sparseconvnet as scn
import time
import os, sys
import math
import numpy as np
data.init(-1,24,24*8+15,16)
dimension = 3
reps = 2 #Conv block repetition factor
m = 32 #Unet number of features
nPlanes = [m, 2*m, 3*m, 4*m, 5*m] #UNet number of features per level
class Model(nn.Module):
def __init__(self):
nn.Module.__init__(self)
self.sparseModel = scn.Sequential().add(
scn.InputLayer(dimension, data.spatialSize, mode=3)).add(
scn.SubmanifoldConvolution(dimension, 1, m, 3, False)).add(
scn.FullyConvolutionalNet(dimension, reps, nPlanes, residual_blocks=False, downsample=[3,2])).add(
scn.BatchNormReLU(sum(nPlanes))).add(
scn.OutputLayer(dimension))
self.linear = nn.Linear(sum(nPlanes), data.nClassesTotal)
def forward(self,x):
x=self.sparseModel(x)
x=self.linear(x)
return x
model=Model()
print(model)
trainIterator=data.train()
validIterator=data.valid()
criterion = nn.CrossEntropyLoss()
p={}
p['n_epochs'] = 100
p['initial_lr'] = 1e-1
p['lr_decay'] = 4e-2
p['weight_decay'] = 1e-4
p['momentum'] = 0.9
p['check_point'] = True
p['use_gpu'] = torch.cuda.is_available()
dtype = 'torch.cuda.FloatTensor' if p['use_gpu'] else 'torch.FloatTensor'
dtypei = 'torch.cuda.LongTensor' if p['use_gpu'] else 'torch.LongTensor'
if p['use_gpu']:
model.cuda()
criterion.cuda()
optimizer = optim.SGD(model.parameters(),
lr=p['initial_lr'],
momentum = p['momentum'],
weight_decay = p['weight_decay'],
nesterov=True)
if p['check_point'] and os.path.isfile('epoch.pth'):
p['epoch'] = torch.load('epoch.pth') + 1
print('Restarting at epoch ' +
str(p['epoch']) +
' from model.pth ..')
model.load_state_dict(torch.load('model.pth'))
else:
p['epoch']=1
print(p)
print('#parameters', sum([x.nelement() for x in model.parameters()]))
def store(stats,batch,predictions,loss):
ctr=0
for nP,f,classOffset,nClasses in zip(batch['nPoints'],batch['xf'],batch['classOffset'],batch['nClasses']):
categ,f=f.split('/')[-2:]
if not categ in stats:
stats[categ]={}
if not f in stats[categ]:
stats[categ][f]={'p': 0, 'y': 0}
#print(predictions[ctr:ctr+nP,classOffset:classOffset+nClasses].abs().max().item())
stats[categ][f]['p']+=predictions.detach()[ctr:ctr+nP,classOffset:classOffset+nClasses].cpu().numpy()
stats[categ][f]['y']=batch['y'].detach()[ctr:ctr+nP].cpu().numpy()-classOffset
ctr+=nP
def inter(pred, gt, label):
assert pred.size == gt.size, 'Predictions incomplete!'
return np.sum(np.logical_and(pred.astype('int') == label, gt.astype('int') == label))
def union(pred, gt, label):
assert pred.size == gt.size, 'Predictions incomplete!'
return np.sum(np.logical_or(pred.astype('int') == label, gt.astype('int') == label))
def iou(stats):
eps = sys.float_info.epsilon
categories= sorted(stats.keys())
ncategory = len(categories)
iou_all = np.zeros(ncategory)
nmodels = np.zeros(ncategory, dtype='int')
for i, categ in enumerate(categories):
nmodels[i] = len(stats[categ])
pred = []
gt = []
for j in stats[categ].values():
pred.append(j['p'].argmax(1))
gt.append(j['y'])
npart = np.max(np.concatenate(gt))+1
iou_per_part = np.zeros((len(pred), npart))
# loop over parts
for j in range(npart):
# loop over CAD models
for k in range(len(pred)):
p = pred[k]
iou_per_part[k, j] = (inter(p, gt[k], j+1) + eps) / (union(p, gt[k], j+1) + eps)
# average over CAD models and parts
iou_all[i] = np.mean(iou_per_part)
# weighted average over categories
iou_weighted_ave = np.sum(iou_all * nmodels) / np.sum(nmodels)
return {'iou': iou_weighted_ave, 'nmodels_sum': nmodels.sum(), 'iou_all': iou_all}
for epoch in range(p['epoch'], p['n_epochs'] + 1):
model.train()
stats = {}
for param_group in optimizer.param_groups:
param_group['lr'] = p['initial_lr'] * \
math.exp((1 - epoch) * p['lr_decay'])
scn.forward_pass_multiplyAdd_count=0
scn.forward_pass_hidden_states=0
start = time.time()
for batch in trainIterator:
optimizer.zero_grad()
batch['x'][1]=batch['x'][1].type(dtype)
batch['y']=batch['y'].type(dtypei)
batch['mask']=batch['mask'].type(dtype)
predictions=model(batch['x'])
loss = criterion.forward(predictions,batch['y'])
store(stats,batch,predictions,loss)
loss.backward()
optimizer.step()
r = iou(stats)
print('train epoch',epoch,1,'iou=', r['iou'], 'MegaMulAdd=',scn.forward_pass_multiplyAdd_count/r['nmodels_sum']/1e6, 'MegaHidden',scn.forward_pass_hidden_states/r['nmodels_sum']/1e6,'time=',time.time() - start,'s')
if p['check_point']:
torch.save(epoch, 'epoch.pth')
torch.save(model.state_dict(),'model.pth')
if epoch in [10,30,100]:
model.eval()
stats = {}
scn.forward_pass_multiplyAdd_count=0
scn.forward_pass_hidden_states=0
start = time.time()
for rep in range(1,1+3):
for batch in validIterator:
batch['x'][1]=batch['x'][1].type(dtype)
batch['y']=batch['y'].type(dtypei)
batch['mask']=batch['mask'].type(dtype)
predictions=model(batch['x'])
loss = criterion.forward(predictions,batch['y'])
store(stats,batch,predictions,loss)
r = iou(stats)
print('valid epoch',epoch,rep,'iou=', r['iou'], 'MegaMulAdd=',scn.forward_pass_multiplyAdd_count/r['nmodels_sum']/1e6, 'MegaHidden',scn.forward_pass_hidden_states/r['nmodels_sum']/1e6,'time=',time.time() - start,'s')
print(r['iou_all'])
# 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, data
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import sparseconvnet as scn
import time
import os, sys
import math
import numpy as np
data.init(-1,24,24*8+15,16)
dimension = 3
reps = 2 #Conv block repetition factor
m = 32 #Unet number of features
nPlanes = [m, 2*m, 3*m, 4*m, 5*m] #UNet number of features per level
class Model(nn.Module):
def __init__(self):
nn.Module.__init__(self)
self.sparseModel = scn.Sequential().add(
scn.InputLayer(dimension, data.spatialSize, mode=3)).add(
scn.SubmanifoldConvolution(dimension, 1, m, 3, False)).add(
scn.UNet(dimension, reps, nPlanes, residual_blocks=False, downsample=[3,2])).add(
scn.BatchNormReLU(m)).add(
scn.OutputLayer(dimension))
self.linear = nn.Linear(m, data.nClassesTotal)
def forward(self,x):
x=self.sparseModel(x)
x=self.linear(x)
return x
model=Model()
print(model)
trainIterator=data.train()
validIterator=data.valid()
criterion = nn.CrossEntropyLoss()
p={}
p['n_epochs'] = 100
p['initial_lr'] = 1e-1
p['lr_decay'] = 4e-2
p['weight_decay'] = 1e-4
p['momentum'] = 0.9
p['check_point'] = True
p['use_gpu'] = torch.cuda.is_available()
dtype = 'torch.cuda.FloatTensor' if p['use_gpu'] else 'torch.FloatTensor'
dtypei = 'torch.cuda.LongTensor' if p['use_gpu'] else 'torch.LongTensor'
if p['use_gpu']:
model.cuda()
criterion.cuda()
optimizer = optim.SGD(model.parameters(),
lr=p['initial_lr'],
momentum = p['momentum'],
weight_decay = p['weight_decay'],
nesterov=True)
if p['check_point'] and os.path.isfile('epoch.pth'):
p['epoch'] = torch.load('epoch.pth') + 1
print('Restarting at epoch ' +
str(p['epoch']) +
' from model.pth ..')
model.load_state_dict(torch.load('model.pth'))
else:
p['epoch']=1
print(p)
print('#parameters', sum([x.nelement() for x in model.parameters()]))
def store(stats,batch,predictions,loss):
ctr=0
for nP,f,classOffset,nClasses in zip(batch['nPoints'],batch['xf'],batch['classOffset'],batch['nClasses']):
categ,f=f.split('/')[-2:]
if not categ in stats:
stats[categ]={}
if not f in stats[categ]:
stats[categ][f]={'p': 0, 'y': 0}
#print(predictions[ctr:ctr+nP,classOffset:classOffset+nClasses].abs().max().item())
stats[categ][f]['p']+=predictions.detach()[ctr:ctr+nP,classOffset:classOffset+nClasses].cpu().numpy()
stats[categ][f]['y']=batch['y'].detach()[ctr:ctr+nP].cpu().numpy()-classOffset
ctr+=nP
def inter(pred, gt, label):
assert pred.size == gt.size, 'Predictions incomplete!'
return np.sum(np.logical_and(pred.astype('int') == label, gt.astype('int') == label))
def union(pred, gt, label):
assert pred.size == gt.size, 'Predictions incomplete!'
return np.sum(np.logical_or(pred.astype('int') == label, gt.astype('int') == label))
def iou(stats):
eps = sys.float_info.epsilon
categories= sorted(stats.keys())
ncategory = len(categories)
iou_all = np.zeros(ncategory)
nmodels = np.zeros(ncategory, dtype='int')
for i, categ in enumerate(categories):
nmodels[i] = len(stats[categ])
pred = []
gt = []
for j in stats[categ].values():
pred.append(j['p'].argmax(1))
gt.append(j['y'])
npart = np.max(np.concatenate(gt))+1
iou_per_part = np.zeros((len(pred), npart))
# loop over parts
for j in range(npart):
# loop over CAD models
for k in range(len(pred)):
p = pred[k]
iou_per_part[k, j] = (inter(p, gt[k], j+1) + eps) / (union(p, gt[k], j+1) + eps)
# average over CAD models and parts
iou_all[i] = np.mean(iou_per_part)
# weighted average over categories
iou_weighted_ave = np.sum(iou_all * nmodels) / np.sum(nmodels)
return {'iou': iou_weighted_ave, 'nmodels_sum': nmodels.sum(), 'iou_all': iou_all}
for epoch in range(p['epoch'], p['n_epochs'] + 1):
model.train()
stats = {}
for param_group in optimizer.param_groups:
param_group['lr'] = p['initial_lr'] * \
math.exp((1 - epoch) * p['lr_decay'])
scn.forward_pass_multiplyAdd_count=0
scn.forward_pass_hidden_states=0
start = time.time()
for batch in trainIterator:
optimizer.zero_grad()
batch['x'][1]=batch['x'][1].type(dtype)
batch['y']=batch['y'].type(dtypei)
batch['mask']=batch['mask'].type(dtype)
predictions=model(batch['x'])
loss = criterion.forward(predictions,batch['y'])
store(stats,batch,predictions,loss)
loss.backward()
optimizer.step()
r = iou(stats)
print('train epoch',epoch,1,'iou=', r['iou'], 'MegaMulAdd=',scn.forward_pass_multiplyAdd_count/r['nmodels_sum']/1e6, 'MegaHidden',scn.forward_pass_hidden_states/r['nmodels_sum']/1e6,'time=',time.time() - start,'s')
if p['check_point']:
torch.save(epoch, 'epoch.pth')
torch.save(model.state_dict(),'model.pth')
if epoch in [10,30,100]:
model.eval()
stats = {}
scn.forward_pass_multiplyAdd_count=0
scn.forward_pass_hidden_states=0
start = time.time()
for rep in range(1,1+3):
for batch in validIterator:
batch['x'][1]=batch['x'][1].type(dtype)
batch['y']=batch['y'].type(dtypei)
batch['mask']=batch['mask'].type(dtype)
predictions=model(batch['x'])
loss = criterion.forward(predictions,batch['y'])
store(stats,batch,predictions,loss)
r = iou(stats)
print('valid epoch',epoch,rep,'iou=', r['iou'], 'MegaMulAdd=',scn.forward_pass_multiplyAdd_count/r['nmodels_sum']/1e6, 'MegaHidden',scn.forward_pass_hidden_states/r['nmodels_sum']/1e6,'time=',time.time() - start,'s')
print(r['iou_all'])
-- 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.SubmanifoldConvolution(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 get_iterators
# 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.SubmanifoldConvolution(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 = get_iterators(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.SubmanifoldConvolution(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 get_iterators
# 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.SubmanifoldConvolution(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 = get_iterators(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 get_iterators
# 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 = get_iterators(spatial_size, 63, 3)
scn.ClassificationTrainValidate(model,
dataset,
{'nEpochs': 100,
'initial_LR': 0.1,
'LR_decay': 0.05,
'weightDecay': 1e-4,
'checkPoint': False})
-- 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
......@@ -6,7 +6,7 @@
import torch
import torchnet
import sparseconvnet.legacy as scn
import sparseconvnet as scn
import pickle
import math
import random
......
-- 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.
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.SubmanifoldConvolution(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 get_iterators
# 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.SubmanifoldConvolution(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 = get_iterators(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.SubmanifoldConvolution(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.SubmanifoldConvolution(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})
......@@ -5,36 +5,45 @@
# LICENSE file in the root directory of this source tree.
import torch
import torch.legacy.nn as nn
import sparseconvnet.legacy as scn
import torch.nn as nn
import sparseconvnet as scn
from data import get_iterators
# 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.SubmanifoldConvolution(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)
class Model(nn.Module):
def __init__(self):
nn.Module.__init__(self)
self.sparseModel = scn.Sequential(
).add(scn.SubmanifoldConvolution(2, 3, 16, 3, False)
).add(scn.MaxPooling(2, 3, 2)
).add(scn.SparseResNet(2, 16, [
['b', 16, 2, 1],
['b', 32, 2, 2],
['b', 48, 2, 2],
['b', 96, 2, 2]])
).add(scn.Convolution(2, 96, 128, 5, 1, False)
).add(scn.BatchNormReLU(128)
).add(scn.SparseToDense(2, 128))
self.linear = nn.Linear(128, 3755)
def forward(self, x):
x = self.sparseModel(x)
x = x.view(-1, 128)
x = self.linear(x)
return x
model = Model()
spatial_size = model.sparseModel.input_spatial_size(torch.LongTensor([1, 1]))
print('Input spatial size:', spatial_size)
dataset = get_iterators(spatial_size, 63, 3)
scn.ClassificationTrainValidate(
model, dataset,
{'nEpochs': 100, 'initial_LR': 0.1, 'LR_decay': 0.05, 'weightDecay': 1e-4})
{'n_epochs': 100,
'initial_lr': 0.1,
'lr_decay': 0.05,
'weight_decay': 1e-4,
'use_gpu': torch.cuda.is_available(),
'check_point': True, })
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