Giter Club home page Giter Club logo

sparseconvnet's Introduction

Submanifold Sparse Convolutional Networks

Support Ukraine

This is the PyTorch library for training Submanifold Sparse Convolutional Networks.

Spatial sparsity

This library brings Spatially-sparse convolutional networks to PyTorch. Moreover, it introduces Submanifold Sparse Convolutions, that can be used to build computationally efficient sparse VGG/ResNet/DenseNet-style networks.

With regular 3x3 convolutions, the set of active (non-zero) sites grows rapidly:
submanifold
With Submanifold Sparse Convolutions, the set of active sites is unchanged. Active sites look at their active neighbors (green); non-active sites (red) have no computational overhead:
submanifold
Stacking Submanifold Sparse Convolutions to build VGG and ResNet type ConvNets, information can flow along lines or surfaces of active points.

Disconnected components don't communicate at first, although they will merge due to the effect of strided operations, either pooling or convolutions. Additionally, adding ConvolutionWithStride2-SubmanifoldConvolution-DeconvolutionWithStride2 paths to the network allows disjoint active sites to communicate; see the 'VGG+' networks in the paper.
Strided Convolution, convolution, deconvolution
Strided Convolution, convolution, deconvolution
From left: (i) an active point is highlighted; a convolution with stride 2 sees the green active sites (ii) and produces output (iii), 'children' of hightlighted active point from (i) are highlighted; a submanifold sparse convolution sees the green active sites (iv) and produces output (v); a deconvolution operation sees the green active sites (vi) and produces output (vii).

Dimensionality and 'submanifolds'

SparseConvNet supports input with different numbers of spatial/temporal dimensions. Higher dimensional input is more likely to be sparse because of the 'curse of dimensionality'.

Dimension Name in 'torch.nn' Use cases
1 Conv1d Text, audio
2 Conv2d Lines in 2D space, e.g. handwriting
3 Conv3d Lines and surfaces in 3D space or (2+1)D space-time
4 - Lines, etc, in (3+1)D space-time

We use the term 'submanifold' to refer to input data that is sparse because it has a lower effective dimension than the space in which it lives, for example a one-dimensional curve in 2+ dimensional space, or a two-dimensional surface in 3+ dimensional space.

In theory, the library supports up to 10 dimensions. In practice, ConvNets with size-3 SVC convolutions in dimension 5+ may be impractical as the number of parameters per convolution is growing exponentially. Possible solutions include factorizing the convolutions (e.g. 3x1x1x..., 1x3x1x..., etc), or switching to a hyper-tetrahedral lattice (see Sparse 3D convolutional neural networks).

Hello World

SparseConvNets can be built either by defining a function that inherits from torch.nn.Module or by stacking modules in a sparseconvnet.Sequential:

import torch
import sparseconvnet as scn

# Use the GPU if there is one, otherwise CPU
device = 'cuda:0' if torch.cuda.is_available() else 'cpu'

model = scn.Sequential().add(
    scn.SparseVggNet(2, 1,
                     [['C', 8], ['C', 8], ['MP', 3, 2],
                      ['C', 16], ['C', 16], ['MP', 3, 2],
                      ['C', 24], ['C', 24], ['MP', 3, 2]])
).add(
    scn.SubmanifoldConvolution(2, 24, 32, 3, False)
).add(
    scn.BatchNormReLU(32)
).add(
    scn.SparseToDense(2, 32)
).to(device)

# output will be 10x10
inputSpatialSize = model.input_spatial_size(torch.LongTensor([10, 10]))
input_layer = scn.InputLayer(2, inputSpatialSize)

msgs = [[" X   X  XXX  X    X    XX     X       X   XX   XXX   X    XXX   ",
         " X   X  X    X    X   X  X    X       X  X  X  X  X  X    X  X  ",
         " XXXXX  XX   X    X   X  X    X   X   X  X  X  XXX   X    X   X ",
         " X   X  X    X    X   X  X     X X X X   X  X  X  X  X    X  X  ",
         " X   X  XXX  XXX  XXX  XX       X   X     XX   X  X  XXX  XXX   "],

        [" XXX              XXXXX      x   x     x  xxxxx  xxx ",
         " X  X  X   XXX       X       x   x x   x  x     x  x ",
         " XXX                X        x   xxxx  x  xxxx   xxx ",
         " X     X   XXX       X       x     x   x      x    x ",
         " X     X          XXXX   x   x     x   x  xxxx     x ",]]


# Create Nx3 and Nx1 vectors to encode the messages above:
locations = []
features = []
for batchIdx, msg in enumerate(msgs):
    for y, line in enumerate(msg):
        for x, c in enumerate(line):
            if c == 'X':
                locations.append([y, x, batchIdx])
                features.append([1])
locations = torch.LongTensor(locations)
features = torch.FloatTensor(features).to(device)

input = input_layer([locations,features])
print('Input SparseConvNetTensor:', input)
output = model(input)

# Output is 2x32x10x10: our minibatch has 2 samples, the network has 32 output
# feature planes, and 10x10 is the spatial size of the output.
print('Output SparseConvNetTensor:', output)

Examples

Examples in the examples folder include

For example:

cd examples/Assamese_handwriting
python VGGplus.py

Setup

Tested with PyTorch 1.3, CUDA 10.0, and Python 3.3 with Conda.

conda install pytorch torchvision cudatoolkit=10.0 -c pytorch # See https://pytorch.org/get-started/locally/
git clone [email protected]:facebookresearch/SparseConvNet.git
cd SparseConvNet/
bash develop.sh

To run the examples you may also need to install unrar:

apt-get install unrar

License

SparseConvNet is BSD licensed, as found in the LICENSE file. Terms of use. Privacy

Copyright © Meta Platforms, Inc

Links

  1. ICDAR 2013 Chinese Handwriting Recognition Competition 2013 First place in task 3, with test error of 2.61%. Human performance on the test set was 4.81%. Report
  2. Spatially-sparse convolutional neural networks, 2014 SparseConvNets for Chinese handwriting recognition
  3. Fractional max-pooling, 2014 A SparseConvNet with fractional max-pooling achieves an error rate of 3.47% for CIFAR-10.
  4. Sparse 3D convolutional neural networks, BMVC 2015 SparseConvNets for 3D object recognition and (2+1)D video action recognition.
  5. Kaggle plankton recognition competition, 2015 Third place. The competition solution is being adapted for research purposes in EcoTaxa.
  6. Kaggle Diabetic Retinopathy Detection, 2015 First place in the Kaggle Diabetic Retinopathy Detection competition.
  7. SparseConvNet 'classic' version
  8. Submanifold Sparse Convolutional Networks, 2017 Introduces deep 'submanifold' SparseConvNets.
  9. Workshop on Learning to See from 3D Data, 2017 First place in the semantic segmentation competition. Report
  10. 3D Semantic Segmentation with Submanifold Sparse Convolutional Networks, 2017 Semantic segmentation for the ShapeNet Core55 and NYU-DepthV2 datasets, CVPR 2018
  11. Unsupervised learning with sparse space-and-time autoencoders (3+1)D space-time autoencoders
  12. ScanNet 3D semantic label benchmark 2018 0.726 average IOU for 3D semantic segmentation.
  13. MinkowskiEngine is an alternative implementation of SparseConvNet; 0.736 average IOU for ScanNet.
  14. SpConv: PyTorch Spatially Sparse Convolution Library is an alternative implementation of SparseConvNet.
  15. Live Semantic 3D Perception for Immersive Augmented Reality describes a way to optimize memory access for SparseConvNet.
  16. OccuSeg real-time object detection using SparseConvNets.
  17. TorchSparse implements 3D submanifold convolutions.
  18. TensorFlow 3D implements submanifold convolutions.
  19. VoTr implements submanifold voxel transformers using SpConv.
  20. Mix3D brings MixUp to the sparse setting— 0.781 average IOU for ScanNet 3D semantic segmentation.
  21. Point Transformer V3 uses sparse convolutions as an enhanced conditional positional encoding (xCPE); 0.794 average IOU for ScanNet 3D semantic segmentation.

