Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
SparseConvNet
Commits
1df7b845
Commit
1df7b845
authored
May 14, 2018
by
Benjamin Thomas Graham
Browse files
3d segmantation
parent
f2e3800b
Changes
204
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
918 additions
and
55 deletions
+918
-55
sparseconvnet/batchNormalization.py
sparseconvnet/batchNormalization.py
+74
-3
sparseconvnet/classificationTrainValidate.py
sparseconvnet/classificationTrainValidate.py
+2
-2
sparseconvnet/convolution.py
sparseconvnet/convolution.py
+4
-11
sparseconvnet/deconvolution.py
sparseconvnet/deconvolution.py
+4
-4
sparseconvnet/denseToSparse.py
sparseconvnet/denseToSparse.py
+1
-1
sparseconvnet/dropout.py
sparseconvnet/dropout.py
+0
-0
sparseconvnet/fullConvolution.py
sparseconvnet/fullConvolution.py
+136
-0
sparseconvnet/identity.py
sparseconvnet/identity.py
+0
-0
sparseconvnet/inputBatch.py
sparseconvnet/inputBatch.py
+0
-0
sparseconvnet/ioLayers.py
sparseconvnet/ioLayers.py
+72
-25
sparseconvnet/maxPooling.py
sparseconvnet/maxPooling.py
+2
-4
sparseconvnet/metadata.py
sparseconvnet/metadata.py
+0
-0
sparseconvnet/networkArchitectures.py
sparseconvnet/networkArchitectures.py
+315
-0
sparseconvnet/networkInNetwork.py
sparseconvnet/networkInNetwork.py
+2
-2
sparseconvnet/randomizedStrideConvolution.py
sparseconvnet/randomizedStrideConvolution.py
+151
-0
sparseconvnet/randomizedStrideMaxPooling.py
sparseconvnet/randomizedStrideMaxPooling.py
+117
-0
sparseconvnet/sequential.py
sparseconvnet/sequential.py
+0
-0
sparseconvnet/sparseConvNetTensor.py
sparseconvnet/sparseConvNetTensor.py
+0
-0
sparseconvnet/sparseToDense.py
sparseconvnet/sparseToDense.py
+1
-3
sparseconvnet/sparsify.py
sparseconvnet/sparsify.py
+37
-0
No files found.
PyTorch/
sparseconvnet/batchNormalization.py
→
sparseconvnet/batchNormalization.py
View file @
1df7b845
...
@@ -44,7 +44,7 @@ class BatchNormalization(Module):
...
@@ -44,7 +44,7 @@ class BatchNormalization(Module):
self
.
bias
=
None
self
.
bias
=
None
def
forward
(
self
,
input
):
def
forward
(
self
,
input
):
assert
input
.
features
.
n
dimension
()
==
0
or
input
.
features
.
size
(
1
)
==
self
.
nPlanes
assert
input
.
features
.
n
element
()
==
0
or
input
.
features
.
size
(
1
)
==
self
.
nPlanes
output
=
SparseConvNetTensor
()
output
=
SparseConvNetTensor
()
output
.
metadata
=
input
.
metadata
output
.
metadata
=
input
.
metadata
output
.
spatial_size
=
input
.
spatial_size
output
.
spatial_size
=
input
.
spatial_size
...
@@ -164,7 +164,78 @@ class BatchNormalizationFunction(Function):
...
@@ -164,7 +164,78 @@ class BatchNormalizationFunction(Function):
runningVar
,
runningVar
,
weight
if
weight
is
not
None
else
nullptr
,
weight
if
weight
is
not
None
else
nullptr
,
bias
if
bias
is
not
None
else
nullptr
,
bias
if
bias
is
not
None
else
nullptr
,
grad_weight
.
data
if
grad_weight
is
not
None
else
nullptr
,
grad_weight
if
grad_weight
is
not
None
else
nullptr
,
grad_bias
.
data
if
grad_bias
is
not
None
else
nullptr
,
grad_bias
if
grad_bias
is
not
None
else
nullptr
,
ctx
.
leakiness
)
ctx
.
leakiness
)
return
grad_input
,
grad_weight
,
grad_bias
,
None
,
None
,
None
,
None
,
None
,
None
return
grad_input
,
grad_weight
,
grad_bias
,
None
,
None
,
None
,
None
,
None
,
None
#
#
# class BatchNormalization(Module):
# """
# Parameters:
# nPlanes : number of input planes
# eps : small number used to stabilise standard deviation calculation
# momentum : for calculating running average for testing (default 0.9)
# affine : only 'true' is supported at present (default 'true')
# noise : add multiplicative and additive noise during training if >0.
# leakiness : Apply activation def inplace: 0<=leakiness<=1.
# 0 for ReLU, values in (0,1) for LeakyReLU, 1 for no activation def.
# """
# def __init__(
# self,
# nPlanes,
# eps=1e-4,
# momentum=0.9,
# affine=True,
# leakiness=1):
# Module.__init__(self)
# self.nPlanes = nPlanes
# self.eps = eps
# self.momentum = momentum
# self.affine = affine
# self.leakiness = leakiness
# self.register_buffer("runningMean", torch.Tensor(nPlanes).fill_(0))
# self.register_buffer("runningVar", torch.Tensor(nPlanes).fill_(1))
# if affine:
# self.weight = Parameter(torch.Tensor(nPlanes).fill_(1))
# self.bias = Parameter(torch.Tensor(nPlanes).fill_(0))
# else:
# self.weight = None
# self.bias = None
#
# def forward(self, input):
# output = SparseConvNetTensor()
# output.metadata = input.metadata
# output.spatial_size = input.spatial_size
# if input.features.ndimension() == 0:
# output.features = input.features
# else:
# output.features = input.features - input.features.mean(0, keepdim=True)
# if self.leakiness != 1:
# output.features = torch.nn.functional.leaky_relu(output.features, self.leakiness)
# return output
#
# def input_spatial_size(self, out_size):
# return out_size
#
# def __repr__(self):
# return str(self.bn)
#
# class BatchNormReLU(BatchNormalization):
# def __init__(self, nPlanes, eps=1e-4, momentum=0.9):
# BatchNormalization.__init__(self, nPlanes, eps, momentum, True, 0)
#
# def __repr__(self):
# s = 'BatchNormReLU(' + str(self.nPlanes) + ',eps=' + str(self.eps) + \
# ',momentum=' + str(self.momentum) + ',affine=' + str(self.affine) + ')'
# return s
#
#
# class BatchNormLeakyReLU(BatchNormalization):
# def __init__(self, nPlanes, eps=1e-4, momentum=0.9):
# BatchNormalization.__init__(self, nPlanes, eps, momentum, True, 0.333)
#
# def __repr__(self):
# s = 'BatchNormReLU(' + str(self.nPlanes) + ',eps=' + str(self.eps) + \
# ',momentum=' + str(self.momentum) + ',affine=' + str(self.affine) + ')'
# return s
PyTorch/
sparseconvnet/classificationTrainValidate.py
→
sparseconvnet/classificationTrainValidate.py
View file @
1df7b845
...
@@ -36,7 +36,7 @@ def updateStats(stats, output, target, loss):
...
@@ -36,7 +36,7 @@ def updateStats(stats, output, target, loss):
# Top-5 score
# Top-5 score
l
=
min
(
5
,
correct
.
size
(
1
))
l
=
min
(
5
,
correct
.
size
(
1
))
stats
[
'top5'
]
+=
correct
[:,
:
l
].
long
().
sum
().
item
()
stats
[
'top5'
]
+=
correct
[:,
:
l
].
long
().
sum
().
item
()
stats
[
'confusion matrix'
].
index_add_
(
0
,
target
,
F
.
softmax
(
output
,
1
).
d
a
ta
)
stats
[
'confusion matrix'
].
index_add_
(
0
,
target
,
F
.
softmax
(
output
,
1
).
d
e
ta
ch
()
)
def
ClassificationTrainValidate
(
model
,
dataset
,
p
):
def
ClassificationTrainValidate
(
model
,
dataset
,
p
):
...
@@ -150,7 +150,7 @@ def ClassificationTrainValidate(model, dataset, p):
...
@@ -150,7 +150,7 @@ def ClassificationTrainValidate(model, dataset, p):
batch
[
'idx'
]
=
batch
[
'idx'
].
cuda
()
batch
[
'idx'
]
=
batch
[
'idx'
].
cuda
()
batch
[
'input'
].
to_variable
()
batch
[
'input'
].
to_variable
()
output
=
model
(
batch
[
'input'
])
output
=
model
(
batch
[
'input'
])
pr
.
append
(
output
.
d
a
ta
)
pr
.
append
(
output
.
d
e
ta
ch
()
)
ta
.
append
(
batch
[
'target'
])
ta
.
append
(
batch
[
'target'
])
idxs
.
append
(
batch
[
'idx'
])
idxs
.
append
(
batch
[
'idx'
])
pr
=
torch
.
cat
(
pr
,
0
)
pr
=
torch
.
cat
(
pr
,
0
)
...
...
PyTorch/
sparseconvnet/convolution.py
→
sparseconvnet/convolution.py
View file @
1df7b845
...
@@ -27,12 +27,6 @@ class ConvolutionFunction(Function):
...
@@ -27,12 +27,6 @@ class ConvolutionFunction(Function):
output_features
=
input_features
.
new
()
output_features
=
input_features
.
new
()
ctx
.
input_metadata
=
input_metadata
ctx
.
input_metadata
=
input_metadata
ctx
.
dimension
=
dimension
ctx
.
dimension
=
dimension
# ctx.weight=weight
# ctx.bias=bias
# ctx.output_spatial_size=output_spatial_size
# ctx.filter_size=filter_size
# ctx.filter_stride=filter_stride
# bias??
ctx
.
save_for_backward
(
ctx
.
save_for_backward
(
input_features
,
input_features
,
input_spatial_size
,
input_spatial_size
,
...
@@ -53,8 +47,7 @@ class ConvolutionFunction(Function):
...
@@ -53,8 +47,7 @@ class ConvolutionFunction(Function):
output_features
,
output_features
,
weight
,
weight
,
bias
if
bias
is
not
None
else
nullptr
,
bias
if
bias
is
not
None
else
nullptr
,
0
,
# remove this parameter!!
0
)
# remove this parameter!!
torch
.
cuda
.
IntTensor
()
if
input_features
.
is_cuda
else
nullptr
)
sparseconvnet
.
forward_pass_hidden_states
+=
output_features
.
nelement
()
sparseconvnet
.
forward_pass_hidden_states
+=
output_features
.
nelement
()
return
output_features
return
output_features
...
@@ -79,9 +72,9 @@ class ConvolutionFunction(Function):
...
@@ -79,9 +72,9 @@ class ConvolutionFunction(Function):
grad_output
.
contiguous
(),
grad_output
.
contiguous
(),
weight
,
weight
,
grad_weight
,
grad_weight
,
grad_bias
.
data
if
grad_bias
is
not
None
else
nullptr
,
grad_bias
if
grad_bias
is
not
None
else
nullptr
,
0
,
# remove this parameter
0
,
# remove this parameter
torch
.
cuda
.
IntTensor
()
if
input_features
.
is_cuda
else
nullptr
)
)
return
grad_input
,
grad_weight
,
grad_bias
,
None
,
None
,
None
,
None
,
None
,
None
return
grad_input
,
grad_weight
,
grad_bias
,
None
,
None
,
None
,
None
,
None
,
None
...
@@ -105,7 +98,7 @@ class Convolution(Module):
...
@@ -105,7 +98,7 @@ class Convolution(Module):
self
.
bias
=
None
self
.
bias
=
None
def
forward
(
self
,
input
):
def
forward
(
self
,
input
):
assert
input
.
features
.
n
dimension
()
==
0
or
input
.
features
.
size
(
1
)
==
self
.
nIn
assert
input
.
features
.
n
element
()
==
0
or
input
.
features
.
size
(
1
)
==
self
.
nIn
output
=
SparseConvNetTensor
()
output
=
SparseConvNetTensor
()
output
.
metadata
=
input
.
metadata
output
.
metadata
=
input
.
metadata
output
.
spatial_size
=
\
output
.
spatial_size
=
\
...
...
PyTorch/
sparseconvnet/deconvolution.py
→
sparseconvnet/deconvolution.py
View file @
1df7b845
...
@@ -41,7 +41,7 @@ class DeconvolutionFunction(Function):
...
@@ -41,7 +41,7 @@ class DeconvolutionFunction(Function):
weight
,
weight
,
bias
if
bias
is
not
None
else
nullptr
,
bias
if
bias
is
not
None
else
nullptr
,
0
,
# remove this parameter!!
0
,
# remove this parameter!!
torch
.
cuda
.
IntTensor
()
if
input_features
.
is_cuda
else
nullptr
)
)
sparseconvnet
.
forward_pass_hidden_states
+=
output_features
.
nelement
()
sparseconvnet
.
forward_pass_hidden_states
+=
output_features
.
nelement
()
ctx
.
save_for_backward
(
input_features
,
ctx
.
save_for_backward
(
input_features
,
output_features
,
output_features
,
...
@@ -81,9 +81,9 @@ class DeconvolutionFunction(Function):
...
@@ -81,9 +81,9 @@ class DeconvolutionFunction(Function):
grad_output
.
contiguous
(),
grad_output
.
contiguous
(),
weight
,
weight
,
grad_weight
,
grad_weight
,
grad_bias
.
data
if
grad_bias
is
not
None
else
nullptr
,
grad_bias
if
grad_bias
is
not
None
else
nullptr
,
0
,
# remove this parameter
0
,
# remove this parameter
torch
.
cuda
.
IntTensor
()
if
input_features
.
is_cuda
else
nullptr
)
)
return
grad_input
,
grad_weight
,
grad_bias
,
None
,
None
,
None
,
None
,
None
,
None
return
grad_input
,
grad_weight
,
grad_bias
,
None
,
None
,
None
,
None
,
None
,
None
...
@@ -107,7 +107,7 @@ class Deconvolution(Module):
...
@@ -107,7 +107,7 @@ class Deconvolution(Module):
self
.
bias
=
None
self
.
bias
=
None
def
forward
(
self
,
input
):
def
forward
(
self
,
input
):
assert
input
.
features
.
n
dimension
()
==
0
or
input
.
features
.
size
(
1
)
==
self
.
nIn
assert
input
.
features
.
n
element
()
==
0
or
input
.
features
.
size
(
1
)
==
self
.
nIn
output
=
SparseConvNetTensor
()
output
=
SparseConvNetTensor
()
output
.
metadata
=
input
.
metadata
output
.
metadata
=
input
.
metadata
output
.
spatial_size
=
\
output
.
spatial_size
=
\
...
...
PyTorch/
sparseconvnet/denseToSparse.py
→
sparseconvnet/denseToSparse.py
View file @
1df7b845
...
@@ -73,7 +73,7 @@ class DenseToSparseFunction(Function):
...
@@ -73,7 +73,7 @@ class DenseToSparseFunction(Function):
print
(
r
)
print
(
r
)
print
(
grad_output
)
print
(
grad_output
)
grad_input
=
grad_output
.
new
().
resize_
(
grad_input
=
grad_output
.
new
().
resize_
(
ctx
.
aas2
).
zero_
().
index_copy_
(
0
,
r
,
grad_output
.
data
)
ctx
.
aas2
).
zero_
().
index_copy_
(
0
,
r
,
grad_output
)
grad_input
=
grad_input
.
view
(
ctx
.
aas
).
permute
(
grad_input
=
grad_input
.
view
(
ctx
.
aas
).
permute
(
*
([
0
,
ctx
.
dimension
+
1
]
+
list
(
range
(
1
,
ctx
.
dimension
+
1
))))
*
([
0
,
ctx
.
dimension
+
1
]
+
list
(
range
(
1
,
ctx
.
dimension
+
1
))))
return
grad_input
,
None
,
None
,
None
return
grad_input
,
None
,
None
,
None
PyTorch/
sparseconvnet/dropout.py
→
sparseconvnet/dropout.py
View file @
1df7b845
File moved
sparseconvnet/fullConvolution.py
0 → 100644
View file @
1df7b845
# 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
sparseconvnet
from
torch.autograd
import
Function
,
Variable
from
torch.nn
import
Module
,
Parameter
from
.utils
import
*
from
.sparseConvNetTensor
import
SparseConvNetTensor
from
.metadata
import
Metadata
class
FullConvolutionFunction
(
Function
):
@
staticmethod
def
forward
(
ctx
,
input_features
,
weight
,
bias
,
input_metadata
,
output_metadata
,
input_spatial_size
,
output_spatial_size
,
dimension
,
filter_size
,
filter_stride
):
output_features
=
input_features
.
new
()
ctx
.
input_metadata
=
input_metadata
ctx
.
output_metadata
=
output_metadata
ctx
.
dimension
=
dimension
ctx
.
save_for_backward
(
input_features
,
input_spatial_size
,
weight
,
bias
,
output_spatial_size
,
filter_size
,
filter_stride
)
sparseconvnet
.
forward_pass_multiplyAdd_count
+=
\
dim_typed_fn
(
dimension
,
input_features
,
'FullConvolution_updateOutput'
)(
input_spatial_size
,
output_spatial_size
,
filter_size
,
filter_stride
,
input_metadata
.
ffi
,
output_metadata
.
ffi
,
input_features
,
output_features
,
weight
,
bias
if
bias
is
not
None
else
nullptr
,
0
)
#remove this parameter!!
sparseconvnet
.
forward_pass_hidden_states
+=
output_features
.
nelement
()
return
output_features
@
staticmethod
def
backward
(
ctx
,
grad_output
):
input_features
,
input_spatial_size
,
weight
,
bias
,
output_spatial_size
,
filter_size
,
filter_stride
=
ctx
.
saved_tensors
grad_input
=
grad_output
.
new
()
grad_weight
=
grad_output
.
new
().
resize_as_
(
weight
).
zero_
()
if
bias
is
None
:
grad_bias
=
None
else
:
grad_bias
=
grad_output
.
data
.
new
().
resize_as_
(
bias
).
zero_
()
dim_typed_fn
(
ctx
.
dimension
,
input_features
,
'FullConvolution_backward'
)(
input_spatial_size
,
output_spatial_size
,
filter_size
,
filter_stride
,
ctx
.
input_metadata
.
ffi
,
ctx
.
output_metadata
.
ffi
,
input_features
,
grad_input
,
grad_output
.
contiguous
(),
weight
,
grad_weight
,
grad_bias
if
grad_bias
is
not
None
else
nullptr
,
0
)
#remove this parameter
return
grad_input
,
grad_weight
,
grad_bias
,
None
,
None
,
None
,
None
,
None
,
None
,
None
class
FullConvolution
(
Module
):
def
__init__
(
self
,
dimension
,
nIn
,
nOut
,
filter_size
,
filter_stride
,
bias
):
Module
.
__init__
(
self
)
self
.
dimension
=
dimension
self
.
nIn
=
nIn
self
.
nOut
=
nOut
self
.
filter_size
=
toLongTensor
(
dimension
,
filter_size
)
self
.
filter_volume
=
self
.
filter_size
.
prod
().
item
()
self
.
filter_stride
=
toLongTensor
(
dimension
,
filter_stride
)
std
=
(
2.0
/
nIn
/
self
.
filter_volume
)
**
0.5
self
.
weight
=
Parameter
(
torch
.
Tensor
(
self
.
filter_volume
*
nIn
,
nOut
).
normal_
(
0
,
std
))
if
bias
:
self
.
bias
=
Parameter
(
torch
.
Tensor
(
nOut
).
zero_
())
else
:
self
.
bias
=
None
def
forward
(
self
,
input
):
assert
input
.
features
.
nelement
()
==
0
or
input
.
features
.
size
(
1
)
==
self
.
nIn
output
=
SparseConvNetTensor
()
output
.
metadata
=
Metadata
(
self
.
dimension
)
output
.
spatial_size
=
\
(
input
.
spatial_size
-
1
)
*
self
.
filter_stride
+
self
.
filter_size
output
.
features
=
FullConvolutionFunction
().
apply
(
input
.
features
,
self
.
weight
,
self
.
bias
,
input
.
metadata
,
output
.
metadata
,
input
.
spatial_size
,
output
.
spatial_size
,
self
.
dimension
,
self
.
filter_size
,
self
.
filter_stride
,
)
return
output
def
__repr__
(
self
):
s
=
'FullConvolution '
+
str
(
self
.
nIn
)
+
'->'
+
str
(
self
.
nOut
)
+
' C'
if
self
.
filter_size
.
max
()
==
self
.
filter_size
.
min
()
and
\
self
.
filter_stride
.
max
()
==
self
.
filter_stride
.
min
():
s
=
s
+
str
(
self
.
filter_size
[
0
])
+
'/'
+
str
(
self
.
filter_stride
[
0
])
else
:
s
=
s
+
'('
+
str
(
self
.
filter_size
[
0
])
for
i
in
self
.
filter_size
[
1
:]:
s
=
s
+
','
+
str
(
i
)
s
=
s
+
')/('
+
str
(
self
.
filter_stride
[
0
])
for
i
in
self
.
filter_stride
[
1
:]:
s
=
s
+
','
+
str
(
i
)
s
=
s
+
')'
return
s
def
input_spatial_size
(
self
,
out_size
):
return
(
out_size
-
1
)
*
self
.
filter_stride
+
self
.
filter_size
PyTorch/
sparseconvnet/identity.py
→
sparseconvnet/identity.py
View file @
1df7b845
File moved
PyTorch/
sparseconvnet/inputBatch.py
→
sparseconvnet/inputBatch.py
View file @
1df7b845
File moved
PyTorch/
sparseconvnet/i
nput
Layer.py
→
sparseconvnet/i
o
Layer
s
.py
View file @
1df7b845
...
@@ -10,6 +10,7 @@ from .utils import *
...
@@ -10,6 +10,7 @@ from .utils import *
from
.sparseConvNetTensor
import
SparseConvNetTensor
from
.sparseConvNetTensor
import
SparseConvNetTensor
from
.metadata
import
Metadata
from
.metadata
import
Metadata
class
InputLayer
(
Module
):
class
InputLayer
(
Module
):
"""
"""
Takes a tuple (coords, features, batch_size [optional])
Takes a tuple (coords, features, batch_size [optional])
...
@@ -27,6 +28,7 @@ class InputLayer(Module):
...
@@ -27,6 +28,7 @@ class InputLayer(Module):
some of the batch items are totally empty.
some of the batch items are totally empty.
In case of repetition in coords:
In case of repetition in coords:
mode == 0 if the input is guaranteed to have no duplicates
mode == 1 to use the last item at each spatial location
mode == 1 to use the last item at each spatial location
mode == 2 to keep the first item at each spatial location
mode == 2 to keep the first item at each spatial location
mode == 3 to sum feature vectors sharing one spatial location
mode == 3 to sum feature vectors sharing one spatial location
...
@@ -57,6 +59,30 @@ class InputLayer(Module):
...
@@ -57,6 +59,30 @@ class InputLayer(Module):
return
output
return
output
class
OutputLayer
(
Module
):
"""
Used in conjunction with an InputLayer for 'autoencoder' style networks
Takes a SparseConvNetTensor and results a float Tensor of size
N x n_feature_planes
N is defined by the InputLayer
Behavior during forward-/back-propagation depends on the InputLayer's mode
"""
def
__init__
(
self
,
dimension
):
Module
.
__init__
(
self
)
self
.
dimension
=
dimension
def
forward
(
self
,
input
):
output
=
OutputLayerFunction
.
apply
(
self
.
dimension
,
input
.
metadata
,
input
.
features
)
return
output
class
BLInputLayer
(
Module
):
class
BLInputLayer
(
Module
):
"""
"""
Takes a tuple (coords, features)
Takes a tuple (coords, features)
...
@@ -109,7 +135,7 @@ class BLOutputLayer(Module):
...
@@ -109,7 +135,7 @@ class BLOutputLayer(Module):
batch_size and length are defined by the BLInputLayer
batch_size and length are defined by the BLInputLayer
Behavior during forward-/back-propagation depends on the BLInputLayer's
Module
mode
Behavior during forward-/back-propagation depends on the BLInputLayer's mode
"""
"""
def
__init__
(
self
,
dimension
):
def
__init__
(
self
,
dimension
):
Module
.
__init__
(
self
)
Module
.
__init__
(
self
)
...
@@ -123,6 +149,7 @@ class BLOutputLayer(Module):
...
@@ -123,6 +149,7 @@ class BLOutputLayer(Module):
)
)
return
output
return
output
class
InputLayerFunction
(
Function
):
class
InputLayerFunction
(
Function
):
@
staticmethod
@
staticmethod
def
forward
(
def
forward
(
...
@@ -145,25 +172,52 @@ class InputLayerFunction(Function):
...
@@ -145,25 +172,52 @@ class InputLayerFunction(Function):
input_features
.
contiguous
(),
input_features
.
contiguous
(),
output_features
,
output_features
,
batch_size
,
batch_size
,
mode
,
mode
torch
.
cuda
.
IntTensor
()
if
input_features
.
is_cuda
else
nullptr
)
)
return
output_features
return
output_features
@
staticmethod
@
staticmethod
def
backward
(
ctx
,
grad_output
):
def
backward
(
ctx
,
grad_output
):
grad_input
=
grad_output
.
data
.
new
()
grad_input
=
grad_output
.
new
()
dim_typed_fn
(
dim_typed_fn
(
ctx
.
dimension
,
ctx
.
dimension
,
grad_output
.
data
,
grad_output
,
'InputLayer_updateGradInput'
)(
'InputLayer_updateGradInput'
)(
ctx
.
metadata
.
ffi
,
ctx
.
metadata
.
ffi
,
grad_input
.
data
,
grad_input
,
grad_output
.
contiguous
().
data
,
grad_output
.
contiguous
())
torch
.
cuda
.
IntTensor
()
if
grad_output
.
data
.
is_cuda
else
nullptr
)
return
None
,
None
,
None
,
None
,
grad_input
,
None
,
None
return
None
,
None
,
None
,
None
,
grad_input
,
None
,
None
class
OutputLayerFunction
(
Function
):
@
staticmethod
def
forward
(
ctx
,
dimension
,
metadata
,
input_features
):
output_features
=
input_features
.
new
()
ctx
.
metadata
=
metadata
ctx
.
dimension
=
dimension
dim_typed_fn
(
dimension
,
input_features
,
'OutputLayer_updateOutput'
)(
metadata
.
ffi
,
input_features
.
contiguous
(),
output_features
)
return
output_features
@
staticmethod
def
backward
(
ctx
,
grad_output
):
grad_input
=
grad_output
.
new
()
grad_output
=
grad_output
.
contiguous
()
dim_typed_fn
(
ctx
.
dimension
,
grad_output
,
'OutputLayer_updateGradInput'
)(
ctx
.
metadata
.
ffi
,
grad_input
,
grad_output
.
contiguous
())
return
None
,
None
,
grad_input
class
BLInputLayerFunction
(
Function
):
class
BLInputLayerFunction
(
Function
):
...
@@ -185,28 +239,23 @@ class BLInputLayerFunction(Function):
...
@@ -185,28 +239,23 @@ class BLInputLayerFunction(Function):
coords
,
coords
,
input_features
.
contiguous
(),
input_features
.
contiguous
(),
output_features
,
output_features
,
mode
,
mode
torch
.
cuda
.
IntTensor
()
if
input_features
.
is_cuda
else
nullptr
)
)
return
output_features
return
output_features
@
staticmethod
@
staticmethod
def
backward
(
ctx
,
grad_output
):
def
backward
(
ctx
,
grad_output
):
grad_input
=
grad_output
.
data
.
new
()
grad_input
=
grad_output
.
new
()
dim_typed_fn
(
dim_typed_fn
(
ctx
.
dimension
,
ctx
.
dimension
,
grad_output
.
data
,
grad_output
,
'BLInputLayer_updateGradInput'
)(
'BLInputLayer_updateGradInput'
)(
ctx
.
metadata
.
ffi
,
ctx
.
metadata
.
ffi
,
grad_input
.
data
,
grad_input
,
grad_output
.
contiguous
().
data
,
grad_output
.
contiguous
())
torch
.
cuda
.
IntTensor
()
if
grad_output
.
data
.
is_cuda
else
nullptr
)
return
None
,
None
,
None
,
None
,
grad_input
,
None
return
None
,
None
,
None
,
None
,
grad_input
,
None
class
BLOutputLayerFunction
(
Function
):
class
BLOutputLayerFunction
(
Function
):
@
staticmethod
@
staticmethod
def
forward
(
def
forward
(
...
@@ -220,20 +269,18 @@ class BLOutputLayerFunction(Function):
...
@@ -220,20 +269,18 @@ class BLOutputLayerFunction(Function):
dim_typed_fn
(
dimension
,
input_features
,
'BLOutputLayer_updateOutput'
)(
dim_typed_fn
(
dimension
,
input_features
,
'BLOutputLayer_updateOutput'
)(
metadata
.
ffi
,
metadata
.
ffi
,
input_features
.
contiguous
(),
input_features
.
contiguous
(),
output_features
,
output_features
torch
.
cuda
.
IntTensor
()
if
input_features
.
is_cuda
else
nullptr
)
)
return
output_features
return
output_features
@
staticmethod
@
staticmethod
def
backward
(
ctx
,
grad_output
):
def
backward
(
ctx
,
grad_output
):
grad_input
=
grad_output
.
data
.
new
()
grad_input
=
grad_output
.
new
()
dim_typed_fn
(
dim_typed_fn
(
ctx
.
dimension
,
ctx
.
dimension
,
grad_output
.
data
,
grad_output
,
'BLOutputLayer_updateGradInput'
)(
'BLOutputLayer_updateGradInput'
)(
ctx
.
metadata
.
ffi
,
ctx
.
metadata
.
ffi
,
grad_input
.
data
,
grad_input
,
grad_output
.
contiguous
().
data
,
grad_output
.
contiguous
())
torch
.
cuda
.
IntTensor
()
if
grad_output
.
data
.
is_cuda
else
nullptr
)
return
None
,
None
,
grad_input
return
None
,
None
,
grad_input
PyTorch/
sparseconvnet/maxPooling.py
→
sparseconvnet/maxPooling.py
View file @
1df7b845
...
@@ -34,8 +34,7 @@ class MaxPoolingFunction(Function):
...
@@ -34,8 +34,7 @@ class MaxPoolingFunction(Function):
input_metadata
.
ffi
,
input_metadata
.
ffi
,
input_features
,
input_features
,
output_features
,
output_features
,
nFeaturesToDrop
,
nFeaturesToDrop
)
torch
.
cuda
.
IntTensor
()
if
input_features
.
is_cuda
else
nullptr
)
ctx
.
save_for_backward
(
ctx
.
save_for_backward
(
input_features
,
input_features
,
output_features
,
output_features
,
...
@@ -65,8 +64,7 @@ class MaxPoolingFunction(Function):
...
@@ -65,8 +64,7 @@ class MaxPoolingFunction(Function):
grad_input
,
grad_input
,
output_features
,
output_features
,
grad_output
,
grad_output
,
ctx
.
nFeaturesToDrop
,
ctx
.
nFeaturesToDrop
)
torch
.
cuda
.
IntTensor
()
if
input_features
.
is_cuda
else
nullptr
)
return
grad_input
,
None
,
None
,
None
,
None
,
None
,
None
,
None
return
grad_input
,
None
,
None
,
None
,
None
,
None
,
None
,
None
...
...
PyTorch/
sparseconvnet/metadata.py
→
sparseconvnet/metadata.py
View file @
1df7b845
File moved
sparseconvnet/networkArchitectures.py
0 → 100644
View file @
1df7b845
# 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
sparseconvnet
as
scn
def
SparseVggNet
(
dimension
,
nInputPlanes
,
layers
):
"""
VGG style nets
Use submanifold convolutions
Also implements 'Plus'-augmented nets
"""
nPlanes
=
nInputPlanes
m
=
scn
.
Sequential
()
for
x
in
layers
:
if
x
==
'MP'
:
m
.
add
(
scn
.
MaxPooling
(
dimension
,
3
,
2
))
elif
x
[
0
]
==
'MP'
:
m
.
add
(
scn
.
MaxPooling
(
dimension
,
x
[
1
],
x
[
2
]))
elif
x
==
'C3/2'
:
m
.
add
(
scn
.
Convolution
(
dimension
,
nPlanes
,
nPlanes
,
3
,
2
,
False
))
m
.
add
(
scn
.
BatchNormReLU
(
nPlanes
))
elif
x
[
0
]
==
'C3/2'
:
m
.
add
(
scn
.
Convolution
(
dimension
,
nPlanes
,
x
[
1
],
3
,
2
,
False
))
nPlanes
=
x
[
1
]
m
.
add
(
scn
.
BatchNormReLU
(
nPlanes
))
elif
x
[
0
]
==
'C'
and
len
(
x
)
==
2
:
m
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
nPlanes
,
x
[
1
],
3
,
False
))
nPlanes
=
x
[
1
]
m
.
add
(
scn
.
BatchNormReLU
(
nPlanes
))
elif
x
[
0
]
==
'C'
and
len
(
x
)
==
3
:
m
.
add
(
scn
.
ConcatTable
()
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
nPlanes
,
x
[
1
],
3
,
False
)
).
add
(
scn
.
Sequential
()
.
add
(
scn
.
Convolution
(
dimension
,
nPlanes
,
x
[
2
],
3
,
2
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
2
]))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
x
[
2
],
x
[
2
],
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
2
]))
.
add
(
scn
.
Deconvolution
(
dimension
,
x
[
2
],
x
[
2
],
3
,
2
,
False
))
)).
add
(
scn
.
JoinTable
())
nPlanes
=
x
[
1
]
+
x
[
2
]
m
.
add
(
scn
.
BatchNormReLU
(
nPlanes
))
elif
x
[
0
]
==
'C'
and
len
(
x
)
==
4
:
m
.
add
(
scn
.
ConcatTable
()
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
nPlanes
,
x
[
1
],
3
,
False
)
)
.
add
(
scn
.
Sequential
()
.
add
(
scn
.
Convolution
(
dimension
,
nPlanes
,
x
[
2
],
3
,
2
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
2
]))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
x
[
2
],
x
[
2
],
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
2
]))
.
add
(
scn
.
Deconvolution
(
dimension
,
x
[
2
],
x
[
2
],
3
,
2
,
False
))
)
.
add
(
scn
.
Sequential
()
.
add
(
scn
.
Convolution
(
dimension
,
nPlanes
,
x
[
3
],
3
,
2
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
3
]))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
x
[
3
],
x
[
3
],
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
3
]))
.
add
(
scn
.
Convolution
(
dimension
,
x
[
3
],
x
[
3
],
3
,
2
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
3
]))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
x
[
3
],
x
[
3
],
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
3
]))
.
add
(
scn
.
Deconvolution
(
dimension
,
x
[
3
],
x
[
3
],
3
,
2
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
3
]))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
x
[
3
],
x
[
3
],
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
3
]))
.
add
(
scn
.
Deconvolution
(
dimension
,
x
[
3
],
x
[
3
],
3
,
2
,
False
))
)).
add
(
scn
.
JoinTable
())
nPlanes
=
x
[
1
]
+
x
[
2
]
+
x
[
3
]
m
.
add
(
scn
.
BatchNormReLU
(
nPlanes
))
elif
x
[
0
]
==
'C'
and
len
(
x
)
==
5
:
m
.
add
(
scn
.
ConcatTable
()
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
nPlanes
,
x
[
1
],
3
,
False
)
)
.
add
(
scn
.
Sequential
()
.
add
(
scn
.
Convolution
(
dimension
,
nPlanes
,
x
[
2
],
3
,
2
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
2
]))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
x
[
2
],
x
[
2
],
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
2
]))
.
add
(
scn
.
Deconvolution
(
dimension
,
x
[
2
],
x
[
2
],
3
,
2
,
False
))
)
.
add
(
scn
.
Sequential
()
.
add
(
scn
.
Convolution
(
dimension
,
nPlanes
,
x
[
3
],
3
,
2
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
3
]))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
x
[
3
],
x
[
3
],
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
3
]))
.
add
(
scn
.
Convolution
(
dimension
,
x
[
3
],
x
[
3
],
3
,
2
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
3
]))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
x
[
3
],
x
[
3
],
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
3
]))
.
add
(
scn
.
Deconvolution
(
dimension
,
x
[
3
],
x
[
3
],
3
,
2
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
3
]))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
x
[
3
],
x
[
3
],
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
3
]))
.
add
(
scn
.
Deconvolution
(
dimension
,
x
[
3
],
x
[
3
],
3
,
2
,
False
))
)
.
add
(
scn
.
Sequential
()
.
add
(
scn
.
Convolution
(
dimension
,
nPlanes
,
x
[
4
],
3
,
2
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
4
]))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
x
[
4
],
x
[
4
],
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
4
]))
.
add
(
scn
.
Convolution
(
dimension
,
x
[
4
],
x
[
4
],
3
,
2
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
4
]))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
x
[
4
],
x
[
4
],
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
4
]))
.
add
(
scn
.
Convolution
(
dimension
,
x
[
4
],
x
[
4
],
3
,
2
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
4
]))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
x
[
4
],
x
[
4
],
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
4
]))
.
add
(
scn
.
Deconvolution
(
dimension
,
x
[
4
],
x
[
4
],
3
,
2
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
4
]))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
x
[
4
],
x
[
4
],
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
4
]))
.
add
(
scn
.
Deconvolution
(
dimension
,
x
[
4
],
x
[
4
],
3
,
2
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
4
]))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
x
[
4
],
x
[
4
],
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
x
[
4
]))
.
add
(
scn
.
Deconvolution
(
dimension
,
x
[
4
],
x
[
4
],
3
,
2
,
False
))
)).
add
(
scn
.
JoinTable
())
nPlanes
=
x
[
1
]
+
x
[
2
]
+
x
[
3
]
+
x
[
4
]
m
.
add
(
scn
.
BatchNormReLU
(
nPlanes
))
return
m
def
SparseResNet
(
dimension
,
nInputPlanes
,
layers
):
"""
pre-activated ResNet
e.g. layers = {{'basic',16,2,1},{'basic',32,2}}
"""
nPlanes
=
nInputPlanes
m
=
scn
.
Sequential
()
def
residual
(
nIn
,
nOut
,
stride
):
if
stride
>
1
:
return
scn
.
Convolution
(
dimension
,
nIn
,
nOut
,
3
,
stride
,
False
)
elif
nIn
!=
nOut
:
return
scn
.
NetworkInNetwork
(
nIn
,
nOut
,
False
)
else
:
return
scn
.
Identity
()
for
blockType
,
n
,
reps
,
stride
in
layers
:
for
rep
in
range
(
reps
):
if
blockType
[
0
]
==
'b'
:
# basic block
if
rep
==
0
:
m
.
add
(
scn
.
BatchNormReLU
(
nPlanes
))
m
.
add
(
scn
.
ConcatTable
().
add
(
scn
.
Sequential
().
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
nPlanes
,
n
,
3
,
False
)
if
stride
==
1
else
scn
.
Convolution
(
dimension
,
nPlanes
,
n
,
3
,
stride
,
False
))
.
add
(
scn
.
BatchNormReLU
(
n
))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
n
,
n
,
3
,
False
)))
.
add
(
residual
(
nPlanes
,
n
,
stride
)))
else
:
m
.
add
(
scn
.
ConcatTable
().
add
(
scn
.
Sequential
().
add
(
scn
.
BatchNormReLU
(
nPlanes
))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
nPlanes
,
n
,
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
n
))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
n
,
n
,
3
,
False
)))
.
add
(
scn
.
Identity
()))
nPlanes
=
n
m
.
add
(
scn
.
AddTable
())
m
.
add
(
scn
.
BatchNormReLU
(
nPlanes
))
return
m
def
UNet
(
dimension
,
reps
,
nPlanes
,
residual_blocks
=
False
,
downsample
=
[
2
,
2
]):
"""
U-Net style network with VGG or ResNet-style blocks.
For voxel level prediction:
import sparseconvnet as scn
import torch.nn
class Model(nn.Module):
def __init__(self):
nn.Module.__init__(self)
self.sparseModel = scn.Sequential().add(
scn.SubmanifoldConvolution(3, nInputFeatures, 64, 3, False)).add(
scn.UNet(3, 2, [64, 128, 192, 256], residual_blocks=True, downsample=[2, 2]))
self.linear = nn.Linear(64, nClasses)
def forward(self,x):
x=self.sparseModel(x).features
x=self.linear(x)
return x
"""
def
block
(
m
,
a
,
b
):
if
residual_blocks
:
#ResNet style blocks
m
.
add
(
scn
.
ConcatTable
()
.
add
(
scn
.
Identity
()
if
a
==
b
else
scn
.
NetworkInNetwork
(
a
,
b
,
False
))
.
add
(
scn
.
Sequential
()
.
add
(
scn
.
BatchNormReLU
(
a
))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
a
,
b
,
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
b
))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
b
,
b
,
3
,
False
)))
).
add
(
scn
.
AddTable
())
else
:
#VGG style blocks
m
.
add
(
scn
.
Sequential
()
.
add
(
scn
.
BatchNormReLU
(
a
))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
a
,
b
,
3
,
False
)))
def
U
(
nPlanes
):
#Recursive function
m
=
scn
.
Sequential
()
if
len
(
nPlanes
)
==
1
:
for
_
in
range
(
reps
):
block
(
m
,
nPlanes
[
0
],
nPlanes
[
0
])
else
:
m
=
scn
.
Sequential
()
for
_
in
range
(
reps
):
block
(
m
,
nPlanes
[
0
],
nPlanes
[
0
])
m
.
add
(
scn
.
ConcatTable
().
add
(
scn
.
Identity
()).
add
(
scn
.
Sequential
().
add
(
scn
.
BatchNormReLU
(
nPlanes
[
0
])).
add
(
scn
.
Convolution
(
dimension
,
nPlanes
[
0
],
nPlanes
[
1
],
downsample
[
0
],
downsample
[
1
],
False
)).
add
(
U
(
nPlanes
[
1
:])).
add
(
scn
.
BatchNormReLU
(
nPlanes
[
1
])).
add
(
scn
.
Deconvolution
(
dimension
,
nPlanes
[
1
],
nPlanes
[
0
],
downsample
[
0
],
downsample
[
1
],
False
))))
m
.
add
(
scn
.
JoinTable
())
for
i
in
range
(
reps
):
block
(
m
,
nPlanes
[
0
]
*
(
2
if
i
==
0
else
1
),
nPlanes
[
0
])
return
m
m
=
U
(
nPlanes
)
return
m
def
FullyConvolutionalNet
(
dimension
,
reps
,
nPlanes
,
residual_blocks
=
False
,
downsample
=
[
2
,
2
]):
"""
Fully-convolutional style network with VGG or ResNet-style blocks.
For voxel level prediction:
import sparseconvnet as scn
import torch.nn
class Model(nn.Module):
def __init__(self):
nn.Module.__init__(self)
self.sparseModel = scn.Sequential().add(
scn.SubmanifoldConvolution(3, nInputFeatures, 64, 3, False)).add(
scn.FullyConvolutionalNet(3, 2, [64, 128, 192, 256], residual_blocks=True, downsample=[2, 2]))
self.linear = nn.Linear(64+128+192+256, nClasses)
def forward(self,x):
x=self.sparseModel(x).features
x=self.linear(x)
return x
"""
def
block
(
m
,
a
,
b
):
if
residual_blocks
:
#ResNet style blocks
m
.
add
(
scn
.
ConcatTable
()
.
add
(
scn
.
Identity
()
if
a
==
b
else
scn
.
NetworkInNetwork
(
a
,
b
,
False
))
.
add
(
scn
.
Sequential
()
.
add
(
scn
.
BatchNormReLU
(
a
))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
a
,
b
,
3
,
False
))
.
add
(
scn
.
BatchNormReLU
(
b
))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
b
,
b
,
3
,
False
)))
).
add
(
scn
.
AddTable
())
else
:
#VGG style blocks
m
.
add
(
scn
.
Sequential
()
.
add
(
scn
.
BatchNormReLU
(
a
))
.
add
(
scn
.
SubmanifoldConvolution
(
dimension
,
a
,
b
,
3
,
False
)))
def
U
(
nPlanes
):
#Recursive function
m
=
scn
.
Sequential
()
if
len
(
nPlanes
)
==
1
:
for
_
in
range
(
reps
):
block
(
m
,
nPlanes
[
0
],
nPlanes
[
0
])
else
:
m
=
scn
.
Sequential
()
for
_
in
range
(
reps
):
block
(
m
,
nPlanes
[
0
],
nPlanes
[
0
])
m
.
add
(
scn
.
ConcatTable
().
add
(
scn
.
Identity
()).
add
(
scn
.
Sequential
().
add
(
scn
.
BatchNormReLU
(
nPlanes
[
0
])).
add
(
scn
.
Convolution
(
dimension
,
nPlanes
[
0
],
nPlanes
[
1
],
downsample
[
0
],
downsample
[
1
],
False
)).
add
(
U
(
nPlanes
[
1
:])).
add
(
scn
.
UnPooling
(
dimension
,
downsample
[
0
],
downsample
[
1
]))))
m
.
add
(
scn
.
JoinTable
())
return
m
m
=
U
(
nPlanes
)
return
m
PyTorch/
sparseconvnet/networkInNetwork.py
→
sparseconvnet/networkInNetwork.py
View file @
1df7b845
...
@@ -52,7 +52,7 @@ class NetworkInNetworkFunction(Function):
...
@@ -52,7 +52,7 @@ class NetworkInNetworkFunction(Function):
input_features
,
input_features
,
grad_output
,
grad_output
,
grad_weight
,
grad_weight
,
grad_bias
.
data
if
grad_bias
is
not
None
else
nullptr
)
grad_bias
if
grad_bias
is
not
None
else
nullptr
)
return
grad_input
,
grad_weight
,
grad_bias
return
grad_input
,
grad_weight
,
grad_bias
...
@@ -72,7 +72,7 @@ class NetworkInNetwork(Module):
...
@@ -72,7 +72,7 @@ class NetworkInNetwork(Module):
self
.
bias
=
None
self
.
bias
=
None
def
forward
(
self
,
input
):
def
forward
(
self
,
input
):
assert
input
.
features
.
n
dimension
()
==
0
or
input
.
features
.
size
(
1
)
==
self
.
nIn
assert
input
.
features
.
n
element
()
==
0
or
input
.
features
.
size
(
1
)
==
self
.
nIn
output
=
SparseConvNetTensor
()
output
=
SparseConvNetTensor
()
output
.
metadata
=
input
.
metadata
output
.
metadata
=
input
.
metadata
output
.
spatial_size
=
input
.
spatial_size
output
.
spatial_size
=
input
.
spatial_size
...
...
sparseconvnet/randomizedStrideConvolution.py
0 → 100644
View file @
1df7b845
# 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
sparseconvnet
from
torch.autograd
import
Function
from
torch.nn
import
Module
,
Parameter
from
.utils
import
*
from
.sparseConvNetTensor
import
SparseConvNetTensor
from
.convolution
import
ConvolutionFunction
class
RandomizedStrideConvolutionFunction
(
Function
):
@
staticmethod
def
forward
(
ctx
,
input_features
,
weight
,
bias
,
input_metadata
,
input_spatial_size
,
output_spatial_size
,
dimension
,
filter_size
,
filter_stride
):
output_features
=
input_features
.
new
()
ctx
.
input_metadata
=
input_metadata
ctx
.
dimension
=
dimension
ctx
.
save_for_backward
(
input_features
,
input_spatial_size
,
weight
,
bias
,
output_spatial_size
,
filter_size
,
filter_stride
)
sparseconvnet
.
forward_pass_multiplyAdd_count
+=
\
dim_typed_fn
(
dimension
,
input_features
,
'RandomizedStrideConvolution_updateOutput'
)(
input_spatial_size
,
output_spatial_size
,
filter_size
,
filter_stride
,
input_metadata
.
ffi
,
input_features
,
output_features
,
weight
,
bias
if
bias
is
not
None
else
nullptr
,
0
)
# remove this parameter!!
sparseconvnet
.
forward_pass_hidden_states
+=
output_features
.
nelement
()
return
output_features
@
staticmethod
def
backward
(
ctx
,
grad_output
):
input_features
,
input_spatial_size
,
weight
,
bias
,
output_spatial_size
,
filter_size
,
filter_stride
=
ctx
.
saved_tensors
grad_input
=
grad_output
.
new
()
grad_weight
=
grad_output
.
new
().
resize_as_
(
weight
).
zero_
()
if
bias
is
None
:
grad_bias
=
None
else
:
grad_bias
=
grad_output
.
new
().
resize_as_
(
bias
).
zero_
()
dim_typed_fn
(
ctx
.
dimension
,
input_features
,
'RandomizedStrideConvolution_backward'
)(
input_spatial_size
,
output_spatial_size
,
filter_size
,
filter_stride
,
ctx
.
input_metadata
.
ffi
,
input_features
,
grad_input
,
grad_output
.
contiguous
(),
weight
,
grad_weight
,
grad_bias
if
grad_bias
is
not
None
else
nullptr
,
0
,
# remove this parameter
)
return
grad_input
,
grad_weight
,
grad_bias
,
None
,
None
,
None
,
None
,
None
,
None
class
RandomizedStrideConvolution
(
Module
):
"""
A bit like Fractional Max Pooling during training, but at test time it
operates like a regular sparseconvnet.Convolution.
Don't use with scn.InputBatch.precomute_metadata()!!
Like regular a sparseconvnet.Convolution, is can be paired with a
sparseconvnet.Deconvolution module in an UNet style network, to restore
the input sparsity pattern.
"""
def
__init__
(
self
,
dimension
,
nIn
,
nOut
,
filter_size
,
filter_stride
,
bias
):
Module
.
__init__
(
self
)
self
.
dimension
=
dimension
self
.
nIn
=
nIn
self
.
nOut
=
nOut
self
.
filter_size
=
toLongTensor
(
dimension
,
filter_size
)
self
.
filter_volume
=
self
.
filter_size
.
prod
().
item
()
self
.
filter_stride
=
toLongTensor
(
dimension
,
filter_stride
)
std
=
(
2.0
/
nIn
/
self
.
filter_volume
)
**
0.5
self
.
weight
=
Parameter
(
torch
.
Tensor
(
self
.
filter_volume
*
nIn
,
nOut
).
normal_
(
0
,
std
))
if
bias
:
self
.
bias
=
Parameter
(
torch
.
Tensor
(
nOut
).
zero_
())
else
:
self
.
bias
=
None
def
forward
(
self
,
input
):
assert
input
.
features
.
ndimension
()
==
0
or
input
.
features
.
size
(
1
)
==
self
.
nIn
output
=
SparseConvNetTensor
()
output
.
metadata
=
input
.
metadata
output
.
spatial_size
=
\
(
input
.
spatial_size
-
self
.
filter_size
)
/
self
.
filter_stride
+
1
assert
((
output
.
spatial_size
-
1
)
*
self
.
filter_stride
+
self
.
filter_size
==
input
.
spatial_size
).
all
()
output
.
features
=
(
RandomizedStrideConvolutionFunction
if
self
.
training
else
ConvolutionFunction
).
apply
(
#output.features = ConvolutionFunction.apply(
#output.features = RandomizedStrideConvolutionFunction.apply(
input
.
features
,
self
.
weight
,
self
.
bias
,
input
.
metadata
,
input
.
spatial_size
,
output
.
spatial_size
,
self
.
dimension
,
self
.
filter_size
,
self
.
filter_stride
,
)
return
output
def
__repr__
(
self
):
s
=
'RandomizedStrideConvolution '
+
str
(
self
.
nIn
)
+
'->'
+
str
(
self
.
nOut
)
+
' C'
if
self
.
filter_size
.
max
().
item
()
==
self
.
filter_size
.
min
().
item
()
and
\
self
.
filter_stride
.
max
().
item
()
==
self
.
filter_stride
.
min
().
item
():
s
=
s
+
str
(
self
.
filter_size
[
0
].
item
())
+
\
'/'
+
str
(
self
.
filter_stride
[
0
].
item
())
else
:
s
=
s
+
'('
+
str
(
self
.
filter_size
[
0
].
item
())
for
i
in
self
.
filter_size
[
1
:]:
s
=
s
+
','
+
str
(
i
.
item
())
s
=
s
+
')/('
+
str
(
self
.
filter_stride
[
0
].
item
())
for
i
in
self
.
filter_stride
[
1
:]:
s
=
s
+
','
+
str
(
i
.
item
())
s
=
s
+
')'
return
s
def
input_spatial_size
(
self
,
out_size
):
return
(
out_size
-
1
)
*
self
.
filter_stride
+
self
.
filter_size
sparseconvnet/randomizedStrideMaxPooling.py
0 → 100644
View file @
1df7b845
# 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.
from
torch.autograd
import
Function
from
torch.nn
import
Module
from
.utils
import
*
from
.sparseConvNetTensor
import
SparseConvNetTensor
from
.maxPooling
import
MaxPoolingFunction
class
RandomizedStrideMaxPoolingFunction
(
Function
):
@
staticmethod
def
forward
(
ctx
,
input_features
,
input_metadata
,
input_spatial_size
,
output_spatial_size
,
dimension
,
pool_size
,
pool_stride
,
nFeaturesToDrop
):
ctx
.
input_metadata
=
input_metadata
ctx
.
dimension
=
dimension
ctx
.
nFeaturesToDrop
=
nFeaturesToDrop
output_features
=
input_features
.
new
()
dim_typed_fn
(
dimension
,
input_features
,
'RandomizedStrideMaxPooling_updateOutput'
)(
input_spatial_size
,
output_spatial_size
,
pool_size
,
pool_stride
,
input_metadata
.
ffi
,
input_features
,
output_features
,
nFeaturesToDrop
)
ctx
.
save_for_backward
(
input_features
,
output_features
,
input_spatial_size
,
output_spatial_size
,
pool_size
,
pool_stride
)
return
output_features
@
staticmethod
def
backward
(
ctx
,
grad_output
):
input_features
,
\
output_features
,
\
input_spatial_size
,
\
output_spatial_size
,
\
pool_size
,
\
pool_stride
=
ctx
.
saved_tensors
grad_input
=
grad_output
.
new
()
dim_typed_fn
(
ctx
.
dimension
,
input_features
,
'RandomizedStrideMaxPooling_updateGradInput'
)(
input_spatial_size
,
output_spatial_size
,
pool_size
,
pool_stride
,
ctx
.
input_metadata
.
ffi
,
input_features
,
grad_input
,
output_features
,
grad_output
,
ctx
.
nFeaturesToDrop
)
return
grad_input
,
None
,
None
,
None
,
None
,
None
,
None
,
None
class
RandomizedStrideMaxPooling
(
Module
):
def
__init__
(
self
,
dimension
,
pool_size
,
pool_stride
,
nFeaturesToDrop
=
0
):
super
(
RandomizedStrideMaxPooling
,
self
).
__init__
()
self
.
dimension
=
dimension
self
.
pool_size
=
toLongTensor
(
dimension
,
pool_size
)
self
.
pool_stride
=
toLongTensor
(
dimension
,
pool_stride
)
self
.
nFeaturesToDrop
=
nFeaturesToDrop
def
forward
(
self
,
input
):
output
=
SparseConvNetTensor
()
output
.
metadata
=
input
.
metadata
output
.
spatial_size
=
(
input
.
spatial_size
-
self
.
pool_size
)
/
self
.
pool_stride
+
1
assert
((
output
.
spatial_size
-
1
)
*
self
.
pool_stride
+
self
.
pool_size
==
input
.
spatial_size
).
all
()
output
.
features
=
(
RandomizedStrideMaxPoolingFunction
if
self
.
training
else
MaxPoolingFunction
).
apply
(
input
.
features
,
input
.
metadata
,
input
.
spatial_size
,
output
.
spatial_size
,
self
.
dimension
,
self
.
pool_size
,
self
.
pool_stride
,
self
.
nFeaturesToDrop
)
return
output
def
input_spatial_size
(
self
,
out_size
):
return
(
out_size
-
1
)
*
self
.
pool_stride
+
self
.
pool_size
def
__repr__
(
self
):
s
=
'RandomizedStrideMaxPooling'
if
self
.
pool_size
.
max
().
item
()
==
self
.
pool_size
.
min
().
item
()
and
\
self
.
pool_stride
.
max
().
item
()
==
self
.
pool_stride
.
min
().
item
():
s
=
s
+
str
(
self
.
pool_size
[
0
].
item
())
+
\
'/'
+
str
(
self
.
pool_stride
[
0
].
item
())
else
:
s
=
s
+
'('
+
str
(
self
.
pool_size
[
0
].
item
())
for
i
in
self
.
pool_size
[
1
:]:
s
=
s
+
','
+
str
(
i
.
item
())
s
=
s
+
')/('
+
str
(
self
.
pool_stride
[
0
].
item
())
for
i
in
self
.
pool_stride
[
1
:]:
s
=
s
+
','
+
str
(
i
.
item
())
s
=
s
+
')'
if
self
.
nFeaturesToDrop
>
0
:
s
=
s
+
' nFeaturesToDrop = '
+
self
.
nFeaturesToDrop
return
s
PyTorch/
sparseconvnet/sequential.py
→
sparseconvnet/sequential.py
View file @
1df7b845
File moved
PyTorch/
sparseconvnet/sparseConvNetTensor.py
→
sparseconvnet/sparseConvNetTensor.py
View file @
1df7b845
File moved
PyTorch/
sparseconvnet/sparseToDense.py
→
sparseconvnet/sparseToDense.py
View file @
1df7b845
...
@@ -42,7 +42,6 @@ class SparseToDenseFunction(Function):
...
@@ -42,7 +42,6 @@ class SparseToDenseFunction(Function):
input_metadata
.
ffi
,
input_metadata
.
ffi
,
input_features
,
input_features
,
output
,
output
,
torch
.
cuda
.
IntTensor
()
if
input_features
.
is_cuda
else
nullptr
,
nPlanes
)
nPlanes
)
return
output
return
output
...
@@ -58,8 +57,7 @@ class SparseToDenseFunction(Function):
...
@@ -58,8 +57,7 @@ class SparseToDenseFunction(Function):
ctx
.
input_metadata
.
ffi
,
ctx
.
input_metadata
.
ffi
,
input_features
,
input_features
,
grad_input
,
grad_input
,
grad_output
.
contiguous
(),
grad_output
.
contiguous
())
torch
.
cuda
.
IntTensor
()
if
input_features
.
is_cuda
else
nullptr
)
return
grad_input
,
None
,
None
,
None
,
None
return
grad_input
,
None
,
None
,
None
,
None
...
...
sparseconvnet/sparsify.py
0 → 100644
View file @
1df7b845
# 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.
# 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
sparseconvnet
from
torch.autograd
import
Function
,
Variable
from
torch.nn
import
Module
,
Parameter
from
.utils
import
*
from
.sparseConvNetTensor
import
SparseConvNetTensor
from
.metadata
import
Metadata
class
Sparsify
(
Module
):
def
__init__
(
self
,
dimension
):
Module
.
__init__
(
self
)
self
.
dimension
=
dimension
def
forward
(
self
,
input
):
output
=
SparseConvNetTensor
()
output
.
metadata
=
Metadata
(
self
.
dimension
)
output
.
spatial_size
=
input
.
spatial_size
active
=
input
.
features
[:,
0
]
>
0
output
.
features
=
input
.
features
[
active
]
active
=
active
.
type
(
'torch.LongTensor'
)
dim_fn
(
self
.
dimension
,
'sparsifyMetadata'
)(
input
.
metadata
.
ffi
,
output
.
metadata
.
ffi
,
input
.
spatial_size
,
active
.
byte
(),
active
.
cumsum
(
0
))
return
output
Prev
1
…
6
7
8
9
10
11
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment