def test_2d_loc_grads(): sdfs = [ torch.from_numpy(np.array([[0, 0.5], [0.5, 1]], dtype=np.float32)), ] convsdf = spn.ConvSDF(sdfs, [ 1, ], 1, 2, 1, 1, max_distance=1, with_params=False, compute_pose_grads=False) convsdf.weight.data.fill_(1) convsdf.bias.data.fill_(0) locs = [] for x in np.arange(0.51, 1.49, 2.0 / 100): for y in np.arange(0.51, 1.49, 2.0 / 100): locs.append([x, y]) locs_t = torch.autograd.Variable(torch.from_numpy( np.array([locs], dtype=np.float32)), requires_grad=True) idxs_t = torch.autograd.Variable( torch.from_numpy(np.array([[0]], dtype=np.float32))) poses_t = torch.autograd.Variable( torch.from_numpy(np.array([[[0, 0, 0]]], dtype=np.float32))) scales_t = torch.autograd.Variable( torch.from_numpy(np.array([[1]], dtype=np.float32))) def func(l): return (convsdf(l, idxs_t, poses_t, scales_t), ) assert gradcheck(func, (locs_t, ), eps=1e-3, atol=1e-3)
def test_adj_grad(Group, device='cuda'): D = Group.manifold_dim X = Group.exp(.5*torch.randn(1,Group.manifold_dim, device=device).double()) def fn(a, b): return (Group.exp(a) * X).adj(b) a = torch.zeros(1, D, requires_grad=True, device=device).double() b = torch.randn(1, D, requires_grad=True, device=device).double() analytical, numerical = gradcheck(fn, [a, b], eps=1e-4) assert torch.allclose(analytical[0], numerical[0], atol=1e-8) assert torch.allclose(analytical[1], numerical[1], atol=1e-8) print("\t-", Group, "Passed adj-grad test")
def test_inv_log_grad(Group, device='cuda', tol=1e-8): D = Group.manifold_dim X = Group.exp(.2*torch.randn(1,D,device=device).double()) def fn(a): return (Group.exp(a) * X).inv().log() a = torch.zeros(1, D, requires_grad=True, device=device).double() analytical, numerical = gradcheck(fn, [a], eps=1e-4) # assert torch.allclose(analytical[0], numerical[0], atol=tol) if not torch.allclose(analytical[0], numerical[0], atol=tol): print(analytical[0]) print(numerical[0]) print("\t-", Group, "Passed inv-grad test")
def extract_translation(Group, device='cuda'): """ prototype function """ D = Group.manifold_dim X = Group.exp(5*torch.randn(1,D, device=device).double()) def fn(a): return (Group.exp(a)*X).translation() a = torch.zeros(1, D, requires_grad=True, device=device).double() analytical, numerical = gradcheck(fn, [a], eps=1e-4) print(analytical[0]) print(numerical[0]) assert torch.allclose(analytical[0], numerical[0], atol=1e-8) print("\t-", Group, "Passed translation test")
def scale(device='cuda'): def fn(a, s): X = SE3.exp(a) X.scale(s) return X.log() s = torch.rand(1, requires_grad=True, device=device).double() a = torch.randn(1, 6, requires_grad=True, device=device).double() analytical, numerical = gradcheck(fn, [a, s], eps=1e-3) print(analytical[1]) print(numerical[1]) assert torch.allclose(analytical[0], numerical[0], atol=1e-8) assert torch.allclose(analytical[1], numerical[1], atol=1e-8) print("\t-", "Passed se3-to-sim3 test")
def ann_test(): """ Set up fake data and parameters for the neural network, and test using gradcheck. """ print("Running ann tests...") N = 20 dimensions = [10, 5, 10] data = np.random.randn(N, dimensions[0]) # each row will be a datum labels = np.zeros((N, dimensions[2])) for i in range(N): labels[i, random.randint(0,dimensions[2]-1)] = 1 params_len = params_count(dimensions) params = np.random.randn(params_len) assert gradcheck(lambda params: _forward_backward_prop(data, labels, params, dimensions), params) print("Success!!")
def eval_convsp(cuda=False): BATCH_SIZE = 2 N = 5 M = 3 NDIM = 2 KERNEL_SIZE = (3, 1) RADIUS = 1.0 DILATION = 0.05 NCHANNELS = 2 NKERNELS = 3 np.random.seed(0) locs = np.random.rand(BATCH_SIZE, N, NDIM).astype(np.float32) qlocs = np.random.rand(BATCH_SIZE, M, NDIM).astype(np.float32) data = np.random.rand(BATCH_SIZE, N, NCHANNELS).astype(np.float32) weights = np.random.rand(NKERNELS, NCHANNELS, np.prod(KERNEL_SIZE)).astype(np.float32) biases = np.random.rand(NKERNELS).astype(np.float32) def use_cuda(x): if cuda: return x.cuda() else: return x def undo_cuda(x): if cuda: return x.cpu() else: return x for use_qlocs in (True, False): locs_t = torch.autograd.Variable(use_cuda(torch.FloatTensor(locs)), requires_grad=True) if use_qlocs: qlocs_t = torch.autograd.Variable(use_cuda(torch.FloatTensor(qlocs)), requires_grad=True) else: qlocs_t = None data_t = torch.autograd.Variable(use_cuda(torch.FloatTensor(data)), requires_grad=True) weights_t = torch.nn.Parameter(torch.FloatTensor(weights), requires_grad=True) biases_t = torch.nn.Parameter(torch.FloatTensor(biases), requires_grad=True) coll = use_cuda(spn.ParticleCollision(NDIM, RADIUS + DILATION*max((k - 1)/2 for k in KERNEL_SIZE))) locs_t, data_t, idxs_t, neighbors_t = coll(locs_t, data_t, (qlocs_t if use_qlocs else None)) for kernel_fn in spn.KERNEL_NAMES: print("\tTesting kernel %s (%s query locations)..." % (kernel_fn, "with" if use_qlocs else "without")) ground_truth = pyconvsp((qlocs if use_qlocs else locs), locs, data, weights, biases, kernel_fn, KERNEL_SIZE, RADIUS, DILATION, NKERNELS) convsp = spn.ConvSP(NCHANNELS, NKERNELS, NDIM, KERNEL_SIZE, DILATION, RADIUS, kernel_fn=kernel_fn) convsp.weight = weights_t convsp.bias = biases_t convsp = use_cuda(convsp) pred_t = undo_cuda(convsp(locs_t, data_t, neighbors_t, qlocs_t)) np.testing.assert_array_almost_equal(pred_t.data.numpy(), ground_truth, decimal=3) dt = torch.autograd.Variable(data_t.data, requires_grad=True) lt = torch.autograd.Variable(locs_t.data, requires_grad=True) if use_qlocs: qt = torch.autograd.Variable(qlocs_t.data, requires_grad=True) wt = torch.nn.Parameter(weights_t.data, requires_grad=True) bt = torch.nn.Parameter(biases_t.data, requires_grad=True) # Use pyconvsp to allow for double precision when computing numeric grads. def func_numerical(l, d, w, b, q=None): return (torch.autograd.Variable(torch.from_numpy( pyconvsp((q.data.cpu().numpy() if use_qlocs else l.data.cpu().numpy()), l.data.cpu().numpy(), d.data.cpu().numpy(), w.data.cpu().numpy(), b.data.cpu().numpy(), kernel_fn, KERNEL_SIZE, RADIUS, DILATION, NKERNELS))),) def func_analytical(l, d, w, b, q=None): convsp.weight = w convsp.bias = b return (convsp(l, d, neighbors_t, (q if use_qlocs else None)),) assert gradcheck(func_analytical, ((lt, dt, wt, bt, qt) if use_qlocs else (lt, dt, wt, bt,)), eps=1e-4, atol=1e-3, rtol=1e-2, func_numerical=func_numerical, use_double=True)
batchsize = 2 c_in = 2 c_out = 4 inpu = 7 kernel = 3 stri = 2 pad = 2 dilation = 2 out = int((inpu + 2 * pad - kernel) / stri + 1) channel_per_group = 2 g_off = c_in // channel_per_group c_off = g_off * kernel * kernel * kernel * 3 group = 2 inputs = Variable(torch.rand(batchsize, c_in, inpu, inpu, inpu).cuda(), requires_grad=True) offsets = Variable(torch.rand(batchsize, c_off, out, out, out).cuda(), requires_grad=True) weight = Variable(torch.rand(c_out, c_in // group, kernel, kernel, kernel).cuda(), requires_grad=True) bias = Variable(torch.rand(c_out).cuda(), requires_grad=True) print( gradcheck(ConvOffset3dFunction.apply, (inputs, offsets, weight, bias, (stri, stri, stri), (pad, pad, pad), (dilation, dilation, dilation), channel_per_group, group))) # print(gradcheck(F.conv3d, (inputs, weight)))
(D, C)) dm = layers.dummy() def f(x): y = fc.forward(x) yout = dm.forward(y) dy = dm.backward(y, 1) dx = fc.backward(x, dy) return yout, dx return f x = np.random.rand(4, 5) f = fc_x_forward() gradcheck(f, x) def fc_w_forward(): N, D, C = 4, 5, 6 x0 = np.random.rand(N, D) fc = layers.FullConn(layers.xaxier_initilizer, layers.zero_initilizer, (D, C)) dm = layers.dummy() def f(x): fc.params['w'] = x y = fc.forward(x0) yout = dm.forward(y) dy = dm.backward(y, 1) dx = fc.backward(x0, dy)
import torch from deform_conv3dl_modules import ConvOffset3d from torch.autograd import Variable import os from gradcheck import gradcheck from deform_conv3dl_functions import ConvOffset3dFunction os.environ['CUDA_VISIBLE_DEVICES'] = '0' batchsize = 2 c_in = 2 c_out = 3 inpu = 5 kernel = 3 stri = 2 pad = 1 out = int((inpu + 2 * pad - kernel) / stri + 1) channel_per_group = 2 g_off = c_in // channel_per_group conv_offset3d = ConvOffset3dFunction((stri, stri, stri), (pad, pad, pad), channel_per_group) inputs = Variable(torch.rand(batchsize, c_in, inpu, inpu, inpu).type(torch.DoubleTensor).cuda(), requires_grad=True) offsets = Variable(torch.rand(batchsize, g_off, out, out, out).type(torch.DoubleTensor).cuda(), requires_grad=True) weight = Variable(torch.rand(c_out, c_in, kernel, kernel, kernel).type(torch.DoubleTensor).cuda(), requires_grad=True) print(gradcheck(conv_offset3d, (inputs, offsets, weight)))
def eval_convsdf(cuda=False): BATCH_SIZE = 2 N = 10 M = 30 NDIM = 3 KERNEL_SIZE = (3, 5, 3) DILATION = 0.001 NKERNELS = 2 MAX_DISTANCE = 13.37 M = 1 np.random.seed(0) locs = np.random.rand(BATCH_SIZE, N, NDIM) weights = np.random.rand(NKERNELS, np.prod(KERNEL_SIZE)) biases = np.random.rand(NKERNELS) kernel_centers = (np.array(KERNEL_SIZE) - 1) / 2 ground_truth = np.zeros((BATCH_SIZE, N, NKERNELS), dtype=np.float32) sdf_widths = np.array([ [4, 4, 4], [6, 4, 8], [5, 5, 5], ], dtype=np.float32) / 1 sdf1 = construct_sdf((5, 5, 5), (1, 2, 3), sdf_widths[0, :]) sdf2 = construct_sdf((6, 4, 8), (1, 0, 2), sdf_widths[1, :]) sdf3 = construct_sdf((20, 20, 20), (5, 15, 5), sdf_widths[2, :]) sdfs = [sdf1, sdf2, sdf3] sdf_poses = np.random.rand(BATCH_SIZE, M, 7) sdf_poses[..., :3] -= 1.5 # Convert axis angle to quaternion sdf_poses[..., 3:-1] *= np.sin(sdf_poses[..., -1, np.newaxis] / 2) sdf_poses[..., -1] = np.cos(sdf_poses[..., -1] / 2) sdf_poses[..., 3:] /= np.sqrt( (sdf_poses[..., 3:]**2).sum(axis=-1))[..., np.newaxis] idxs = np.random.randint(0, 3, size=(BATCH_SIZE, M)) idxs[-1, -1] = -1 scales = np.random.rand(BATCH_SIZE, M) + 0.5 sdf_fns = [ RegularGridInterpolator([ np.linspace(0.5, y - 0.5, y) * s / y for y, s in zip(sdfs[i].shape, sdf_widths[i, ...]) ], sdfs[i], bounds_error=False, fill_value=np.finfo(np.float32).max) for i in range(len(sdfs)) ] for outk in range(NKERNELS): allkidx = itertools.product( *[list(range(-(k // 2), k // 2 + 1)) for k in KERNEL_SIZE[::-1]]) for k, kidx in enumerate(allkidx): for i in range(N): for b in range(BATCH_SIZE): r = locs[b, i, :] + [ kidx[::-1][j] * DILATION for j in range(3) ] minv = MAX_DISTANCE for m in range(M): mm = idxs[b, m] if mm < 0: continue r2 = quaternionMult( quaternionConjugate(sdf_poses[b, m, 3:]), quaternionMult(r - sdf_poses[b, m, :3], sdf_poses[b, m, 3:]))[:3] r2 /= scales[b, m] v = sdf_fns[mm](r2) * scales[b, m] minv = min(v, minv) ground_truth[b, i, outk] += weights[outk, k] * minv ground_truth += biases[np.newaxis, np.newaxis, :] def use_cuda(x): if cuda: return x.cuda() else: return x def undo_cuda(x): if cuda: return x.cpu() else: return x sdfs_t = [torch.FloatTensor(x) for x in sdfs] sdf_sizes_t = [ np.mean([ 1.0 * sdf_widths[i, j] / sdfs[i].shape[j] for j in range(len(sdfs[i].shape)) ]) for i in range(len(sdfs)) ] locs_t = torch.autograd.Variable(use_cuda(torch.FloatTensor(locs)), requires_grad=True) idxs_t = torch.autograd.Variable(use_cuda(torch.FloatTensor(idxs)), requires_grad=False) poses_t = torch.autograd.Variable(use_cuda(torch.FloatTensor(sdf_poses)), requires_grad=True) scales_t = torch.autograd.Variable(use_cuda(torch.FloatTensor(scales)), requires_grad=False) weights_t = torch.nn.Parameter(torch.FloatTensor(weights), requires_grad=True) biases_t = torch.nn.Parameter(torch.FloatTensor(biases), requires_grad=True) convsdf = spn.ConvSDF(sdfs_t, sdf_sizes_t, NKERNELS, NDIM, KERNEL_SIZE, DILATION, MAX_DISTANCE, compute_pose_grads=True) convsdf.weight = weights_t convsdf.bias = biases_t convsdf = use_cuda(convsdf) pred = undo_cuda(convsdf(locs_t, idxs_t, poses_t, scales_t)) np.testing.assert_array_almost_equal(pred.data.numpy(), ground_truth, decimal=3) # def func(l, w, b, pp): # _pp = torch.cat((pp, poses_t[..., -4:]), 2) # convsdf.weight = w # convsdf.bias = b # return (convsdf(l, idxs_t, _pp, scales_t),) # assert gradcheck(func, (locs_t, weights_t, biases_t, poses_t[..., :3]), eps=1e-2, atol=1e-3) # def func(pp): # # _pp = torch.cat((pp, poses_t[..., -4:]), 2) # return (convsdf(locs_t, idxs_t, pp, scales_t),) # assert gradcheck(func, (poses_t,), eps=1e-4, atol=1e-3) def func(l, w, b): convsdf.weight = w convsdf.bias = b return (convsdf(l, idxs_t, poses_t, scales_t), ) assert gradcheck(func, (locs_t, weights_t, biases_t), eps=1e-2, atol=1e-3) test_2d_loc_grads()
def eval_particlecollision(cuda=False): BATCH_SIZE = 2 N = 100 M = 77 NDIM = 2 RADIUS = 0.2 NCHANNELS = 2 np.random.seed(0) locs = np.random.rand(BATCH_SIZE, N, NDIM).astype(np.float32) qlocs = np.random.rand(BATCH_SIZE, M, NDIM).astype(np.float32) data = np.random.rand(BATCH_SIZE, N, NCHANNELS).astype(np.float32) gt_neighbors = np.ones((BATCH_SIZE, M, N), dtype=int) * -1 for b in range(BATCH_SIZE): for i in range(M): for j in range(N): d = np.square(qlocs[b, i, :] - locs[b, j, :]).sum() if d <= RADIUS * RADIUS: nc = min(np.where(gt_neighbors[b, i, :] < 0)[0]) gt_neighbors[b, i, nc] = j def use_cuda(x): if cuda: return x.cuda() else: return x def undo_cuda(x): if cuda: return x.cpu() else: return x olocs = locs oqlocs = qlocs odata = data locs = torch.autograd.Variable(use_cuda(torch.FloatTensor(locs.copy())), requires_grad=False) qlocs = torch.autograd.Variable(use_cuda(torch.FloatTensor(qlocs.copy())), requires_grad=False) data = torch.autograd.Variable(use_cuda(torch.FloatTensor(data.copy())), requires_grad=False) coll = spn.ParticleCollision(NDIM, RADIUS, max_collisions=N) convsp = use_cuda(coll) vlocs, vdata, vidxs, vneighbors = coll(locs, data, qlocs) idxs = undo_cuda(vidxs).data.numpy().astype(int) neighbors = undo_cuda(vneighbors).data.numpy().astype(int) nlocs = undo_cuda(vlocs).data.numpy() ndata = undo_cuda(vdata).data.numpy() # First make sure all the indexes are in idxs. for b in range(BATCH_SIZE): for i in range(N): assert i in idxs[b, :] # Next make sure locs and data are in the order idxs says they're in. for b in range(BATCH_SIZE): for i, j in enumerate(idxs[b, :]): assert all(olocs[b, j, :] == nlocs[b, i, :]) assert all(odata[b, j, :] == ndata[b, i, :]) # Make sure the input locs and data weren't altered. assert np.all(undo_cuda(locs).data.numpy() == olocs) assert np.all(undo_cuda(data).data.numpy() == odata) # Check the neighbor list. for b in range(BATCH_SIZE): for i in range(M): for j in neighbors[b, i, :]: if j < 0: break assert idxs[b, j] in gt_neighbors[b, i, :] for j in gt_neighbors[b, i, :]: if j < 0: break jj = np.where(idxs[b, :] == j)[0][0] assert jj in neighbors[b, i, :] # Finally put the locations and data back in their original order. reorder = use_cuda(spn.ReorderData(reverse=True)) vlocs, vdata = reorder(vidxs, vlocs, vdata) assert np.all(undo_cuda(vlocs).data.numpy() == olocs) assert np.all(undo_cuda(vdata).data.numpy() == odata) # Test gradients. def func(l, d, q): return coll(l, d, q)[:2] assert gradcheck(func, (locs, data, qlocs), eps=1e-2, atol=1e-3)
def eval_particleprojection(cuda=False): np.random.seed(1) BATCH_SIZE = 2 N = 5 CAMERA_FOV = 45.0 / 180.0 * np.pi CAMERA_SIZE = (120, 90) # CAMERA_SIZE = (1024, 768) CAMERA_FL = CAMERA_SIZE[0] / 2 / (CAMERA_FOV / 2.0) FILTER_STD = 5 FILTER_SCALE = 1.0 / 0.06 CAMERA_POSE = 5.0 * (np.random.rand(BATCH_SIZE, 3).astype(np.float32) - 0.5) CAMERA_TARGET = np.array([(0.0, 0.0, 0.0)] * BATCH_SIZE, dtype=np.float32) CAMERA_ROT = np.zeros((BATCH_SIZE, 4), dtype=np.float32) for b in range(BATCH_SIZE): CAMERA_ROT[b, :] = pointAt(CAMERA_POSE[b, :], np.array([0, 0, 0], dtype=np.float32)) locs = 2.0 * (np.random.rand(BATCH_SIZE, N, 3).astype(np.float32) - 0.5) depth_mask = np.ones((BATCH_SIZE, CAMERA_SIZE[1], CAMERA_SIZE[0]), dtype=np.float32) * np.finfo(np.float32).max ir = (int(CAMERA_SIZE[0] / 2 - CAMERA_SIZE[0] * 0.2), int(CAMERA_SIZE[0] / 2 + CAMERA_SIZE[0] * 0.2) + 1) jr = (int(CAMERA_SIZE[1] / 2 - CAMERA_SIZE[1] * 0.2), int(CAMERA_SIZE[1] / 2 + CAMERA_SIZE[1] * 0.2) + 1) ul = 0.0 lr = 10.0 ur = 5.0 ll = 3.5 for i in range(ir[0], ir[1]): for j in range(jr[0], jr[1]): ii = 1.0 * (i - ir[0]) / (ir[1] - ir[0]) jj = 1.0 * (j - jr[0]) / (jr[1] - jr[0]) l = ul * (1 - jj) + ll * jj r = ur * (1 - jj) + lr * jj depth_mask[0, j, i] = l * (1 - ii) + r * ii def use_cuda(x): if cuda: return x.cuda() else: return x def undo_cuda(x): if cuda: return x.cpu() else: return x def np2var(t): return torch.autograd.Variable(use_cuda(torch.from_numpy(t)), requires_grad=False) locs_t = torch.autograd.Variable(use_cuda(torch.FloatTensor(locs)), requires_grad=True) depth_mask_t = torch.autograd.Variable(use_cuda( torch.FloatTensor(depth_mask)), requires_grad=False) camera_pose_t = torch.autograd.Variable(use_cuda( torch.FloatTensor(CAMERA_POSE)), requires_grad=False) camera_rot_t = torch.autograd.Variable(use_cuda( torch.FloatTensor(CAMERA_ROT)), requires_grad=False) particleProjection = spn.ParticleProjection(CAMERA_FL, CAMERA_SIZE, FILTER_STD, FILTER_SCALE) # particleViewer([ # lambda p, r: pyproject(CAMERA_FL, CAMERA_SIZE, FILTER_STD, FILTER_SCALE, locs, # p, r, depth_mask), # lambda p, r: undo_cuda(particleProjection(locs_t, np2var(p), np2var(r), # depth_mask_t)).data.numpy(), # ], BATCH_SIZE, 5, ["Ground Truth", "Output"]) # return ground_truth = pyproject(CAMERA_FL, CAMERA_SIZE, FILTER_STD, FILTER_SCALE, locs, CAMERA_POSE, CAMERA_ROT, depth_mask) pred_t = particleProjection(locs_t, camera_pose_t, camera_rot_t, depth_mask_t) pred = undo_cuda(pred_t).data.numpy() # visualizeOutput([ground_truth, pred, -(pred - ground_truth)], # ["Ground Truth", "Prediction", "Difference"]) np.testing.assert_array_almost_equal(pred, ground_truth, decimal=3) # Use pyconvsp to allow for double precision when computing numeric grads. def func_numerical(l): ll = undo_cuda(l).data.numpy() return torch.autograd.Variable(use_cuda( torch.from_numpy( pyproject(CAMERA_FL, CAMERA_SIZE, FILTER_STD, FILTER_SCALE, ll, CAMERA_POSE, CAMERA_ROT, dtype=np.float64))), requires_grad=False) def func_analytical(l): return particleProjection(l, camera_pose_t, camera_rot_t) assert gradcheck(func_analytical, (locs_t, ), eps=1e-6, atol=1e-3, rtol=1e-2, func_numerical=func_numerical, use_double=True)
import torch from conv2d_functions import Conv2dFunction from torch.autograd import Variable import os from gradcheck import gradcheck os.environ['CUDA_VISIBLE_DEVICES'] = '4' batchsize = 2 c_in = 2 c_out = 4 inpu = 7 kernel = 1 stri = 2 pad = 2 dilation = 2 out = int((inpu + 2 * pad - dilation * (kernel - 1) - 1) / stri + 1) group = 2 inputs = Variable(torch.rand(batchsize, c_in, inpu, inpu).cuda(), requires_grad=True) weight = Variable(torch.rand(c_out, c_in // group, kernel, kernel).cuda(), requires_grad=True) bias = Variable(torch.rand(c_out).cuda(), requires_grad=True) print( gradcheck(Conv2dFunction.apply, (inputs, weight, bias, (stri, stri), (pad, pad), (dilation, dilation), group)))
def eval_imageprojection(cuda=False): np.random.seed(1) BATCH_SIZE = 2 N = 5 CHANNELS = 2 CAMERA_FOV = 45.0/180.0*np.pi CAMERA_SIZE = (30, 30) CAMERA_FL = CAMERA_SIZE[0]/2/(CAMERA_FOV/2.0) CAMERA_POSE = 5.0*(np.random.rand(BATCH_SIZE, 3).astype(np.float32) - 0.5) CAMERA_TARGET = np.array([(0.0, 0.0, 0.0)]*BATCH_SIZE, dtype=np.float32) CAMERA_ROT = np.zeros((BATCH_SIZE, 4), dtype=np.float32) for b in range(BATCH_SIZE): CAMERA_ROT[b, :] = pointAt(CAMERA_POSE[b, :], np.array([0, 0, 0], dtype=np.float32)) locs = 2.0*(np.random.rand(BATCH_SIZE, N, 3).astype(np.float32) - 0.5) image = np.random.rand(BATCH_SIZE, CHANNELS, CAMERA_SIZE[1], CAMERA_SIZE[0]) depth_mask = np.ones((BATCH_SIZE, CAMERA_SIZE[1], CAMERA_SIZE[0]), dtype=np.float32)*np.finfo(np.float32).max ir = (int(CAMERA_SIZE[0]/2 - CAMERA_SIZE[0]*0.2), int(CAMERA_SIZE[0]/2 + CAMERA_SIZE[0]*0.2) + 1) jr = (int(CAMERA_SIZE[1]/2 - CAMERA_SIZE[1]*0.2), int(CAMERA_SIZE[1]/2 + CAMERA_SIZE[1]*0.2) + 1) ul = 0.0 lr = 10.0 ur = 5.0 ll = 3.5 for i in range(ir[0], ir[1]): for j in range(jr[0], jr[1]): ii = 1.0*(i - ir[0])/(ir[1] - ir[0]) jj = 1.0*(j - jr[0])/(jr[1] - jr[0]) l = ul*(1 - jj) + ll*jj r = ur*(1 - jj) + lr*jj depth_mask[0, j, i] = l*(1 - ii) + r*ii def use_cuda(x): if cuda: return x.cuda() else: return x def undo_cuda(x): if cuda: return x.cpu() else: return x def np2var(t): return torch.autograd.Variable(use_cuda(torch.from_numpy(t)), requires_grad=False) locs_t = torch.autograd.Variable(use_cuda(torch.FloatTensor(locs)), requires_grad=True) image_t = torch.autograd.Variable(use_cuda(torch.FloatTensor(image)), requires_grad=True) depth_mask_t = torch.autograd.Variable(use_cuda(torch.FloatTensor(depth_mask)), requires_grad=False) camera_pose_t = torch.autograd.Variable(use_cuda(torch.FloatTensor(CAMERA_POSE)), requires_grad=False) camera_rot_t = torch.autograd.Variable(use_cuda(torch.FloatTensor(CAMERA_ROT)), requires_grad=False) imageProjection = spn.ImageProjection(CAMERA_FL) ground_truth = pyproject(locs, image, CAMERA_FL, CAMERA_POSE, CAMERA_ROT, depth_mask) pred_t = imageProjection(locs_t, image_t, camera_pose_t, camera_rot_t, depth_mask_t) pred = undo_cuda(pred_t).data.numpy() np.testing.assert_array_almost_equal(pred, ground_truth, decimal=3) # Use pyproject to allow for double precision when computing numeric grads. def func_numerical(l, i): ll = undo_cuda(l).data.numpy() ii = undo_cuda(i).data.numpy() return torch.autograd.Variable(use_cuda(torch.from_numpy(pyproject(ll, ii, CAMERA_FL, CAMERA_POSE, CAMERA_ROT, dtype=np.float64))), requires_grad=False) def func_analytical(l, i): return imageProjection(l, i, camera_pose_t, camera_rot_t) assert gradcheck(func_analytical, (locs_t, image_t,), eps=1e-3, atol=1e-3, rtol=1e-2)