def forward(self, data, octree): assert data.size(1) == self.channel_in conv = octree_conv( data, self.weights, octree, self.depth, self.channel_out, self.kernel_size, self.stride, self.nempty) if self.stride == 2 and not self.nempty: conv = ocnn.octree_pad(conv, octree, self.depth-1) return conv
def forward(self, data, octree): depth = self.depth col = ocnn.octree2col(data, octree, depth, self.kernel_size, self.stride, False) col = col.view([self.cdim, -1]) conv = torch.mm(self.weights, col) conv = torch.unsqueeze(torch.unsqueeze(conv, 0), -1) # [C,H] -> [1,C,H,1] if self.stride == 2: conv = ocnn.octree_pad(conv, octree, depth-1) return conv
def test_octree2colP(self): depth = 4 channel = 5 stride = [1, 2] kernel_size = [[3, 3, 3], [2, 2, 2], [3, 1, 1], [3, 3, 1], [1, 1, 1]] samples = ocnn.octree_samples( ['octree_1', 'octree_2', 'octree_2', 'octree_1']) octree = ocnn.octree_batch(samples).cuda() node_num = ocnn.octree_property(octree, 'node_num', depth) data_in = torch.rand(1, channel, node_num.item(), 1).cuda() data_in = ocnn.octree_depad(data_in, octree, depth) data_in1 = data_in.clone().requires_grad_() data1 = ocnn.octree_pad(data_in1, octree, depth, 0) data_in2 = data_in.clone().requires_grad_() # octree2colP = octree2col + depad for i in range(len(stride)): for j in range(len(kernel_size)): out1 = ocnn.octree2col(data1, octree, depth, kernel_size[j], stride[i], False) if stride[i] == 1: ks, height = out1.size(1), out1.size(2) out1 = out1.view(1, -1, height, 1) out1 = ocnn.octree_depad(out1, octree, depth) out1 = out1.view(channel, ks, -1) out2 = ocnn.octree2col(data_in2, octree, depth, kernel_size[j], stride[i], True) pesudo_grad = torch.rand(out1.shape, dtype=out1.dtype, device=out1.device) out1.backward(pesudo_grad, retain_graph=True) out2.backward(pesudo_grad, retain_graph=True) # check self.assertTrue( np.array_equal(out1.detach().cpu().numpy(), out2.detach().cpu().numpy())) self.assertTrue( np.allclose(data_in1.grad.cpu().numpy(), data_in2.grad.cpu().numpy()))
def forward(self, data, octree): channel = data.shape[1] data = data.view(1, channel, -1, 8) pool = data.mean(dim=3, keepdims=True) output = ocnn.octree_pad(pool, octree, self.depth-1) # !!! depth-1 return output
def forward(self, data, octree): pool, mask = octree_max_pool(data, octree, self.depth) output = ocnn.octree_pad(pool, octree, self.depth-1) # !!! depth-1 return output if not self.return_indices else (output, mask)
def forward(self, data_in, octree): conv = octree_conv(data_in, self.weights, octree, self.depth, self.channel_out, self.kernel_size, self.stride) if self.stride == 2: conv = ocnn.octree_pad(conv, octree, self.depth - 1) return conv