def _test_sparse_conv2d_correctness(self, xsize, bsize, ksize, strides, padding, dtype=tf.float32): np.random.RandomState(0) x = tf.constant(np.random.uniform(-1, 1, xsize), dtype=dtype) w = tf.constant(np.random.uniform(-1, 1, ksize), dtype=dtype) mask = np.random.uniform(-5, 1, xsize[:-1]) mask = tf.constant((mask > 0).astype(np.float32), dtype=dtype) mask_out = tf.nn.max_pool( tf.expand_dims(mask, 3), [1, ksize[0], ksize[1], 1], strides, padding) y_exp = mask_conv2d(x, w, mask, strides, padding) ind_blk = convert_mask_to_block_indices(mask, bsize, ksize, strides, padding, 0.) y_act = sparse_conv2d(x, w, ind_blk, strides, padding) with self.test_session(): y_exp_val = y_exp.eval() y_act_val = y_act.eval() mask_val = mask_out.eval() mask_val = np.tile(mask_val, [1, 1, 1, ksize[-1]]) y_exp_val = y_exp_val * mask_val y_act_val = y_act_val * mask_val y_exp_val = y_exp_val[mask_val > 0.] y_act_val = y_act_val[mask_val > 0.] np.testing.assert_allclose(y_act_val, y_exp_val, rtol=1e-2, atol=0.1)
def _test_sparse_conv2d_matmul_correctness(self, xsize, ksize, padding, dtype=tf.float32): np.random.RandomState(0) strides = [1, 1, 1, 1] # Only [1, 1, 1, 1] is supported currently. # Use block size to be the same with kernel size makes it the same with matrix multiplication. bsize = [1, ksize[0], ksize[1], 1] x = tf.constant(np.random.uniform(-1, 1, xsize), dtype=dtype) w = tf.constant(np.random.uniform(-1, 1, ksize), dtype=dtype) mask = np.random.uniform(-5, 1, xsize[:-1]) mask = tf.constant((mask > 0).astype(np.float32), dtype=dtype) mask_out = tf.nn.max_pool(tf.expand_dims(mask, 3), [1, ksize[0], ksize[1], 1], strides, padding) y_exp = mask_conv2d(x, w, mask, strides, padding) ind_blk = convert_mask_to_block_indices(mask, bsize, ksize, strides, padding, 0.) y_act = sparse_conv2d_matmul(x, w, ind_blk, strides, padding) with self.test_session(): y_exp_val = y_exp.eval() y_act_val = y_act.eval() mask_val = mask_out.eval() mask_val = np.tile(mask_val, [1, 1, 1, ksize[-1]]) y_exp_val = y_exp_val * mask_val y_act_val = y_act_val * mask_val y_exp_val = y_exp_val[mask_val > 0.] y_act_val = y_act_val[mask_val > 0.] np.testing.assert_allclose(y_act_val, y_exp_val, rtol=1e-2, atol=1e-5)
def _test_sparse_conv2d_with_mask(self, mask, bsize, ksize, strides, padding, y_exp): mask_ = tf.constant(mask) ind_blk = convert_mask_to_block_indices(mask_, bsize, ksize, strides, padding, 0.) x = tf.constant(np.ones([1, mask.shape[1], mask.shape[2], 1], dtype=np.float32)) w = tf.constant(np.ones(ksize, dtype=np.float32)) y = sparse_conv2d(x, w, ind_blk, strides, padding) with self.test_session(): y_act = y.eval() self.assertEqual(y_act.size, y_exp.size) np.testing.assert_array_equal(y_act.reshape(y_exp.shape), y_exp)
def _sparse_conv2d_with_mask(x, w, strides, padding, mask, bsize, tol): """Sparse conv 2d with mask.""" ksize = [int(ss) for ss in w.get_shape()] ind_blk = convert_mask_to_block_indices(mask, bsize, ksize, strides, padding, tol, avgpool=True) y = sparse_conv2d(x, w, ind_blk, strides, padding) return y
def gather_tf(x, mask, bsize, ksize, strides, padding): blk_indices = convert_mask_to_block_indices(mask, bsize, ksize, strides, padding, 0.0) blk_shape = tf.shape(blk_indices) blk_indices_ = tf.reshape(blk_indices, [-1, 3]) # Calculate the block strides. bstrides = _calc_block_strides(blk_shape, ksize, strides) # Pad input. x_ = _pad_input(x, ksize, strides, padding, bsize=[1, blk_shape[1], blk_shape[2], 1], bstrides=bstrides) # Gather patches. p = tf.gather_nd(x_, blk_indices_) # Reshape patches. p = tf.reshape(p, [blk_shape[0], blk_shape[1], blk_shape[2], -1]) return p, blk_indices