Skip to content

Commit

Permalink
minor doc fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
chrischoy committed Jan 27, 2020
1 parent 298095c commit c8a4bbf
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 107 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Change Log

## [master] - 2020-01-22
## [0.4.0] - 2020-01-26

### Added

Expand Down
70 changes: 34 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@

The Minkowski Engine is an auto-differentiation library for sparse tensors. It supports all standard neural network layers such as convolution, pooling, unpooling, and broadcasting operations for sparse tensors. For more information, please visit [the documentation page](http://stanfordvl.github.io/MinkowskiEngine/overview.html).

## Example Networks

The Minkowski Engine supports various functions that can be built on a sparse tensor. We list a few popular network architectures and applications here. To run the examples, please install the package and run the command in the package root directory.

| Examples | Networks and Commands |
|:---------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
| Semantic Segmentation | <img src="https://stanfordvl.github.io/MinkowskiEngine/_images/segmentation_3d_net.png"> <br /> <img src="https://stanfordvl.github.io/MinkowskiEngine/_images/segmentation.png" width="256"> <br /> `python -m examples.indoor` |
| Classification | ![](https://stanfordvl.github.io/MinkowskiEngine/_images/classification_3d_net.png) <br /> `python -m examples.modelnet40` |
| Reconstruction | <img src="https://stanfordvl.github.io/MinkowskiEngine/_images/generative_3d_net.png"> <br /> <img src="https://stanfordvl.github.io/MinkowskiEngine/_images/generative_3d_results.gif" width="256"> <br /> `python -m examples.reconstruction` |


## Building a Neural Network on a Sparse Tensor

The Minkowski Engine provides APIs that allow users to build a neural network on a sparse tensor. Then, how dow we define convolution/pooling/transposed operations on a sparse tensor?
Expand Down Expand Up @@ -127,41 +138,39 @@ function (`MinkowskiEngine.utils.sparse_quantize`).
### Creating a Network

```python
import torch.nn as nn
import MinkowskiEngine as ME

class ExampleNetwork(ME.MinkowskiNetwork):

def __init__(self, in_feat, out_feat, D):
super(ExampleNetwork, self).__init__(D)
self.conv1 = ME.MinkowskiConvolution(
in_channels=in_feat,
out_channels=64,
kernel_size=3,
stride=2,
dilation=1,
has_bias=False,
dimension=D)
self.bn1 = ME.MinkowskiBatchNorm(64)
self.conv2 = ME.MinkowskiConvolution(
in_channels=64,
out_channels=128,
kernel_size=3,
stride=2,
dimension=D)
self.bn2 = ME.MinkowskiBatchNorm(128)
self.conv1 = nn.Sequential(
ME.MinkowskiConvolution(
in_channels=in_feat,
out_channels=64,
kernel_size=3,
stride=2,
dilation=1,
has_bias=False,
dimension=D),
ME.MinkowskiBatchNorm(64),
ME.MinkowskiReLU())
self.conv2 = nn.Sequential(
ME.MinkowskiConvolution(
in_channels=64,
out_channels=128,
kernel_size=3,
stride=2,
dimension=D),
ME.MinkowskiBatchNorm(128),
ME.MinkowskiReLU())
self.pooling = ME.MinkowskiGlobalPooling(dimension=D)
self.linear = ME.MinkowskiLinear(128, out_feat)
self.relu = ME.MinkowskiReLU(inplace=True)

def forward(self, x):
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)

out = self.conv2(out)
out = self.bn2(out)
out = self.relu(out)

out = self.pooling(out)
return self.linear(out)
```
Expand All @@ -184,18 +193,6 @@ class ExampleNetwork(ME.MinkowskiNetwork):
loss = criterion(output.F, label)
```


### Running the Examples

After installing the package, run `python -m examples.example` in the package root directory. There are many more examples, but here's a gist of some of exciting examples. To run them, simply type the command below an example image in terminal.

| Example | Figures and Commands |
|:---------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
| Semantic Segmentation | <p align="center"> <img src="https://stanfordvl.github.io/MinkowskiEngine/_images/segmentation.png" width="256"> </p> <br /> `python -m examples.indoor` |
| Classification | ![](https://stanfordvl.github.io/MinkowskiEngine/_images/classification_3d_net.png) <br /> `python -m examples.modelnet40` |
| Reconstruction | <p align="center"> <img src="https://stanfordvl.github.io/MinkowskiEngine/_images/generative_3d_net.png"> <br /> <img src="https://stanfordvl.github.io/MinkowskiEngine/_images/generative_3d_results.gif" width="256"> </p> <br /> `python -m examples.reconstruction` |


## Discussion and Documentation

For discussion and questions, please use `minkowskiengine@googlegroups.com`.
Expand Down Expand Up @@ -223,7 +220,8 @@ If you use the Minkowski Engine, please cite:
}
```

## Projects using MinkowskiEngine
## Projects using Minkowski Engine

- [4D Spatio-Temporal Segmentation](https://github.com/chrischoy/SpatioTemporalSegmentation)
- [Fully Convolutional Geometric Features, ICCV'19](https://github.com/chrischoy/FCGF)
- [Learning multiview 3D point cloud registration](https://arxiv.org/abs/2001.05119)
Binary file modified docs/images/classification_3d_net.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/segmentation_3d_net.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
73 changes: 36 additions & 37 deletions docs/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,27 @@

The Minkowski Engine is an auto-differentiation library for sparse tensors. It supports all standard neural network layers such as convolution, pooling, unpooling, and broadcasting operations for sparse tensors. For more information, please visit [the documentation page](http://stanfordvl.github.io/MinkowskiEngine/overview.html).

## Example Networks

The Minkowski Engine supports various functions that can be built on a sparse tensor. We list a few popular network architectures and applications here. To run the examples, please install the package and run the command in the package root directory.

| Examples | Networks and Commands |
|:---------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
| Semantic Segmentation | <img src="https://stanfordvl.github.io/MinkowskiEngine/_images/segmentation_3d_net.png"> <br /> <img src="https://stanfordvl.github.io/MinkowskiEngine/_images/segmentation.png" width="256"> <br /> `python -m examples.indoor` |
| Classification | ![](https://stanfordvl.github.io/MinkowskiEngine/_images/classification_3d_net.png) <br /> `python -m examples.modelnet40` |
| Reconstruction | <img src="https://stanfordvl.github.io/MinkowskiEngine/_images/generative_3d_net.png"> <br /> <img src="https://stanfordvl.github.io/MinkowskiEngine/_images/generative_3d_results.gif" width="256"> <br /> `python -m examples.reconstruction` |


## Building a Neural Network on a Sparse Tensor

The Minkowski Engine provides APIs that allow users to build a neural network on a sparse tensor. Then, how dow we define convolution/pooling/transposed operations on a sparse tensor?
Visually, a convolution on a sparse tensor is similar to that on a dense tensor. However, on a sparse tensor, we compute convolution output on a few specified points. For more information, please visit [convolution on a sparse tensor](https://stanfordvl.github.io/MinkowskiEngine/convolution_on_sparse.html)
Visually, a convolution on a sparse tensor is similar to that on a dense tensor. However, on a sparse tensor, we compute convolution outputs on a few specified points. For more information, please visit [convolution on a sparse tensor](https://stanfordvl.github.io/MinkowskiEngine/convolution_on_sparse.html)

| Dense Tensor | Sparse Tensor |
|:-----------------------------:|:-----------------------------:|
| ![](./_images/conv_dense.gif) |![](./_images/conv_sparse.gif) |


--------------------------------------------------------------------------------

## Features
Expand Down Expand Up @@ -127,41 +139,39 @@ function (`MinkowskiEngine.utils.sparse_quantize`).
### Creating a Network

```python
import torch.nn as nn
import MinkowskiEngine as ME

class ExampleNetwork(ME.MinkowskiNetwork):

def __init__(self, in_feat, out_feat, D):
super(ExampleNetwork, self).__init__(D)
self.conv1 = ME.MinkowskiConvolution(
in_channels=in_feat,
out_channels=64,
kernel_size=3,
stride=2,
dilation=1,
has_bias=False,
dimension=D)
self.bn1 = ME.MinkowskiBatchNorm(64)
self.conv2 = ME.MinkowskiConvolution(
in_channels=64,
out_channels=128,
kernel_size=3,
stride=2,
dimension=D)
self.bn2 = ME.MinkowskiBatchNorm(128)
self.conv1 = nn.Sequential(
ME.MinkowskiConvolution(
in_channels=in_feat,
out_channels=64,
kernel_size=3,
stride=2,
dilation=1,
has_bias=False,
dimension=D),
ME.MinkowskiBatchNorm(64),
ME.MinkowskiReLU())
self.conv2 = nn.Sequential(
ME.MinkowskiConvolution(
in_channels=64,
out_channels=128,
kernel_size=3,
stride=2,
dimension=D),
ME.MinkowskiBatchNorm(128),
ME.MinkowskiReLU())
self.pooling = ME.MinkowskiGlobalPooling(dimension=D)
self.linear = ME.MinkowskiLinear(128, out_feat)
self.relu = ME.MinkowskiReLU(inplace=True)

def forward(self, x):
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)

out = self.conv2(out)
out = self.bn2(out)
out = self.relu(out)

out = self.pooling(out)
return self.linear(out)
```
Expand All @@ -184,18 +194,6 @@ class ExampleNetwork(ME.MinkowskiNetwork):
loss = criterion(output.F, label)
```


### Running the Examples

After installing the package, run `python -m examples.example` in the package root directory. There are many more examples, but here's a gist of some of exciting examples. To run them, simply type the command below an example image in terminal.

| Example | Figures and Code |
|:---------------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
| Semantic Segmentation | <p align="center"> <img src="https://stanfordvl.github.io/MinkowskiEngine/_images/segmentation.png" width="256"> </p> <br /> `python -m examples.indoor` |
| Classification | ![](https://stanfordvl.github.io/MinkowskiEngine/_images/classification_3d_net.png) <br /> `python -m examples.modelnet40` |
| Reconstruction | <p align="center"> <img src="https://stanfordvl.github.io/MinkowskiEngine/_images/generative_3d_net.png"> <br /> <img src="https://stanfordvl.github.io/MinkowskiEngine/_images/generative_3d_results.gif" width="256"> </p> ![]() <br /> `python -m examples.reconstruction` |


## Discussion and Documentation

For discussion and questions, please use `minkowskiengine@googlegroups.com`.
Expand Down Expand Up @@ -223,7 +221,8 @@ If you use the Minkowski Engine, please cite:
}
```

## Projects using MinkowskiEngine
## Projects using Minkowski Engine

- [4D Spatio-Temporal Segmentation](https://github.com/chrischoy/SpatioTemporalSegmentation)
- [Fully Convolutional Geometric Features, ICCV'19](https://github.com/chrischoy/FCGF)
- [Learning multiview 3D point cloud registration](https://arxiv.org/abs/2001.05119)
23 changes: 8 additions & 15 deletions examples/indoor.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,21 +131,14 @@ def generate_input_sparse_tensor(file_name, voxel_size=0.05):

# Measure time
with torch.no_grad():
for voxel_size in [0.1, 0.05, 0.02]:
timer = Timer()
coordinates, features = generate_input_sparse_tensor(
config.file_name, voxel_size=voxel_size)

# Feed-forward pass and get the prediction
for i in range(4):
timer.tic()
sinput = ME.SparseTensor(
features, coords=coordinates).to(device)
soutput = model(sinput)
timer.toc()
print(
f'Time to process a room with {voxel_size}m voxel downsampling '
f'containing {len(sinput)} voxels: {timer.min_time}')
voxel_size = 0.02
coordinates, features = generate_input_sparse_tensor(
config.file_name, voxel_size=voxel_size)

# Feed-forward pass and get the prediction
sinput = ME.SparseTensor(
features, coords=coordinates).to(device)
soutput = model(sinput)

# Feed-forward pass and get the prediction
coordinates, features = soutput.decomposed_coordinates_and_features
Expand Down
25 changes: 7 additions & 18 deletions examples/reconstruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,8 @@ def PointCloud(points, colors=None):


def collate_pointcloud_fn(list_data):
new_list_data = []
num_removed = 0
for data in list_data:
if data is not None:
new_list_data.append(data)
else:
num_removed += 1

list_data = new_list_data

if len(list_data) == 0:
raise ValueError('No data in the batch')

coords, feats, labels = list(zip(*list_data))

eff_num_batch = len(coords)
assert len(labels) == eff_num_batch

# Concatenate all lists
return {
'coords': coords,
Expand Down Expand Up @@ -212,6 +196,7 @@ def make_data_loader(phase, augment_data, batch_size, shuffle, num_workers,
'--weights', type=str, default='modelnet_reconstruction.pth')
parser.add_argument('--load_optimizer', type=str, default='true')
parser.add_argument('--train', action='store_true')
parser.add_argument('--max_visualization', type=int, default=4)

###############################################################################
# End of utility functions
Expand Down Expand Up @@ -499,7 +484,6 @@ def train(net, dataloader, device, config):

optimizer.zero_grad()
init_coords = torch.zeros((config.batch_size, 4), dtype=torch.int)
# Batch index
init_coords[:, 0] = torch.arange(config.batch_size)

in_feat = torch.zeros((config.batch_size, in_nchannel))
Expand Down Expand Up @@ -557,10 +541,11 @@ def visualize(net, dataloader, device, config):
in_nchannel = len(dataloader.dataset)
net.eval()
crit = nn.BCEWithLogitsLoss()
n_vis = 0

for data_dict in dataloader:

init_coords = torch.zeros((config.batch_size, 4), dtype=torch.int)
# Batch index
init_coords[:, 0] = torch.arange(config.batch_size)

in_feat = torch.zeros((config.batch_size, in_nchannel))
Expand Down Expand Up @@ -599,6 +584,10 @@ def visualize(net, dataloader, device, config):
opcd.rotate(M)
o3d.visualization.draw_geometries([pcd, opcd])

n_vis += 1
if n_vis > config.max_visualization:
return


if __name__ == '__main__':
config = parser.parse_args()
Expand Down

0 comments on commit c8a4bbf

Please sign in to comment.