Citations

If you find this code useful in your research then please cite:

3D Semantic Segmentation with Submanifold Sparse Convolutional Networks, CVPR 2018
Benjamin Graham,
Martin Engelcke,
Laurens van der Maaten,

@article{3DSemanticSegmentationWithSubmanifoldSparseConvNet,
  title={3D Semantic Segmentation with Submanifold Sparse Convolutional Networks},
  author={Graham, Benjamin and Engelcke, Martin and van der Maaten, Laurens},
  journal={CVPR},
  year={2018}
}

and/or

Submanifold Sparse Convolutional Networks, https://arxiv.org/abs/1706.01307
Benjamin Graham,
Laurens van der Maaten,

@article{SubmanifoldSparseConvNet,
  title={Submanifold Sparse Convolutional Networks},
  author={Graham, Benjamin and van der Maaten, Laurens},
  journal={arXiv preprint arXiv:1706.01307},
  year={2017}
}

sparseconvnet's People

Contributors

bottler avatar btgraham avatar dmitryvinn avatar dymat avatar gnedster avatar lvdmaaten avatar mpmisko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sparseconvnet's Issues

How to add Factional Max Pooling(FMP) to SparseConvNet?

Hey, your FMP and Sparse convolution network are very inspiring. I read your code published for kaggle winner solution. Thank a lot.

I want to implement a model in PyTorch using both of them. I note the FMP python wrapper torch.nn.FractionalMaxPool2d has been included in latest PyTorch release.

Can you give any example?

Thanks,

Steven

Runtime Error When Running Examples

Hi Benjamin,

A runtime error raised when I ran ResNet.py or VGGplus.py:RuntimeError: softmax(): argument 'input' (position 1) must be Variable, not torch.cuda.FloatTensor

The full traceback was:

Traceback (most recent call last):
  File "VGGplus.py", line 42, in <module>
    'check_point': True,})
  File "/root/SparseConvNet/PyTorch/sparseconvnet/classificationTrainValidate.py", line 92, in ClassificationTrainValidate
    updateStats(stats, output.data, batch['target'].data, loss.data[0])
  File "/root/SparseConvNet/PyTorch/sparseconvnet/classificationTrainValidate.py", line 38, in updateStats
    stats['confusion matrix'].index_add_(0,target,F.softmax(output).data)
  File "/root/anaconda2/lib/python2.7/site-packages/torch/nn/functional.py", line 768, in softmax
    return torch._C._nn.softmax(input, dim)
RuntimeError: softmax(): argument 'input' (position 1) must be Variable, not torch.cuda.FloatTensor

The PyTorch version is 0.3. Thank you for your help.

Python VGG-Cplus.py in Chinese_handwriting issue

