|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import torch |
|
|
|
|
|
import MinkowskiEngine as ME |
|
|
|
|
|
from tests.python.common import data_loader |
|
|
|
|
|
|
|
|
def get_random_coords(dimension=2, tensor_stride=2): |
|
|
torch.manual_seed(0) |
|
|
|
|
|
coords = torch.rand(10, dimension + 1) |
|
|
coords[:, :dimension] *= 5 |
|
|
coords[:, -1] *= 2 |
|
|
coords = coords.floor().int() |
|
|
coords = ME.utils.sparse_quantize(coords) |
|
|
coords[:, :dimension] *= tensor_stride |
|
|
return coords, tensor_stride |
|
|
|
|
|
|
|
|
def print_sparse_tensor(tensor): |
|
|
for c, f in zip(tensor.C.numpy(), tensor.F.detach().numpy()): |
|
|
print(f"Coordinate {c} : Feature {f}") |
|
|
|
|
|
|
|
|
def conv(): |
|
|
in_channels, out_channels, D = 2, 3, 2 |
|
|
coords, feats, labels = data_loader(in_channels, batch_size=1) |
|
|
|
|
|
|
|
|
input = ME.SparseTensor(features=feats, coordinates=coords) |
|
|
conv = ME.MinkowskiConvolution( |
|
|
in_channels, |
|
|
out_channels, |
|
|
kernel_size=3, |
|
|
stride=2, |
|
|
bias=False, |
|
|
dimension=D) |
|
|
|
|
|
output = conv(input) |
|
|
|
|
|
print('Input:') |
|
|
print_sparse_tensor(input) |
|
|
|
|
|
print('Output:') |
|
|
print_sparse_tensor(output) |
|
|
|
|
|
|
|
|
strided_coords, tensor_stride = get_random_coords() |
|
|
|
|
|
input = ME.SparseTensor( |
|
|
features=torch.rand(len(strided_coords), in_channels), |
|
|
coordinates=strided_coords, |
|
|
tensor_stride=tensor_stride) |
|
|
conv_tr = ME.MinkowskiConvolutionTranspose( |
|
|
in_channels, |
|
|
out_channels, |
|
|
kernel_size=3, |
|
|
stride=2, |
|
|
bias=False, |
|
|
dimension=D) |
|
|
output = conv_tr(input) |
|
|
|
|
|
print('\nInput:') |
|
|
print_sparse_tensor(input) |
|
|
|
|
|
print('Convolution Transpose Output:') |
|
|
print_sparse_tensor(output) |
|
|
|
|
|
|
|
|
def conv_on_coords(): |
|
|
in_channels, out_channels, D = 2, 3, 2 |
|
|
coords, feats, labels = data_loader(in_channels, batch_size=1) |
|
|
|
|
|
|
|
|
strided_coords4, tensor_stride4 = get_random_coords(tensor_stride=4) |
|
|
strided_coords2, tensor_stride2 = get_random_coords(tensor_stride=2) |
|
|
input = ME.SparseTensor( |
|
|
features=torch.rand(len(strided_coords4), in_channels), |
|
|
coordinates=strided_coords4, |
|
|
tensor_stride=tensor_stride4) |
|
|
cm = input.coordinate_manager |
|
|
|
|
|
|
|
|
conv_tr = ME.MinkowskiConvolutionTranspose( |
|
|
in_channels, |
|
|
out_channels, |
|
|
kernel_size=3, |
|
|
stride=2, |
|
|
bias=False, |
|
|
dimension=D) |
|
|
|
|
|
pool_tr = ME.MinkowskiPoolingTranspose( |
|
|
kernel_size=2, |
|
|
stride=2, |
|
|
dimension=D) |
|
|
|
|
|
|
|
|
|
|
|
output1 = conv_tr(input) |
|
|
|
|
|
|
|
|
|
|
|
output2 = conv_tr(input, coords) |
|
|
|
|
|
|
|
|
|
|
|
coords_key, _ = cm.insert_and_map(strided_coords2, tensor_stride=2) |
|
|
output3 = conv_tr(input, coords_key) |
|
|
|
|
|
|
|
|
|
|
|
output4 = conv_tr(input, output1) |
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
conv() |
|
|
conv_on_coords() |
|
|
|