|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import torch |
|
|
import unittest |
|
|
|
|
|
from MinkowskiEngine import ( |
|
|
SparseTensor, |
|
|
TensorField, |
|
|
MinkowskiConvolution, |
|
|
MinkowskiLocalPoolingFunction, |
|
|
MinkowskiSumPooling, |
|
|
MinkowskiAvgPooling, |
|
|
MinkowskiMaxPooling, |
|
|
MinkowskiLocalPoolingTransposeFunction, |
|
|
MinkowskiPoolingTranspose, |
|
|
MinkowskiGlobalPoolingFunction, |
|
|
MinkowskiGlobalPooling, |
|
|
MinkowskiGlobalSumPooling, |
|
|
MinkowskiGlobalAvgPooling, |
|
|
MinkowskiGlobalMaxPooling, |
|
|
) |
|
|
|
|
|
from utils.gradcheck import gradcheck |
|
|
from tests.python.common import data_loader |
|
|
|
|
|
|
|
|
class TestLocalMaxPooling(unittest.TestCase): |
|
|
def test_gpu(self): |
|
|
if not torch.cuda.is_available(): |
|
|
return |
|
|
|
|
|
in_channels, D = 2, 2 |
|
|
coords, feats, labels = data_loader(in_channels) |
|
|
feats = feats.double() |
|
|
feats.requires_grad_() |
|
|
input = SparseTensor(feats, coordinates=coords) |
|
|
pool = MinkowskiMaxPooling(kernel_size=3, stride=2, dimension=D) |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
if not torch.cuda.is_available(): |
|
|
return |
|
|
|
|
|
input = SparseTensor(feats, coordinates=coords, device=0) |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
fn = MinkowskiLocalPoolingFunction() |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
pool.pooling_mode, |
|
|
pool.kernel_generator, |
|
|
input.coordinate_map_key, |
|
|
output.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
def test(self): |
|
|
in_channels, D = 2, 2 |
|
|
coords, feats, labels = data_loader(in_channels) |
|
|
feats = feats.double() |
|
|
feats.requires_grad_() |
|
|
input = SparseTensor(feats, coordinates=coords) |
|
|
pool = MinkowskiMaxPooling(kernel_size=3, stride=2, dimension=D) |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
fn = MinkowskiLocalPoolingFunction() |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
pool.pooling_mode, |
|
|
pool.kernel_generator, |
|
|
input.coordinate_map_key, |
|
|
output.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
class TestLocalSumPooling(unittest.TestCase): |
|
|
def test_sumpooling(self): |
|
|
in_channels, D = 2, 2 |
|
|
coords, feats, labels = data_loader(in_channels) |
|
|
feats = feats.double() |
|
|
feats.requires_grad_() |
|
|
input = SparseTensor(feats, coords) |
|
|
pool = MinkowskiSumPooling(kernel_size=3, stride=2, dimension=D) |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
fn = MinkowskiLocalPoolingFunction() |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
pool.pooling_mode, |
|
|
pool.kernel_generator, |
|
|
input.coordinate_map_key, |
|
|
output.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
input = SparseTensor(feats, coords, device=0) |
|
|
output = pool(input) |
|
|
print(output) |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
pool.pooling_mode, |
|
|
pool.kernel_generator, |
|
|
input.coordinate_map_key, |
|
|
output.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
def test_poolmap(self): |
|
|
in_channels, D = 2, 2 |
|
|
coords, feats, labels = data_loader(in_channels) |
|
|
feats = feats.double() |
|
|
feats.requires_grad_() |
|
|
input = SparseTensor(feats, coords) |
|
|
pool = MinkowskiSumPooling(kernel_size=2, stride=2, dimension=D) |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
fn = MinkowskiLocalPoolingFunction() |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
pool.pooling_mode, |
|
|
pool.kernel_generator, |
|
|
input.coordinate_map_key, |
|
|
output.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
input = SparseTensor(feats, coords, device=0) |
|
|
output = pool(input) |
|
|
print(output) |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
pool.pooling_mode, |
|
|
pool.kernel_generator, |
|
|
input.coordinate_map_key, |
|
|
output.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
class TestLocalAvgPooling(unittest.TestCase): |
|
|
def test_gpu(self): |
|
|
if not torch.cuda.is_available(): |
|
|
return |
|
|
|
|
|
in_channels, D = 2, 2 |
|
|
coords, feats, labels = data_loader(in_channels) |
|
|
feats = feats.double() |
|
|
feats.requires_grad_() |
|
|
input = SparseTensor(feats, coordinates=coords) |
|
|
pool = MinkowskiAvgPooling(kernel_size=3, stride=2, dimension=D) |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
if not torch.cuda.is_available(): |
|
|
return |
|
|
|
|
|
input = SparseTensor(feats, coordinates=coords, device=0) |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
fn = MinkowskiLocalPoolingFunction() |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
pool.pooling_mode, |
|
|
pool.kernel_generator, |
|
|
input.coordinate_map_key, |
|
|
output.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
def test(self): |
|
|
in_channels, D = 2, 2 |
|
|
coords, feats, labels = data_loader(in_channels) |
|
|
feats = feats.double() |
|
|
feats.requires_grad_() |
|
|
input = SparseTensor(feats, coordinates=coords) |
|
|
pool = MinkowskiAvgPooling(kernel_size=3, stride=2, dimension=D) |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
fn = MinkowskiLocalPoolingFunction() |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
pool.pooling_mode, |
|
|
pool.kernel_generator, |
|
|
input.coordinate_map_key, |
|
|
output.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
class TestPoolingTranspose(unittest.TestCase): |
|
|
def test_unpool(self): |
|
|
in_channels, out_channels, D = 2, 3, 2 |
|
|
coords, feats, labels = data_loader(in_channels) |
|
|
feats = feats.double() |
|
|
input = SparseTensor(feats, coords) |
|
|
conv = MinkowskiConvolution( |
|
|
in_channels, out_channels, kernel_size=3, stride=2, dimension=D |
|
|
) |
|
|
conv = conv.double() |
|
|
unpool = MinkowskiPoolingTranspose(kernel_size=3, stride=2, dimension=D) |
|
|
input = conv(input) |
|
|
output = unpool(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
fn = MinkowskiLocalPoolingTransposeFunction() |
|
|
|
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
unpool.pooling_mode, |
|
|
unpool.kernel_generator, |
|
|
input.coordinate_map_key, |
|
|
None, |
|
|
input.coordinate_manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
def test_unpool_gpu(self): |
|
|
if not torch.cuda.is_available(): |
|
|
return |
|
|
|
|
|
in_channels, out_channels, D = 2, 3, 2 |
|
|
coords, feats, labels = data_loader(in_channels) |
|
|
feats = feats.double() |
|
|
input = SparseTensor(feats, coords) |
|
|
conv = MinkowskiConvolution( |
|
|
in_channels, out_channels, kernel_size=3, stride=2, dimension=D |
|
|
) |
|
|
conv = conv.double() |
|
|
unpool = MinkowskiPoolingTranspose(kernel_size=3, stride=2, dimension=D) |
|
|
input = conv(input) |
|
|
output = unpool(input) |
|
|
print(output) |
|
|
|
|
|
fn = MinkowskiLocalPoolingTransposeFunction() |
|
|
|
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
unpool.pooling_mode, |
|
|
unpool.kernel_generator, |
|
|
input.coordinate_map_key, |
|
|
None, |
|
|
input.coordinate_manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
with torch.cuda.device(0): |
|
|
conv = conv.to("cuda") |
|
|
input = SparseTensor(feats, coords, device="cuda") |
|
|
input = conv(input) |
|
|
input.requires_grad_() |
|
|
output = unpool(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
unpool.pooling_mode, |
|
|
unpool.kernel_generator, |
|
|
input.coordinate_map_key, |
|
|
None, |
|
|
input.coordinate_manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
class TestGlobalAvgPooling(unittest.TestCase): |
|
|
def test_batch_size1(self): |
|
|
if not torch.cuda.is_available(): |
|
|
return |
|
|
|
|
|
in_channels, D = 2, 2 |
|
|
coords, feats, labels = data_loader(in_channels, batch_size=1) |
|
|
feats = feats.double() |
|
|
feats.requires_grad_() |
|
|
input = SparseTensor(feats, coordinates=coords) |
|
|
pool = MinkowskiGlobalAvgPooling() |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
if not torch.cuda.is_available(): |
|
|
return |
|
|
|
|
|
input = SparseTensor(feats, coordinates=coords, device=0) |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
fn = MinkowskiGlobalPoolingFunction() |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
pool.pooling_mode, |
|
|
input.coordinate_map_key, |
|
|
output.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
def test_gpu(self): |
|
|
if not torch.cuda.is_available(): |
|
|
return |
|
|
|
|
|
in_channels = 2 |
|
|
coords, feats, labels = data_loader(in_channels) |
|
|
feats = feats.double() |
|
|
feats.requires_grad_() |
|
|
input = SparseTensor(feats, coordinates=coords) |
|
|
pool = MinkowskiGlobalAvgPooling() |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
if not torch.cuda.is_available(): |
|
|
return |
|
|
|
|
|
input = SparseTensor(feats, coordinates=coords, device=0) |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
fn = MinkowskiGlobalPoolingFunction() |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
pool.pooling_mode, |
|
|
input.coordinate_map_key, |
|
|
output.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
def test(self): |
|
|
in_channels, D = 2, 2 |
|
|
coords, feats, labels = data_loader(in_channels) |
|
|
feats = feats.double() |
|
|
feats.requires_grad_() |
|
|
input = SparseTensor(feats, coords) |
|
|
pool = MinkowskiGlobalAvgPooling() |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
fn = MinkowskiGlobalPoolingFunction() |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
pool.pooling_mode, |
|
|
input.coordinate_map_key, |
|
|
output.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
class TestGlobalMaxPooling(unittest.TestCase): |
|
|
def test_batch_size(self): |
|
|
if not torch.cuda.is_available(): |
|
|
return |
|
|
|
|
|
in_channels, D = 2, 2 |
|
|
coords, feats, labels = data_loader(in_channels, batch_size=1) |
|
|
feats = feats.double() |
|
|
feats.requires_grad_() |
|
|
input = SparseTensor(feats, coordinates=coords) |
|
|
pool = MinkowskiGlobalMaxPooling() |
|
|
output = pool(input) |
|
|
print(output) |
|
|
output.F.sum().backward() |
|
|
|
|
|
if not torch.cuda.is_available(): |
|
|
return |
|
|
|
|
|
input = SparseTensor(feats, coordinates=coords, device="cuda") |
|
|
output = pool(input) |
|
|
print(output) |
|
|
output.F.sum().backward() |
|
|
|
|
|
def test_gpu(self): |
|
|
if not torch.cuda.is_available(): |
|
|
return |
|
|
|
|
|
in_channels, D = 2, 2 |
|
|
coords, feats, labels = data_loader(in_channels) |
|
|
feats = feats.double() |
|
|
feats.requires_grad_() |
|
|
input = SparseTensor(feats, coordinates=coords) |
|
|
pool = MinkowskiGlobalMaxPooling() |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
if not torch.cuda.is_available(): |
|
|
return |
|
|
|
|
|
input = SparseTensor(feats, coordinates=coords, device=0) |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
fn = MinkowskiGlobalPoolingFunction() |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
pool.pooling_mode, |
|
|
input.coordinate_map_key, |
|
|
output.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
def test(self): |
|
|
in_channels, D = 2, 2 |
|
|
coords, feats, labels = data_loader(in_channels) |
|
|
feats = feats.double() |
|
|
feats.requires_grad_() |
|
|
input = SparseTensor(feats, coords) |
|
|
pool = MinkowskiGlobalAvgPooling() |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
fn = MinkowskiGlobalPoolingFunction() |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
pool.pooling_mode, |
|
|
input.coordinate_map_key, |
|
|
output.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
def test_field(self): |
|
|
in_channels, D = 2, 2 |
|
|
coords, feats, labels = data_loader(in_channels) |
|
|
feats = feats.double() |
|
|
feats.requires_grad_() |
|
|
input = TensorField(feats, coords) |
|
|
pool = MinkowskiGlobalMaxPooling() |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
fn = MinkowskiGlobalPoolingFunction() |
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
pool.pooling_mode, |
|
|
input.coordinate_field_map_key, |
|
|
output.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|
|
|
if not torch.cuda.is_available(): |
|
|
return |
|
|
|
|
|
input = TensorField(feats, coords, device="cuda") |
|
|
output = pool(input) |
|
|
print(output) |
|
|
|
|
|
|
|
|
self.assertTrue( |
|
|
gradcheck( |
|
|
fn, |
|
|
( |
|
|
input.F, |
|
|
pool.pooling_mode, |
|
|
input.coordinate_field_map_key, |
|
|
output.coordinate_map_key, |
|
|
input._manager, |
|
|
), |
|
|
) |
|
|
) |
|
|
|