ozzie@debian:~/working/work/ML/SparseConvNet/examples/Chinese_handwriting$ python VGG-Cplus.py
nn.Sequential {
[input -> (0) -> (1) -> output]
(0): nn.Sequential {
[input -> (0) -> (1) -> (2) -> (3) -> output]
(0): nn.Sequential {
[input -> (0) -> (1) -> (2) -> (3) -> (4) -> (5) -> (6) -> (7) -> (8) -> (9) -> (10) -> (11) -> (12) -> (13) -> (14) -> (15) -> (16) -> (17) -> (18) -> (19) -> (20) -> (21) -> (22) -> (23) -> (24) -> (25) -> (26) -> (27) -> (28) -> (29) -> (30) -> (31) -> (32) -> (33) -> output]
(0): sparseconvnet.legacy.concatTable.ConcatTable {
input
|-> (0): ValidConvolution 3->16 C3 |-> (1): nn.Sequential {
[input -> (0) -> (1) -> (2) -> (3) -> (4) -> output]
(0): Convolution 3->8 C3/2
(1): BatchNormReLU(8,eps=0.0001,momentum=0.9,affine=True)
(2): ValidConvolution 8->8 C3
(3): BatchNormReLU(8,eps=0.0001,momentum=0.9,affine=True)
(4): Deconvolution 8->8 C3/2
}
+. -> output
}
(1): JoinTable: 16 + 8 -> 24
(2): BatchNormReLU(24,eps=0.0001,momentum=0.9,affine=True)
(3): sparseconvnet.legacy.concatTable.ConcatTable {
input
|-> (0): ValidConvolution 24->16 C3 |-> (1): nn.Sequential {
[input -> (0) -> (1) -> (2) -> (3) -> (4) -> output]
(0): Convolution 24->8 C3/2
(1): BatchNormReLU(8,eps=0.0001,momentum=0.9,affine=True)
(2): ValidConvolution 8->8 C3
(3): BatchNormReLU(8,eps=0.0001,momentum=0.9,affine=True)
(4): Deconvolution 8->8 C3/2
}
+. -> output
}
(4): JoinTable: 16 + 8 -> 24
(5): BatchNormReLU(24,eps=0.0001,momentum=0.9,affine=True)
(6): MaxPooling3/2
(7): sparseconvnet.legacy.concatTable.ConcatTable {
input
|-> (0): ValidConvolution 24->32 C3 |-> (1): nn.Sequential {
[input -> (0) -> (1) -> (2) -> (3) -> (4) -> output]
(0): Convolution 24->8 C3/2
(1): BatchNormReLU(8,eps=0.0001,momentum=0.9,affine=True)
(2): ValidConvolution 8->8 C3
(3): BatchNormReLU(8,eps=0.0001,momentum=0.9,affine=True)
(4): Deconvolution 8->8 C3/2
}
+. -> output
}
(8): JoinTable: 32 + 8 -> 40
(9): BatchNormReLU(40,eps=0.0001,momentum=0.9,affine=True)
(10): sparseconvnet.legacy.concatTable.ConcatTable {
input
|-> (0): ValidConvolution 40->32 C3 |-> (1): nn.Sequential {
[input -> (0) -> (1) -> (2) -> (3) -> (4) -> output]
(0): Convolution 40->8 C3/2
(1): BatchNormReLU(8,eps=0.0001,momentum=0.9,affine=True)
(2): ValidConvolution 8->8 C3
(3): BatchNormReLU(8,eps=0.0001,momentum=0.9,affine=True)
(4): Deconvolution 8->8 C3/2
}
+. -> output
}
(11): JoinTable: 32 + 8 -> 40
(12): BatchNormReLU(40,eps=0.0001,momentum=0.9,affine=True)
(13): MaxPooling3/2
(14): sparseconvnet.legacy.concatTable.ConcatTable {
input
|-> (0): ValidConvolution 40->48 C3 |-> (1): nn.Sequential {
[input -> (0) -> (1) -> (2) -> (3) -> (4) -> output]
(0): Convolution 40->16 C3/2
(1): BatchNormReLU(16,eps=0.0001,momentum=0.9,affine=True)
(2): ValidConvolution 16->16 C3
(3): BatchNormReLU(16,eps=0.0001,momentum=0.9,affine=True)
(4): Deconvolution 16->16 C3/2
}
+. -> output
}
(15): JoinTable: 48 + 16 -> 64
(16): BatchNormReLU(64,eps=0.0001,momentum=0.9,affine=True)
(17): sparseconvnet.legacy.concatTable.ConcatTable {
input
|-> (0): ValidConvolution 64->48 C3 |-> (1): nn.Sequential {
[input -> (0) -> (1) -> (2) -> (3) -> (4) -> output]
(0): Convolution 64->16 C3/2
(1): BatchNormReLU(16,eps=0.0001,momentum=0.9,affine=True)
(2): ValidConvolution 16->16 C3
(3): BatchNormReLU(16,eps=0.0001,momentum=0.9,affine=True)
(4): Deconvolution 16->16 C3/2
}
+. -> output
}
(18): JoinTable: 48 + 16 -> 64
(19): BatchNormReLU(64,eps=0.0001,momentum=0.9,affine=True)
(20): MaxPooling3/2
(21): sparseconvnet.legacy.concatTable.ConcatTable {
input
|-> (0): ValidConvolution 64->64 C3 |-> (1): nn.Sequential {
[input -> (0) -> (1) -> (2) -> (3) -> (4) -> output]
(0): Convolution 64->16 C3/2
(1): BatchNormReLU(16,eps=0.0001,momentum=0.9,affine=True)
(2): ValidConvolution 16->16 C3
(3): BatchNormReLU(16,eps=0.0001,momentum=0.9,affine=True)
(4): Deconvolution 16->16 C3/2
}
+. -> output
}
(22): JoinTable: 64 + 16 -> 80
(23): BatchNormReLU(80,eps=0.0001,momentum=0.9,affine=True)
(24): sparseconvnet.legacy.concatTable.ConcatTable {
input
|-> (0): ValidConvolution 80->64 C3 |-> (1): nn.Sequential {
[input -> (0) -> (1) -> (2) -> (3) -> (4) -> output]
(0): Convolution 80->16 C3/2
(1): BatchNormReLU(16,eps=0.0001,momentum=0.9,affine=True)
(2): ValidConvolution 16->16 C3
(3): BatchNormReLU(16,eps=0.0001,momentum=0.9,affine=True)
(4): Deconvolution 16->16 C3/2
}
+. -> output
}
(25): JoinTable: 64 + 16 -> 80
(26): BatchNormReLU(80,eps=0.0001,momentum=0.9,affine=True)
(27): MaxPooling3/2
(28): sparseconvnet.legacy.concatTable.ConcatTable {
input
|-> (0): ValidConvolution 80->96 C3 |-> (1): nn.Sequential {
[input -> (0) -> (1) -> (2) -> (3) -> (4) -> output]
(0): Convolution 80->16 C3/2
(1): BatchNormReLU(16,eps=0.0001,momentum=0.9,affine=True)
(2): ValidConvolution 16->16 C3
(3): BatchNormReLU(16,eps=0.0001,momentum=0.9,affine=True)
(4): Deconvolution 16->16 C3/2
}
+. -> output
}
(29): JoinTable: 96 + 16 -> 112
(30): BatchNormReLU(112,eps=0.0001,momentum=0.9,affine=True)
(31): sparseconvnet.legacy.concatTable.ConcatTable {
input
|-> (0): ValidConvolution 112->96 C3 |-> (1): nn.Sequential {
[input -> (0) -> (1) -> (2) -> (3) -> (4) -> output]
(0): Convolution 112->16 C3/2
(1): BatchNormReLU(16,eps=0.0001,momentum=0.9,affine=True)
(2): ValidConvolution 16->16 C3
(3): BatchNormReLU(16,eps=0.0001,momentum=0.9,affine=True)
(4): Deconvolution 16->16 C3/2
}
+. -> output
}
(32): JoinTable: 96 + 16 -> 112
(33): BatchNormReLU(112,eps=0.0001,momentum=0.9,affine=True)
}
(1): Convolution 112->128 C3/2
(2): BatchNormReLU(128,eps=0.0001,momentum=0.9,affine=True)
(3): SparseToDense(2)
}
(1): nn.Sequential {
[input -> (0) -> (1) -> output]
(0): nn.View(-1, 128)
(1): nn.Linear(128 -> 3755)
}
}
('input spatial size',
63
63
[torch.LongTensor of size 2]
)
Traceback (most recent call last):
File "VGG-Cplus.py", line 36, in
dataset = getIterators(spatial_size, 63, 3)
File "/media/New_bt/ML/SparseConvNet/examples/Chinese_handwriting/data.py", line 118, in getIterators
return {'train': train(*args), 'val': val(*args)}
File "/media/New_bt/ML/SparseConvNet/examples/Chinese_handwriting/data.py", line 29, in train
d = pickle.load(open('pickle/train.pickle', 'rb'))
IOError: [Errno 2] No such file or directory: 'pickle/train.pickle'

the directory pickle is null, and there is no train.pickle

ozzie@debian:/working/work/ML/SparseConvNet/examples/Chinese_handwriting$ ls
data.lua OLHWDB1.1tst_pot.zip ResNet-A-VSC.py VGG-C.lua
data.py pickle ResNet-B-VSC.lua VGG-Cplus.lua
data.pyc POT ResNet-C-VSC.lua VGG-Cplus.py
DenseNet-A-VSC.lua process.lua ResNet-D-VSC.lua VGG-C.py
DenseNet-A-VSC.py readPotFiles2.py t7 VGG-D.lua
DenseNet-B-VSC.lua readPotFiles.py VGG-A-VSC.lua VGG-Dplus.lua
OLHWDB1.1trn_pot.zip ResNet-A-VSC.lua VGG-B-VSC.lua
ozzie@debian:
/working/work/ML/SparseConvNet/examples/Chinese_handwriting$ ls -la pickle/
total 8
drwxr-xr-x 2 ozzie ozzie 4096 Jul 18 18:35 .
drwxr-xr-x 5 ozzie ozzie 4096 Jul 18 18:35 ..
ozzie@debian:~/working/work/ML/SparseConvNet/examples/Chinese_handwriting$

Install on OSX

Does anyone have any hints for how to install on OSX?
brew install google-sparsehash
Seems to install the required libsparsehash-dev library.
(and pip3 install cffi was needed for cffi)
But python setup.py develop gives me errors like:

./generic/Geometry/../32bits.h:30:9: error: cannot initialize a variable of type 'long *' with an rvalue of type 'int64_t *' (aka 'long long *')
  long *td = THLongTensor_data(t);
        ^    ~~~~~~~~~~~~~~~~~~~~

I believe this has to do with the C compiler used, but not sure how to change the one used. Any hints are very welcome!

Platform:
OSX 10.13
Python 3.6
PyTorch 0.3.1
no GPU

ModelNet40 Torch examples failing

All three of the torch examples for ModelNet40 are failing with the following error:

/home/aa/torch/install/bin/luajit: /home/aa/.luarocks/share/lua/5.1/nn/THNN.lua:110: wrong number of arguments for function call
stack traceback:
[C]: in function 'v'
/home/aa/.luarocks/share/lua/5.1/nn/THNN.lua:110: in function 'ClassNLLCriterion_updateOutput'
.../aa/.luarocks/share/lua/5.1/nn/ClassNLLCriterion.lua:41: in function 'updateOutput'
...a/.luarocks/share/lua/5.1/nn/CrossEntropyCriterion.lua:20: in function 'forward'
...re/lua/5.1/sparseconvnet/ClassificationTrainValidate.lua:58: in function 'ClassificationTrainValidate'
VGGplus.lua:35: in main chunk
[C]: in function 'dofile'
...aa/torch/install/lib/luarocks/rocks/trepl/scm-1/bin/th:150: in main chunk
[C]: at 0x00406670

Not sure if it's a lua problem? should it be a specific version of lua/luajit?

Also, would it be possible for you to provide PyTorch models for the Modelnet40 code?

Thanks!

is set_location([x,y]) in hello_world wrong?

I think setLocation in hello_world in reversed.

self.N = 1
self.C = 10
self.K = 10
self.H = 5
self.W = 65
self.inputSpatialSize = torch.LongTensor([self.H,self.W])
self.densifier = scn.SparseToDense(2,self.C)
x1 = torch.rand(self.N, self.C, self.H, self.W)
sparse_input = scn.InputBatch(2, self.inputSpatialSize)
sparse_input.addSample()    
for y in range(self.H):
     for x in range(self.W):
           f = []
           for c in range(self.C):
                f.append(x1[0,c,y,x])
            featureVector = torch.FloatTensor(f)
            location = torch.LongTensor([y, x]) # y,x instead of x,y
            sparse_input.setLocation(location, featureVector, 0) 
tmp = self.densifier(sparse_input).data
diff = x1-tmp
criterion = diff.abs().max()
print(criterion)  

outputs 0 as absolute maximum difference.

how to write to metadatas?

At some point I need to filter out all zeros values (and their corresponding locations). Is there a workaround to modify the metadatas of a sparse tensor?

There seems a bug for 1x1 convolution

Hello. I'm now using the SparseConvNet for character regconition. And I found when I set the filter size to 1 for the scn.Convolution layer, then the layer had empty output. I did not dive deep into the source code. Is this a bug? How can I fix it?

Including sparse convolutions inside traditional model

Hi, first of all thank you so much for sharing this amazing library, I'm willing to use it in my MSc thesis.
I have a few questions: If I understood everything correctly, you advise to create a network and forward it an InputBatch created manually. This works well for a network where you have only sparse convolutions. Unfortunately, I have a network where I use a large majority of dense convolutions, and I would like to add some sparse convolutive layers at the end of it. Is it possible to achieve this?
I saw that in the pytorch version of the library there is a DenseToSparse layer that would (probably) solve this issue, but you advise not to use it. What is the reason? Could I port it to Lua, or do you plan to implement it in Lua?
Thanks in advance for your time, and I'm sorry if I misunderstood something.

Other datasets preprocessing

Thank you for your great work!
I now want to use your SparseConvnet to construct a mobilenetv1 for testing on my own dataset, and the images in this dataset is indeed sparse (in fact it is wafer dataset, and I have binarized to make them sparse).
What I want to ask is, it seems that I have to pass a tuple (coords, features, batch_size [optional]) to scn.InputLayer, however I don't really understand what they are.
Are coords the coordinates point to those active sites (foreground points) ?
Then what is features which is of size N x n_feature_planes ?
Thank you very much!

THCudaCheck FAIL THCTensorMath.cu error=8 : invalid device function on Titan X

I get following error when I run hello-world.py

THCudaCheck FAIL file=/py/conda-bld/pytorch_1493676237139/work/torch/lib/THC/generic/THCTensorMath.cu line=35 error=8 : invalid device function
Traceback (most recent call last):
  File "hello-world.py", line 54, in <module>
    output = model.forward(input)
  File "/home/mgo/miniconda2/lib/python2.7/site-packages/torch/legacy/nn/Module.py", line 33, in forward
    return self.updateOutput(input)
  File "/home/mgo/miniconda2/lib/python2.7/site-packages/torch/legacy/nn/Sequential.py", line 36, in updateOutput
    currentOutput = module.updateOutput(currentOutput)
  File "/home/mgo/miniconda2/lib/python2.7/site-packages/torch/legacy/nn/Sequential.py", line 36, in updateOutput
    currentOutput = module.updateOutput(currentOutput)
  File "/home/mgo/Desktop/SparseConvNet/PyTorch/sparseconvnet/legacy/validConvolution.py", line 46, in updateOutput
    torch.cuda.IntTensor() if input.features.is_cuda else nullptr)
  File "/home/mgo/miniconda2/lib/python2.7/site-packages/torch/utils/ffi/__init__.py", line 177, in safe_call
    result = torch._C._safe_call(*args, **kwargs)
torch.FatalError: cuda runtime error (8) : invalid device function at /py/conda-bld/pytorch_1493676237139/work/torch/lib/THC/generic/THCTensorMath.cu:35

P.S. I don't get any errors when I run hello-world.lua or VGGplus.lua or any other PyTorch example

Attribute Error When Running Examples

Hi Benjamin, thank you for your contribution of designing this wonderful SparseConvNet, and I have encountered a problem while running the examples provided by you, hopefully you can help me with it.

When I ran the scripts hello-world.py under SparseConvNet/examples or ResNet.py under SparseConvNet/examples/Assamese_handwriting/, there was a same attribute error:

File "/root/SparseConvNet/PyTorch/sparseconvnet/submanifoldConvolution.py", line 94, in forward
    output.features=ValidConvolutionFunction.apply(

The full traceback is: (take the ResNet.py case as an example)

File "ResNet.py", line 45, in <module>
    'check_point': True,})
  File "/root/SparseConvNet/PyTorch/sparseconvnet/classificationTrainValidate.py", line 90, in ClassificationTrainValidate
    output = model(batch['input'])
  File "/root/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.py", line 206, in __call__
    result = self.forward(*input, **kwargs)
  File "ResNet.py", line 29, in forward
    x = self.sparseModel(x)
  File "/root/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.py", line 206, in __call__
    result = self.forward(*input, **kwargs)
  File "/root/anaconda2/lib/python2.7/site-packages/torch/nn/modules/container.py", line 64, in forward
    input = module(input)
  File "/root/anaconda2/lib/python2.7/site-packages/torch/nn/modules/module.py", line 206, in __call__
    result = self.forward(*input, **kwargs)
  File "/root/SparseConvNet/PyTorch/sparseconvnet/submanifoldConvolution.py", line 94, in forward
    output.features=ValidConvolutionFunction.apply(
AttributeError: type object 'ValidConvolutionFunction' has no attribute 'apply'

After looking into the file submanifoldConvolution.py, I found that there is actually no apply that belongs to ValidConvolutionFunction, but there is a forward function whose API seems can fit here. However, the parameter number failed to match (the function requires 8 but only 7 are provided). I added self as the 1st parameter, but a new error raised.

I wonder how can I fix this problem? Thank you very much.

InputBatch's set_locations missing values

Adding a sample InputBatch and assigning data using set_locations is missing values.
Assigning data in a loop using set_location works correctly.

Reproducible example:

import numpy
import sparseconvnet as scn
import torch

spatial_dim = 2
spatial_shape = (10, 5)
mask = numpy.zeros(spatial_shape, dtype='uint8')
mask[:2, :2] = 1

locations = torch.LongTensor(numpy.stack(numpy.where(mask)).T)
features = torch.FloatTensor([[1, 2, 3], ] * 4)

input_ = scn.InputBatch(spatial_dim, torch.LongTensor(spatial_shape))

print("locations data")
print(locations)
print("features data")
print(features)

input_.add_sample()
input_.set_locations(locations, features)

print("SparseConvNetTensor")
print(input_)

output:

locations data
tensor([[ 0, 0],
[ 0, 1],
[ 1, 0],
[ 1, 1]])
features data
tensor([[ 1., 2., 3.],
[ 1., 2., 3.],
[ 1., 2., 3.],
[ 1., 2., 3.]])
SparseConvNetTensor
SparseConvNetTensor<<features=tensor([[ 1., 2., 3.],
[ 1., 2., 3.],
[ 1., 2., 3.]])coordinates=tensor([[ 0, 0, 0],
[ 1, 1, 0],
[ 0, 1, 0]])spatial size=tensor([ 10, 5])

or am I doing something wrong ?

Questions about implementing muti-branches network architecture.

I'm trying use Torch7 to implement a network that has muti-branches and applies its ith child module to the ith slice of the input. Since the input of the sparse convnet must be an 'InputBatch', I tried the Container nn.ParallelTable(), and put several 'InputBatch' into a table as the final input to the nn.ParallelTable(). But I got some error in backward procedure in function 'updateGradInput' where you made an annotation ' just call backward'.I'm not quiet sure what to do, should I just call 'backward' after your annotation? I tried this but got some other errors.Or should I implement a new ParallelTable which has 'backward' function?

Any suggestion or plan for speeding up hash table operation?

I find it takes a long time on CPU when the number of input points is large, though I have used precomputeMetaData and OMP. Most of the time is spent on the hash table operation, because libsparsehash runs on CPU and we process these data one-by-one.

I think it might be a common case in large-scale 3D CNN applications, so do you have any suggestion or plan for speeding up hash table operation? Such as using GPU-based hash table CUDPP, though I know it might not be an easy task to reimplement this project with CUDPP.

Implementation Details of SparseConvNet for CIFAR-10 Dataset

Hi Benjamin,

I am very interested in your paper "Spatially-sparse convolutional neural networks", which was published in 2014, and I am currently re-implementing your network for CIFAR-10 (I am currently implementing the "vanilla" sparse convnet without using fractional max pooling). While I have encountered several implementation problems, and since I failed to find a valid email address of you, I therefore posted my questions here. I am sorry for the inconvenience.

  1. In your paper you said that you designed a DeepCNiN (5, 300) network for this CIFAR-10 problem, which should have the following architecture:
Input - 300C3 - MP2 - 300C1 - 
          - 600C2 - MP2 - 600C1 -
          - 900C2 - MP2 - 900C1 - 
          - 1200C2- MP2 - 1200C1 -
          - 1500C2- MP2 - 1500C1 - 
          - 1800C2- 1800C1 - Softmax - Output

But in your code posted here, I found that you actually called addLeNetLayerROFMP (which first adds a Conv layer, then a NiN layer and then a ROFMP layer, whose order is different from that proposed in your paper) for 12 times and then addLeNetLayerMP for 2 times, finally a Softmax layer (the number of layers is also different). Since this architecture is different from the one you proposed in your paper, I wonder which one did you finally adopt and can yield the best result (or the result posted in your paper)?

  1. I wonder what is the initialization method that you used for the weight and bias (e.g. Gaussian distribution)? I didn't really find your code for this.

Thank you for your patience and help.

Type mismatch error in example code

I get the following error when I try to run the torch examples:

...sparseconvnet/SparseToDense.lua:39: bad argument #1 to 'size' (torch.CudaTensor expected, got boolean)

Stack Trace:

In 1 module of nn.Sequential:
In 4 module of sparseconvnet.Sequential:
...ch/install/share/lua/5.2/sparseconvnet/SparseToDense.lua:39: bad argument #1 to 'size' (torch.CudaTensor expected, got boolean)
stack traceback:
[C]: in function 'size'
...ch/install/share/lua/5.2/sparseconvnet/SparseToDense.lua:39: in function <...ch/install/share/lua/5.2/sparseconvnet/SparseToDense.lua:31>
[C]: in function 'xpcall'
/home/aa/torch/install/share/lua/5.2/nn/Container.lua:63: in function 'rethrowErrors'
...torch/install/share/lua/5.2/sparseconvnet/Sequential.lua:41: in function <...torch/install/share/lua/5.2/sparseconvnet/Sequential.lua:32>
[C]: in function 'xpcall'
/home/aa/torch/install/share/lua/5.2/nn/Container.lua:63: in function 'rethrowErrors'
/home/aa/torch/install/share/lua/5.2/nn/Sequential.lua:44: in function </home/aa/torch/install/share/lua/5.2/nn/Sequential.lua:41>
(...tail calls...)
...re/lua/5.2/sparseconvnet/ClassificationTrainValidate.lua:57: in function 'ClassificationTrainValidate'
VGGplus.lua:35: in main chunk
[C]: in function 'dofile'
...aa/torch/install/lib/luarocks/rocks/trepl/scm-1/bin/th:150: in main chunk
[C]: in ?

Pytorch examples run without any problems. Would you have any insight on this?

Conversely, do you have Pytorch examples for ModelNet40?

how to specify padding?

i don't see where to specify padding for convolutions?
when i create a dummy model with one layer, filter_size=3, filter_stride=1 and compute input_spatial_size for [10,10] output i get 12, 12, which seems to indicate padding = 0.

[Bug?] Segmentation fault when using scn.InputLayer with cuda

Problem

when I try to use scn.InputLayer to convert coors and features to SparseConvTensor, a Segmentation fault is produced.

Code to reproduce:

import torch 
import numpy as np
import sparseconvnet as scn
coors = np.concatenate([
    np.random.randint(0, 100, size=[500, 1]),
    np.random.randint(0, 200, size=[500, 1])
], axis=1).astype(np.int64)
# coors = np.zeros([500, 2], dtype=np.int64)
features = np.random.uniform(-1, 1, size=[500, 32]).astype(np.float32)
coors = torch.from_numpy(coors).cuda() # if without cuda, no problem
features = torch.from_numpy(features).cuda() # if without cuda, no problem
input_layer = scn.InputLayer(2, (100, 200), mode=1)
input_layer((coors, features))

Using ReLU without BatchNorm

Hey!

Thanks for this library, this could prove very useful for what I'm working on.

I'm trying to set up a simple ConvNet with Sparse convolutions but for activations I can only find BatchNormReLU. Is it possible to use a ReLU without BatchNorm?

My code:

        self.sparseModel = scn.Sequential()
        self.sparseModel.add(scn.ValidConvolution(2, 1, 16, 3, False))
        self.sparseModel.add(scn.BatchNormReLU(16))
        self.sparseModel.add(scn.MaxPooling(2, 3, 2))
        self.sparseModel.add(scn.ValidConvolution(2, 16, 8, 3, False))
        self.sparseModel.add(scn.BatchNormReLU(8))
        self.sparseModel.add(scn.MaxPooling(2, 3, 2))
        self.sparseModel.add(scn.SparseToDense(2,8))

Lars

build error with pytorch-1.0

Hi,
I try to compile this project with pytorch-1.0.
But it reports a lot of compiling error.

In file included from sparseconvnet/SCN/sparseconvnet_cuda.cpp:30:
sparseconvnet/SCN/CPU/Convolution.cpp: In Function ‘double cpu_Convolution_updateOutput(at::Tensor, at::Tensor, at::Tensor, at::Tensor, Metadata<Dimension>&, at::Tensor, at::Tensor, at::Tensor, at::Tensor)’:
sparseconvnet/SCN/CPU/Convolution.cpp:65:47: Error:‘struct at::Type’ has no member named ‘tensor’; did you mean ‘renorm’?
       auto input_rows = input_features.type().tensor({nRules, ip});
                                               ^~~~~~
                                               renorm

..... (lots of similar errors)

error: command 'gcc' failed with exit status 1

Speed up data preparation

I find my program spend most time in input.precomputeMetadata(precomputeStride), it spends about 9.3s, while forward and backward only spend 1.4s and 2.3s. So I replace the Convolution_InputSgsToRulesAndOutputSgs with Convolution_InputSgsToRulesAndOutputSgs_OMP, and recompile it.
But I find OMP version performs even worse, I takes about 9.5s.
My CPU info is:
CPU(s): 40
On-line CPU(s) list: 0-39
Thread(s) per core: 2
Core(s) per socket: 10
Socket(s): 2
My batch size is 4, and for a fair comparison, there are only 4 training data, so each time the loaded data are the same data.

So, have I done anything wrong, or anyone has suggestions about speeding up precomputeMetadata?
Thanks

22 errors detected in the compilation of "/tmp/tmpxft_00001a9c_00000000-6_cuda.cpp1.ii".

Hi,

I get the following error after running bash build.sh. Working on Ubuntu 16.04, Python 3.6 and Pytorch-1.0. Any idea how I could solve this?

Thank you!

sparseconvnet/SCN/CUDA/ActivePooling.cu(26): error: no instance of overloaded function "at::TypeExtendedInterface::tensor" matches the argument list
argument types are: ({...})
object type is: at::TypeExtendedInterface

sparseconvnet/SCN/CUDA/ActivePooling.cu(27): error: type name is not allowed

sparseconvnet/SCN/CUDA/ActivePooling.cu(27): error: expected an expression

sparseconvnet/SCN/CUDA/ActivePooling.cu(61): error: no instance of overloaded function "at::TypeExtendedInterface::tensor" matches the argument list
argument types are: ({...})
object type is: at::TypeExtendedInterface

22 errors detected in the compilation of "/tmp/tmpxft_00001a9c_00000000-6_cuda.cpp1.ii".
error: command '/usr/local/cuda/bin/nvcc' failed with exit status 1

torch version example problem

I am trying the torch version examples, th hello.lua, but get SparseToDense.lua:39: bad argument #1 to 'size' (torch.CudaTensor expected, got boolean), the pytorch version is OK.
I remember that I have successfully running the torch version examples, so I think this error may be caused by some updates of torch or others, then I tried several versions of torch, but this error still happens.

AttributeError: 'int' object has no attribute 'item'

hi,
when i run hello_world.py, I got a error:
File "/home/XXX/software/anaconda2/envs/pytorch_py3/lib/python3.6/site-packages/sparseconvnet-0.1.1-py3.6.egg/sparseconvnet/submanifoldConvolution.py", line 22, in init
self.filter_volume = self.filter_size.prod().item()
AttributeError: 'int' object has no attribute 'item'
How can I deal with. Thanks

why is output size same as input size?

I am running the hello world, I do not understand why inputing a spatial size of 10x10 leads to an output spatial size of 10x10. Shouldn't the downsizing reduce those?

fatal error: torch/extension.h: No such file or directory #include <torch/extension.h>

gcc-5 and pytorch 0.4.1 got this error. more messages:

➜  SparseConvNet git:(master) ✗ sudo python3 setup.py install         
running install
running bdist_egg
running egg_info
writing sparseconvnet.egg-info/PKG-INFO
writing dependency_links to sparseconvnet.egg-info/dependency_links.txt
writing top-level names to sparseconvnet.egg-info/top_level.txt
package init file 'sparseconvnet/SCN/__init__.py' not found (or not a regular file)
reading manifest file 'sparseconvnet.egg-info/SOURCES.txt'
writing manifest file 'sparseconvnet.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_py
running build_ext
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/local/include -.o -std=c++11 -fopenmp -DTORCH_EXTENSION_NAME=SCN -D_GLIBCXX_USE_CXX11_ABI=0
sparseconvnet/SCN/sparseconvnet_cuda.cpp:14:10: fatal error: torch/extension.h: No such file or directory
 #include <torch/extension.h>
          ^~~~~~~~~~~~~~~~~~~
compilation terminated.
error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

How to use SparseConvNet in the Imagenet data?

@btgraham Hi, I am very interested in your paper "Spatially-sparse convolutional neural networks",too. But 1. I don't know how to implement the network that trains Imagenet data by using “ facebookresearch/SparseConvNet”, beacuse of the fact how images are as the input of networks.
2. what's the different between sparse comv and original conv?
3. why is it improved that using sparseconv on the imagenet or kaggle diabetic data?
thank you!

Tiny Bugs and Questions in Convolution and Deconvolution

Hi, thanks for your awesome framework. I really want to apply it in my own 3D detection problem.

I notice some potential bugs when I reading the source code.

The first one is

if ctx.bias is None:
grad_bias=None
else:
grad_bias = Variable(grad_output.data.new().resize_as_(bias).zero_())
if ctx.bias is None:
grad_bias=None
else:
grad_bias = Variable(grad_output.data.new().resize_as_(ctx.bias).zero_())

Line 57- Line 60 seem to be redundant and worse, bias is actually not defined.

Another one is

def input_spatial_size(self, out_size):
return (out_size - 1) * self.filter_stride + self.filter_size

According to my understanding, this function should output expected input size given output size. The calculation here seems to belong to convolution, not deconvolution.

And possibly, spatial size checking should be added to make sure the inputs to JoinTable and AddTable are compatible.

Finally, I have some questions about deconvolution.

  1. How deconvoution decides its active sites of output. Does it retrieve the rulebook saved earlier, which is generated by a former convolution of the same spatial size.
  2. Take segmentation as an example, if my whole network are built by this sparse framework, does it mean that both of my input and output are sparse?

Python Module Failing

Hi,

First, great work! However I'm trying to get the Python examples running but hitting this error:

Traceback (most recent call last):
  File "hello-world.py", line 8, in <module>
    import sparseconvnet.legacy as scn
  File "/.../local/lib/python2.7/site-packages/sparseconvnet/legacy/__init__.py", line 7, in <module>
    from ..utils import *
  File /.../local/lib/python2.7/site-packages/sparseconvnet/utils.py", line 8, in <module>
    import sparseconvnet.SCN as scn
  File "/.../local/lib/python2.7/site-packages/sparseconvnet/SCN/__init__.py", line 3, in <module>
    from ._SCN import lib as _lib, ffi as _ffi
ImportError: No module named _SCN

Could this be a missing config in setup.py? Seems like the ._SCN module isn't built or copied over. Any help is appreciated.

Cheers

'getSpatialLocations' return strange values

I use getSpatialLocations() to get the locations of features, but I find the returned values contain many (0,0,0,0). However, locations should be unique and not repeat.
I trace the codes, and I think this line and this line should be changed to
lD[(it->second + SGs[i].ctr) * (Dimension + 1) + d] = it->first[d];
lD[(it->second + SGs[i].ctr)* (Dimension + 1) + Dimension] = i;
Otherwise, locations of latter sample will overwrite locations of previous sample, and this will left many values in lD not be written.

Installing/Building in docker (running with cuda)

I encounter an issue when the installation instructions are part of a Dockerfile.
When using docker build, everything seems ok during build but at run time (docker run --runtime=nvidia ...) trying to run the hello_world.py example yields segmentation fault.

Though nvcc should be able to build without dependency in the driver runtime, I've made 2 tests:

  1. If I manually re-install/build SparseConvNet after running the container with --runtime=nvidia, the hello_world example runs fine.
  2. Doing the same by running the container but this time without --runtime=nvidia and manually re-installing/building SparseConvNet, yields segmentation fault upon running the hello-world example

Has anyone had an issue building into a docker image?

Permutohedral lattice support

Hi,

Do you think this implementation could be easily adapted to work with sparse permutohedral lattices ? As discussed in 1 2. I know both rely on efficient Hash Tables, so maybe there is an easy way to achieve this.

Thanks in advance,
Lucas

ValidConvolution generates same features twice

When I changed the example hello-world.py

msg = [
" X  "
"XXX "
"    "]

Then forwarding the input to one ValidConvolution generates 8 features not 4, and it results in exact duplicates.

scn.ValidConvolution(2, 1, 7, 3, False)(input)

SparseConvNetTensor<<Variable containing:
 0.8005  1.0915  0.1243  0.2239 -2.0065  2.4473  0.7704
-0.0807  0.8334  0.7881  0.9474 -1.2600  0.9929  1.4385
-0.9909  0.2812 -0.8543  0.7658 -1.7169  1.6085  1.5675
-0.7380 -0.0175 -1.5790  0.8088 -0.6446  1.7917 -0.0282
 0.8005  1.0915  0.1243  0.2239 -2.0065  2.4473  0.7704
-0.0807  0.8334  0.7881  0.9474 -1.2600  0.9929  1.4385
-0.9909  0.2812 -0.8543  0.7658 -1.7169  1.6085  1.5675
-0.7380 -0.0175 -1.5790  0.8088 -0.6446  1.7917 -0.0282
[torch.FloatTensor of size 8x7]
<<Metadata:dim=2, p=94189934691952>>
 12
  9
[torch.LongTensor of size 2]
>>

The first 4 rows and rows 5-8 are exactly the same features.
Within the ValidConvolutionRule.h, the rulebook contains a duplicate rule for features 4-7.

(gdb) p rules
$1 = std::vector of length 9, capacity 9 = {
std::vector of length 4, capacity 4 = {0, 3, 4, 7},
std::vector of length 4, capacity 4 = {0, 2, 4, 6},
  std::vector of length 4, capacity 4 = {0, 1, 4, 5},
  std::vector of length 8, capacity 8 = {2, 3, 1, 2, 6, 7, 5, 6},
  std::vector of length 16, capacity 16 = {3, 3, 1, 1, 2, 2, 0, 0, 7, 7, 5, 5, 6, 6, 4, 4}, 
  std::vector of length 8, capacity 8 = {2, 1, 3, 2, 6, 5, 7, 6},
  std::vector of length 4, capacity 4 = {1, 0, 5, 4},
  std::vector of length 4, capacity 4 = {2, 0, 6, 4},
  std::vector of length 4, capacity 4 = {3, 0, 7, 4}}

Is there a reason for computing the exact same features twice?

scn.BatchNormalization does not produce results like nn.BatchNorm2d

Reproducible code:

import numpy
import sparseconvnet as scn
import torch
from torch import nn

spatial_dim = 2
spatial_shape = (500, 1000)
mask = numpy.zeros(spatial_shape, dtype='uint8')
mask[200:400, 400:600] = 1


dim = 2
inplanes = 3
outplanes = 1
# NOTE: transpose yields indices to be f-contiguous instead of c-contiguous.
# set_locations assumes c-contiguous and converts to c-contiguous when it's not.
# for performance make sure locations (and features) input is c-contiguous
i, j = numpy.where(mask)
n_sites = len(i)
ij = numpy.hstack([i.reshape(-1, 1), j.reshape(-1, 1)])
locations = torch.LongTensor(ij)
features = torch.FloatTensor([[1, 2, 3], ] * n_sites)

sparse_input = scn.InputBatch(spatial_dim, torch.LongTensor(spatial_shape))

sparse_input.add_sample()
assert locations.is_contiguous()
assert features.is_contiguous()
sparse_input.set_locations(locations, features)

dense_input = scn.SparseToDense(dim, inplanes)(sparse_input)


sparse_model = scn.Sequential()
sparse_model.add_module('bn1', scn.BatchNormalization(inplanes, eps=1e-5, momentum=0.1))
sparse_model.add_module('relu1', scn.ReLU())
sparse_model.add_module('conv1', scn.SubmanifoldConvolution(dim, inplanes, outplanes, 1, False))

dense_model = nn.Sequential()
dense_model.add_module('bn1', nn.BatchNorm2d(inplanes, eps=1e-5, momentum=0.1))
dense_model.add_module('relu1', nn.ReLU(inplace=True))
dense_model.add_module('conv1', nn.Conv2d(inplanes, outplanes, kernel_size=1, bias=False))

# set all parameters values to 1 for comparison
for dp, sp in zip(dense_model.parameters(), sparse_model.parameters()):
    sp.data.copy_(torch.ones_like(sp.data))
    dp.data.copy_(torch.ones_like(dp.data))
dense_output = dense_model(dense_input)
sparse_output = sparse_model(sparse_input)


do = dense_output.squeeze().detach()
so = scn.SparseToDense(dim, outplanes)(sparse_output).squeeze().detach()
print("All close:")
print(numpy.allclose(do, so))

# or stack first plane for convinience
stacked_output = numpy.vstack([do, so])
#  matshow(stacked_output)

Output is False.
If bn lines are commented out, output becomes True.

Should I expect same outputs with both versions?

TriangLeNet

Hi,

in your Paper "Sparse 3D convolutional neural networks" you stated that you have compared a network with triangular kernels against a kernel with quadric kernels.

Is there any implementation of the triangular version available for PyTorch or could you give some hints towards how to implement it?

Thanks!

Problem with Deconvolution Python

Hello,
In SparseConvNet/PyTorch/sparseconvnet/legacy/deconvolution.py it appears that method suggestInputSize(...) is missing the "return", causing crash.
Best regards.

sparseconvnet/SCN/sparseconvnet_cuda.cpp:14:29: fatal error: torch/extension.h: No such file or directory

any help please?

Here is complete log.

running install
running bdist_egg
running egg_info
creating sparseconvnet.egg-info
writing sparseconvnet.egg-info/PKG-INFO
writing top-level names to sparseconvnet.egg-info/top_level.txt
writing dependency_links to sparseconvnet.egg-info/dependency_links.txt
writing manifest file 'sparseconvnet.egg-info/SOURCES.txt'
package init file 'sparseconvnet/SCN/__init__.py' not found (or not a regular file)
reading manifest file 'sparseconvnet.egg-info/SOURCES.txt'
writing manifest file 'sparseconvnet.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
running build_py
creating build
creating build/lib.linux-x86_64-3.5
creating build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/identity.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/__init__.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/sparseToDense.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/unPooling.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/batchNormalization.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/sparseConvNetTensor.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/randomizedStrideMaxPooling.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/inputBatch.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/permutohedralSubmanifoldConvolution.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/spectral_norm.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/activations.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/averagePooling.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/submanifoldConvolution.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/metadata.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/sparsify.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/fullConvolution.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/randomizedStrideConvolution.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/networkInNetwork.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/maxPooling.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/networkArchitectures.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/classificationTrainValidate.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/utils.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/deconvolution.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/tables.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/ioLayers.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/convolution.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/denseToSparse.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/dropout.py -> build/lib.linux-x86_64-3.5/sparseconvnet
copying sparseconvnet/sequential.py -> build/lib.linux-x86_64-3.5/sparseconvnet
running build_ext
building 'sparseconvnet.SCN' extension
creating build/temp.linux-x86_64-3.5
creating build/temp.linux-x86_64-3.5/sparseconvnet
creating build/temp.linux-x86_64-3.5/sparseconvnet/SCN
/usr/local/cuda/bin/nvcc -I/home/keti/venv-tv/include -I/home/keti/Project/second.pytorch/SparseConvNet/sparseconvnet/SCN/ -I/home/keti/venv-tv/lib/python3.5/site-packages/torch/lib/include -I/home/keti/venv-tv/lib/python3.5/site-packages/torch/lib/include/TH -I/home/keti/venv-tv/lib/python3.5/site-packages/torch/lib/include/THC -I/usr/local/cuda/include -I/usr/include/python3.5m -I/home/keti/venv-tv/include/python3.5m -c sparseconvnet/SCN/cuda.cu -o build/temp.linux-x86_64-3.5/sparseconvnet/SCN/cuda.o -std=c++11 -Xcompiler -fopenmp -DTORCH_EXTENSION_NAME=SCN -D_GLIBCXX_USE_CXX11_ABI=0 --compiler-options '-fPIC'
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/home/keti/venv-tv/include -I/home/keti/Project/second.pytorch/SparseConvNet/sparseconvnet/SCN/ -I/home/keti/venv-tv/lib/python3.5/site-packages/torch/lib/include -I/home/keti/venv-tv/lib/python3.5/site-packages/torch/lib/include/TH -I/home/keti/venv-tv/lib/python3.5/site-packages/torch/lib/include/THC -I/usr/local/cuda/include -I/usr/include/python3.5m -I/home/keti/venv-tv/include/python3.5m -c sparseconvnet/SCN/sparseconvnet_cuda.cpp -o build/temp.linux-x86_64-3.5/sparseconvnet/SCN/sparseconvnet_cuda.o -std=c++11 -fopenmp -DTORCH_EXTENSION_NAME=SCN -D_GLIBCXX_USE_CXX11_ABI=0
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
sparseconvnet/SCN/sparseconvnet_cuda.cpp:14:29: fatal error: torch/extension.h: No such file or directory
compilation terminated.
error: command 'x86_64-linux-gnu-gcc' failed with exit status 1

convolution with groups?

Is there a way for applying convolution with groups to implement a sparse Xception or ResNeXT model?

I think this would be useful since sparsity is often greater considering the entire volume of features rather than just spatial sites.

Cuda zeros output values

Hello,

When i run the examples on cpu, everything works fine.
When i use cuda however, training is not making any progress (loss stays roughly the same).

I figured out, that on cuda modules like SubmanifoldConvolution and BatchNormReLU return only zeros.
scn_cuda_bug_demo.py

Any Ideas?

I'm using python 3.5, cuda9.0 and pytorch0.4.0.
Plain PyTorch works fine both on cpu and cuda.

AttributeError: module 'sparseconvnet.SCN' has no attribute 'Metadata_2'

I've fixed the above problem.
But now I got trouble with sparseconvnet, after I compile it with gcc 5.4 and pytorch 1.0, it said:
Installed /data-sdb/benjin.zhu/libs/anaconda3.6/lib/python3.6/site-packages/sparseconvnet-0.2-py3.6-linux-x86_64.egg Processing dependencies for sparseconvnet==0.2 Finished processing dependencies for sparseconvnet==0.2

but then I tried python examples/hello-world.py, I got
$ python examples/hello-world.py Traceback (most recent call last): File "examples/hello-world.py", line 30, in input = scn.InputBatch(2, inputSpatialSize) File "/data-sdb/benjin.zhu/second/SparseConvNet/sparseconvnet/inputBatch.py", line 19, in init self.metadata = Metadata(dimension) File "/data-sdb/benjin.zhu/second/SparseConvNet/sparseconvnet/metadata.py", line 17, in Metadata return getattr(sparseconvnet.SCN, 'Metadata_%d' % dim)() AttributeError: module 'sparseconvnet.SCN' has no attribute 'Metadata_2'

This stucks me for a long time.

Error when using second GPU

Hello,

I have 2 GPUs in my computer. When I want to use the second one for a SCN, I get errors similar to:

RuntimeError: cublas runtime error : library not initialized at /opt/conda/conda-bld/pytorch_1525909934016/work/aten/src/THC/THCGeneral.cpp:411
THCudaCheck FAIL file=/opt/conda/conda-bld/pytorch_1525909934016/work/aten/src/THC/generic/THCTensorCopy.c line=70 error=77 : an illegal memory access was encountered

Simple code:

import torch
import torch.nn as nn
import sparseconvnet as scn

device = 'cuda:1'  # doesn't work for the scn model
# device = 'cuda:0'  # does work
# device = 'cpu'     # does work

class Model_SCN(nn.Module):

    def __init__(self):
        nn.Module.__init__(self)

        inputSpatialSize = [32, 32, 32]
        dimension = 3
        self.sparseModel = scn.Sequential().add(
           scn.InputLayer(dimension, inputSpatialSize, mode=2)).add(
           scn.OutputLayer(dimension))

    def forward(self, x):
        x = self.sparseModel(x)
        return x

class Model(nn.Module):

    def __init__(self):
        nn.Module.__init__(self)

        self.fc1 = nn.Linear(2, 2)

    def forward(self, x):
        x = self.fc1(x)
        return x

model = Model()
model = model.to(device)
model_scn = Model_SCN()
model_scn = model_scn.to(device)

coords = torch.tensor([[0, 0, 0], [1, 0, 0]], device=device, dtype=torch.long)
features = torch.tensor([[1], [1]], device=device, dtype=torch.float)

output_scn = model_scn((coords, features))
output = model(features.squeeze())

Normal PyTorch nets as well as SCNs on cpu or cuda:0 work just fine.
I'm using python 3.5, cuda9.0 and pytorch0.4.0 on ubuntu.

Examples for U-net

I'm pretty interesting how to construct a U-net with SparseConv. Would you mind provide an example of sparse U-net?

3d_segmentation ShapeNet: scaling x 4

Hi!
I am a little confused with the following line:
https://github.com/facebookresearch/SparseConvNet/blob/master/examples/3d_segmentation/data.py#L80

xl=np.floor(resolution*(4+xl)).astype('int64')

It looks like input points first were transposed far from zero point and are scaled after. As the result all samples are placed far from center.
While, in the paper described that each point cloud centered and re-scaled to fit into a sphere with diameter 4S.

Is it ok that point clouds are not centered? Or to guarantee that all values are positive?

Import Error:

Hi there, I have installed your amazing library with the following command (on Pytorch):

sudo apt-get install libsparsehash-dev
python setup.py develop

I think the library was installed correctly, but when I want to import sparseconvnet package, the error bellow has happened:

ImportError: /home/mohammad/SparseConvNet-master/PyTorch/sparseconvnet/SCN/_SCN.so: undefined symbol: _ZNSt12length_errorC1EPKc

Could you please help me how can I solve this problem?

Empty output when using scn.Deconvolution

Hi! I'm trying to use the deconvolution layer, but I got an empty output.
My code is:

import torch, sparseconvnet as scn
deconv = scn.Deconvolution(2, 1, 1, 3, 1, False).cuda()
print(deconv.weight)
input=scn.InputBatch(2, 5)
input.add_sample()
input.set_location(torch.LongTensor([1, 1]), torch.FloatTensor([1]), 0)
input.set_location(torch.LongTensor([2, 3]), torch.FloatTensor([1]), 0)
input.set_location(torch.LongTensor([3, 2]), torch.FloatTensor([1]), 0)
input.cuda()
print(deconv(input))

Then I got the result:

Parameter containing:
tensor([[[-0.2356]],

        [[-0.5641]],

        [[-0.6885]],

        [[ 0.0216]],

        [[-1.1243]],

        [[ 0.3640]],

        [[-0.2336]],

        [[ 0.1309]],

        [[-0.4607]]], device='cuda:0')
SparseConvNetTensor<<features=tensor([], device='cuda:0')coordinates=tensor([], dtype=torch.int64)spatial size=tensor([ 7,  7])>>

I use pytorch 0.4 and cuda 9.0.
Thanks for your help!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.