def testGradientsExplicit(self): sp_input = self._SparseTensor_4x6() # SparseSliceGrad does not currently have a GPU kernel. with test_util.force_cpu(): start, size = [0, 0], [4, 1] sp_output = sparse_ops.sparse_slice(sp_input, start, size) input_grad_vals = sparse_ops.sparse_slice_grad( sp_output.values, sp_input.indices, start, sp_output.indices) self.assertAllEqual(input_grad_vals, [0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 30, 0, 0, 0]) start, size = [0, 1], [4, 1] sp_output = sparse_ops.sparse_slice(sp_input, start, size) input_grad_vals = sparse_ops.sparse_slice_grad( sp_output.values, sp_input.indices, start, sp_output.indices) self.assertAllEqual(input_grad_vals, [0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0]) start, size = [1, 3], [3, 1] sp_output = sparse_ops.sparse_slice(sp_input, start, size) input_grad_vals = sparse_ops.sparse_slice_grad( sp_output.values, sp_input.indices, start, sp_output.indices) self.assertAllEqual(input_grad_vals, [0, 0, 0, 0, 0, 13, 0, 0, 23, 0, 0, 0, 33, 0]) sp_input = self._SparseTensor_4x6_empty() start, size = [0, 0], [4, 1] sp_output = sparse_ops.sparse_slice(sp_input, start, size) input_grad_vals = sparse_ops.sparse_slice_grad( sp_output.values, sp_input.indices, start, sp_output.indices) self.assertAllEqual(input_grad_vals, [])
def testSliceMatrixUnevenRows(self): with self.session(use_gpu=False): sp_input = self._SparseTensor_5x7() sp_tensor0 = sparse_ops.sparse_slice(sp_input, [0, 0], [3, 7]) sp_tensor1 = sparse_ops.sparse_slice(sp_input, [3, 0], [3, 7]) self.assertAllEqual(sp_tensor0.indices.eval(), [[0, 0], [0, 2], [0, 4], [0, 5], [1, 1], [1, 3], [1, 4], [1, 6], [2, 0], [2, 3], [2, 5]]) self.assertAllEqual(sp_tensor0.values.eval(), [0, 2, 4, 5, 11, 13, 14, 16, 20, 23, 25]) self.assertAllEqual(sp_tensor0.dense_shape.eval(), [3, 7]) self.assertAllEqual( sp_tensor1.indices.eval(), [[0, 0], [0, 2], [0, 3], [0, 5], [1, 1], [1, 4], [1, 6]]) self.assertAllEqual(sp_tensor1.values.eval(), [30, 32, 33, 35, 41, 44, 46]) self.assertAllEqual(sp_tensor1.dense_shape.eval(), [2, 7]) sp_tensor0 = sparse_ops.sparse_slice(sp_input, [0, 0], [2, 7]) sp_tensor1 = sparse_ops.sparse_slice(sp_input, [2, 0], [2, 7]) sp_tensor2 = sparse_ops.sparse_slice(sp_input, [4, 0], [2, 7]) self.assertAllEqual( sp_tensor0.indices.eval(), [[0, 0], [0, 2], [0, 4], [0, 5], [1, 1], [1, 3], [1, 4], [1, 6]]) self.assertAllEqual(sp_tensor0.values.eval(), [0, 2, 4, 5, 11, 13, 14, 16]) self.assertAllEqual(sp_tensor0.dense_shape.eval(), [2, 7]) self.assertAllEqual(sp_tensor1.values.eval(), [20, 23, 25, 30, 32, 33, 35]) self.assertAllEqual(sp_tensor1.dense_shape.eval(), [2, 7]) self.assertAllEqual(sp_tensor2.indices.eval(), [[0, 1], [0, 4], [0, 6]]) self.assertAllEqual(sp_tensor2.values.eval(), [41, 44, 46]) self.assertAllEqual(sp_tensor2.dense_shape.eval(), [1, 7]) return
def testSliceMatrixUnevenRows(self): with self.session(use_gpu=False): sp_input = self._SparseTensor_5x7() sp_tensor0 = sparse_ops.sparse_slice(sp_input, [0, 0], [3, 7]) sp_tensor1 = sparse_ops.sparse_slice(sp_input, [3, 0], [3, 7]) self.assertAllEqual(sp_tensor0.indices, [[0, 0], [0, 2], [0, 4], [0, 5], [1, 1], [1, 3], [1, 4], [1, 6], [2, 0], [2, 3], [2, 5]]) self.assertAllEqual(sp_tensor0.values, [0, 2, 4, 5, 11, 13, 14, 16, 20, 23, 25]) self.assertAllEqual(sp_tensor0.dense_shape, [3, 7]) self.assertAllEqual( sp_tensor1.indices, [[0, 0], [0, 2], [0, 3], [0, 5], [1, 1], [1, 4], [1, 6]]) self.assertAllEqual(sp_tensor1.values, [30, 32, 33, 35, 41, 44, 46]) self.assertAllEqual(sp_tensor1.dense_shape, [2, 7]) sp_tensor0 = sparse_ops.sparse_slice(sp_input, [0, 0], [2, 7]) sp_tensor1 = sparse_ops.sparse_slice(sp_input, [2, 0], [2, 7]) sp_tensor2 = sparse_ops.sparse_slice(sp_input, [4, 0], [2, 7]) self.assertAllEqual( sp_tensor0.indices, [[0, 0], [0, 2], [0, 4], [0, 5], [1, 1], [1, 3], [1, 4], [1, 6]]) self.assertAllEqual(sp_tensor0.values, [0, 2, 4, 5, 11, 13, 14, 16]) self.assertAllEqual(sp_tensor0.dense_shape, [2, 7]) self.assertAllEqual(sp_tensor1.values, [20, 23, 25, 30, 32, 33, 35]) self.assertAllEqual(sp_tensor1.dense_shape, [2, 7]) self.assertAllEqual(sp_tensor2.indices, [[0, 1], [0, 4], [0, 6]]) self.assertAllEqual(sp_tensor2.values, [41, 44, 46]) self.assertAllEqual(sp_tensor2.dense_shape, [1, 7]) return
def testGradientsExplicit(self): sp_input = self._SparseTensor_4x6() start, size = [0, 0], [4, 1] sp_output = sparse_ops.sparse_slice(sp_input, start, size) input_grad_vals = sparse_ops.sparse_slice_grad(sp_output.values, sp_input.indices, start, sp_output.indices) # pyformat: disable self.assertAllEqual(input_grad_vals, [0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 30, 0, 0, 0]) # pyformat: enable start, size = [0, 1], [4, 1] sp_output = sparse_ops.sparse_slice(sp_input, start, size) input_grad_vals = sparse_ops.sparse_slice_grad(sp_output.values, sp_input.indices, start, sp_output.indices) # pyformat: disable self.assertAllEqual(input_grad_vals, [0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0]) # pyformat: enable start, size = [1, 3], [3, 1] sp_output = sparse_ops.sparse_slice(sp_input, start, size) input_grad_vals = sparse_ops.sparse_slice_grad(sp_output.values, sp_input.indices, start, sp_output.indices) # pyformat: disable self.assertAllEqual(input_grad_vals, [0, 0, 0, 0, 0, 13, 0, 0, 23, 0, 0, 0, 33, 0]) # pyformat: enable # Test empty slice of non-empty input. start, size = [2, 1], [2, 1] sp_output = sparse_ops.sparse_slice(sp_input, start, size) input_grad_vals = sparse_ops.sparse_slice_grad(sp_output.values, sp_input.indices, start, sp_output.indices) # pyformat: disable self.assertAllEqual(input_grad_vals, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) # pyformat: enable sp_input = self._SparseTensor_4x6_empty() start, size = [0, 0], [4, 1] sp_output = sparse_ops.sparse_slice(sp_input, start, size) input_grad_vals = sparse_ops.sparse_slice_grad(sp_output.values, sp_input.indices, start, sp_output.indices) self.assertAllEqual(input_grad_vals, [])
def testSliceMatrixRows(self): with self.session(use_gpu=False): sp_input = self._SparseTensor_4x6() sp_tensor0 = sparse_ops.sparse_slice(sp_input, [0, 0], [2, 6]) sp_tensor1 = sparse_ops.sparse_slice(sp_input, [2, 0], [3, 7]) self.assertAllEqual( sp_tensor0.indices, [[0, 0], [0, 2], [0, 4], [0, 5], [1, 1], [1, 3], [1, 4]]) self.assertAllEqual(sp_tensor0.values, [0, 2, 4, 5, 11, 13, 14]) self.assertAllEqual(sp_tensor0.dense_shape, [2, 6]) self.assertAllEqual( sp_tensor1.indices, [[0, 0], [0, 3], [0, 5], [1, 0], [1, 2], [1, 3], [1, 5]]) self.assertAllEqual(sp_tensor1.values, [20, 23, 25, 30, 32, 33, 35]) self.assertAllEqual(sp_tensor1.dense_shape, [2, 6])
def _ExtractVolumePatchesGrad(op, grad): batch_size, planes_in, rows_in, cols_in, channels = [ dim.value for dim in op.inputs[0].shape.dims ] input_bphwc = array_ops.shape(op.inputs[0]) batch_size = input_bphwc[0] channels = input_bphwc[4] # Create indices matrix for input tensor. # Note that 0 is preserved for padding location, # so indices for input start from 1 to 1 + rows_in * cols_in. input_indices_num = 1 + planes_in * rows_in * cols_in input_idx = array_ops.reshape( math_ops.range(1, input_indices_num, dtype=ops.dtypes.int64), (1, planes_in, rows_in, cols_in, 1)) input_idx_patched = gen_array_ops.extract_volume_patches( input_idx, op.get_attr("ksizes"), op.get_attr("strides"), op.get_attr("padding")) # Create indices matrix for output tensor. _, planes_out, rows_out, cols_out, _ = [ dim.value for dim in op.outputs[0].shape.dims ] _, ksize_p, ksize_r, ksize_c, _ = op.get_attr("ksizes") # Indices for output start from 0. prc_indices_num = planes_out * rows_out * cols_out output_indices_num = prc_indices_num * ksize_p * ksize_r * ksize_c output_idx = array_ops.reshape( math_ops.range(output_indices_num, dtype=ops.dtypes.int64), (1, planes_out, rows_out, cols_out, ksize_p * ksize_r * ksize_c)) # Construct mapping table for indices: (input -> output). idx_matrix = array_ops.concat([ array_ops.expand_dims(input_idx_patched, axis=-1), array_ops.expand_dims(output_idx, axis=-1) ], axis=-1) idx_map = array_ops.reshape(idx_matrix, (-1, 2)) sp_shape = (input_indices_num, output_indices_num) sp_mat_full = sparse_tensor.SparseTensor( idx_map, array_ops.ones([output_indices_num], dtype=grad.dtype), sp_shape) # Remove all padding locations [0, :]. sp_mat = sparse_ops.sparse_slice(sp_mat_full, (1, 0), (input_indices_num - 1, output_indices_num)) grad_expanded = array_ops.transpose( array_ops.reshape( _IndexedSlicesToTensorNoWarning(grad), (batch_size, planes_out, rows_out, cols_out, ksize_p, ksize_r, ksize_c, channels)), (1, 2, 3, 4, 5, 6, 0, 7)) grad_flat = array_ops.reshape(grad_expanded, (-1, batch_size * channels)) jac = sparse_ops.sparse_tensor_dense_matmul(sp_mat, grad_flat) grad_out = array_ops.reshape( jac, (planes_in, rows_in, cols_in, batch_size, channels)) grad_out = array_ops.transpose(grad_out, (3, 0, 1, 2, 4)) return [grad_out]
def testSliceMatrixRows(self): with self.session(use_gpu=False): sp_input = self._SparseTensor_4x6() sp_tensor0 = sparse_ops.sparse_slice(sp_input, [0, 0], [2, 6]) sp_tensor1 = sparse_ops.sparse_slice(sp_input, [2, 0], [3, 7]) self.assertAllEqual( sp_tensor0.indices.eval(), [[0, 0], [0, 2], [0, 4], [0, 5], [1, 1], [1, 3], [1, 4]]) self.assertAllEqual(sp_tensor0.values.eval(), [0, 2, 4, 5, 11, 13, 14]) self.assertAllEqual(sp_tensor0.dense_shape.eval(), [2, 6]) self.assertAllEqual( sp_tensor1.indices.eval(), [[0, 0], [0, 3], [0, 5], [1, 0], [1, 2], [1, 3], [1, 5]]) self.assertAllEqual(sp_tensor1.values.eval(), [20, 23, 25, 30, 32, 33, 35]) self.assertAllEqual(sp_tensor1.dense_shape.eval(), [2, 6])
def slice_fn(t=t, ndims=ndims, new_shape=new_shape): """Slices the tensor.""" if isinstance(t, sparse_tensor.SparseTensor): return sparse_ops.sparse_slice(t, [0] * ndims, math_ops.to_int64(new_shape)) else: return array_ops.slice(t, [0] * ndims, new_shape)
def _ExtractImagePatchesGrad(op, grad): batch_size, rows_in, cols_in, channels = [ dim.value for dim in op.inputs[0].shape.dims ] input_bhwc = array_ops.shape(op.inputs[0]) batch_size = input_bhwc[0] channels = input_bhwc[3] # Create indices matrix for input tensor. # Note that 0 is preserved for padding location, # so indices for input start from 1 to 1 + rows_in * cols_in. input_indices_num = 1 + rows_in * cols_in input_idx = array_ops.reshape(math_ops.range(1, input_indices_num, dtype=ops.dtypes.int64), (1, rows_in, cols_in, 1)) input_idx_patched = gen_array_ops.extract_image_patches( input_idx, op.get_attr("ksizes"), op.get_attr("strides"), op.get_attr("rates"), op.get_attr("padding")) # Create indices matrix for output tensor. _, rows_out, cols_out, _ = [dim.value for dim in op.outputs[0].shape.dims] _, ksize_r, ksize_c, _ = op.get_attr("ksizes") # Indices for output start from 0. output_indices_num = rows_out * cols_out * ksize_r * ksize_c output_idx = array_ops.reshape(math_ops.range(output_indices_num, dtype=ops.dtypes.int64), (1, rows_out, cols_out, ksize_r * ksize_c)) # Construct mapping table for indices: (input -> output). idx_matrix = array_ops.concat( [array_ops.expand_dims(input_idx_patched, axis=-1), array_ops.expand_dims(output_idx, axis=-1)], axis=-1) idx_map = array_ops.reshape(idx_matrix, (-1, 2)) sp_shape = (input_indices_num, output_indices_num) sp_mat_full = sparse_tensor.SparseTensor( idx_map, array_ops.ones([output_indices_num], dtype=grad.dtype), sp_shape) # Remove all padding locations [0, :]. sp_mat = sparse_ops.sparse_slice(sp_mat_full, (1, 0), (input_indices_num - 1, output_indices_num)) grad_expanded = array_ops.transpose( array_ops.reshape( grad, (batch_size, rows_out, cols_out, ksize_r, ksize_c, channels)), (1, 2, 3, 4, 0, 5)) grad_flat = array_ops.reshape(grad_expanded, (-1, batch_size * channels)) jac = sparse_ops.sparse_tensor_dense_matmul(sp_mat, grad_flat) grad_out = array_ops.reshape(jac, (rows_in, cols_in, batch_size, channels)) grad_out = array_ops.transpose(grad_out, (2, 0, 1, 3)) return [grad_out]
def _ExtractImagePatchesGrad(op, grad): input_bhwc = array_ops.shape(op.inputs[0], out_type=dtypes.int64) batch_size, rows_in, cols_in, channels = input_bhwc[0], input_bhwc[1], \ input_bhwc[2], input_bhwc[3] # Create indices matrix for input tensor. # Note that 0 is preserved for padding location, # so indices for input start from 1 to 1 + rows_in * cols_in. input_indices_num = 1 + rows_in * cols_in input_idx = array_ops.reshape( math_ops.range(1, input_indices_num, dtype=ops.dtypes.int64), (1, rows_in, cols_in, 1)) input_idx_patched = gen_array_ops.extract_image_patches( input_idx, op.get_attr("ksizes"), op.get_attr("strides"), op.get_attr("rates"), op.get_attr("padding")) # Create indices matrix for output tensor. output_bhwc = array_ops.shape(op.outputs[0], out_type=dtypes.int64) rows_out, cols_out = output_bhwc[1], output_bhwc[2] _, ksize_r, ksize_c, _ = op.get_attr("ksizes") # Indices for output start from 0. output_indices_num = rows_out * cols_out * ksize_r * ksize_c output_idx = array_ops.reshape( math_ops.range(output_indices_num, dtype=ops.dtypes.int64), (1, rows_out, cols_out, ksize_r * ksize_c)) # Construct mapping table for indices: (input -> output). idx_matrix = array_ops.concat([ array_ops.expand_dims(input_idx_patched, axis=-1), array_ops.expand_dims(output_idx, axis=-1) ], axis=-1) idx_map = array_ops.reshape(idx_matrix, (-1, 2)) sp_shape = (input_indices_num, output_indices_num) sp_mat_full = sparse_tensor.SparseTensor( idx_map, array_ops.ones([output_indices_num], dtype=grad.dtype), sp_shape) # Remove all padding locations [0, :]. sp_mat = sparse_ops.sparse_slice( sp_mat_full, (1, 0), (input_indices_num - 1, output_indices_num)) with warnings.catch_warnings(): warnings.filterwarnings( "ignore", message="Converting sparse IndexedSlices to a dense Tensor.*") grad_expanded = array_ops.transpose( array_ops.reshape( grad, (batch_size, rows_out, cols_out, ksize_r, ksize_c, channels)), (1, 2, 3, 4, 0, 5)) grad_flat = array_ops.reshape(grad_expanded, (-1, batch_size * channels)) jac = sparse_ops.sparse_tensor_dense_matmul(sp_mat, grad_flat) grad_out = array_ops.reshape(jac, (rows_in, cols_in, batch_size, channels)) grad_out = array_ops.transpose(grad_out, (2, 0, 1, 3)) return [grad_out]
def testSliceEmpty(self): with test_util.use_gpu(): sp_empty = self._SparseTensor_4x6_empty() sp_input = self._SparseTensor_4x6() sparse_tensor0 = sparse_ops.sparse_slice(sp_empty, [0, 0], [4, 1]) sparse_tensor1 = sparse_ops.sparse_slice(sp_input, [1, 1], [0, 0]) sparse_tensor2 = sparse_ops.sparse_slice(sp_input, [2, 1], [2, 1]) empty_inds = np.empty(shape=(0, 2), dtype=np.int64) self.assertAllEqual(sparse_tensor0.indices, empty_inds) self.assertAllEqual(sparse_tensor0.values, []) self.assertAllEqual(sparse_tensor0.dense_shape, [4, 1]) self.assertAllEqual(sparse_tensor1.indices, empty_inds) self.assertAllEqual(sparse_tensor1.values, []) self.assertAllEqual(sparse_tensor1.dense_shape, [0, 0]) self.assertAllEqual(sparse_tensor2.indices, empty_inds) self.assertAllEqual(sparse_tensor2.values, []) self.assertAllEqual(sparse_tensor2.dense_shape, [2, 1])
def testSliceEmpty(self): # SparseSlice does not currently have a GPU kernel. with test_util.force_cpu(): sp_empty = self._SparseTensor_4x6_empty() sp_input = self._SparseTensor_4x6() sparse_tensor0 = sparse_ops.sparse_slice(sp_empty, [0, 0], [4, 1]) sparse_tensor1 = sparse_ops.sparse_slice(sp_input, [1, 1], [0, 0]) sparse_tensor2 = sparse_ops.sparse_slice(sp_input, [2, 1], [2, 1]) empty_inds = np.empty(shape=(0, 2), dtype=np.int64) self.assertAllEqual(sparse_tensor0.indices, empty_inds) self.assertAllEqual(sparse_tensor0.values, []) self.assertAllEqual(sparse_tensor0.dense_shape, [4, 1]) self.assertAllEqual(sparse_tensor1.indices, empty_inds) self.assertAllEqual(sparse_tensor1.values, []) self.assertAllEqual(sparse_tensor1.dense_shape, [0, 0]) self.assertAllEqual(sparse_tensor2.indices, empty_inds) self.assertAllEqual(sparse_tensor2.values, []) self.assertAllEqual(sparse_tensor2.dense_shape, [2, 1])
def testSliceColumns(self): with self.session(use_gpu=False): sp_input = self._SparseTensor_4x6() sparse_tensor0 = sparse_ops.sparse_slice(sp_input, [0, 0], [4, 2]) sparse_tensor1 = sparse_ops.sparse_slice(sp_input, [0, 2], [5, 2]) sparse_tensor2 = sparse_ops.sparse_slice(sp_input, [0, 4], [5, 3]) self.assertAllEqual(sparse_tensor0.indices, [[0, 0], [1, 1], [2, 0], [3, 0]]) self.assertAllEqual(sparse_tensor0.values, [0, 11, 20, 30]) self.assertAllEqual(sparse_tensor0.dense_shape, [4, 2]) self.assertAllEqual(sparse_tensor1.indices, [[0, 0], [1, 1], [2, 1], [3, 0], [3, 1]]) self.assertAllEqual(sparse_tensor1.values, [2, 13, 23, 32, 33]) self.assertAllEqual(sparse_tensor1.dense_shape, [4, 2]) self.assertAllEqual(sparse_tensor2.indices, [[0, 0], [0, 1], [1, 0], [2, 1], [3, 1]]) self.assertAllEqual(sparse_tensor2.values, [4, 5, 14, 25, 35]) self.assertAllEqual(sparse_tensor2.dense_shape, [4, 2])
def testSliceColumns(self): with self.session(use_gpu=False): sp_input = self._SparseTensor_4x6() sparse_tensor0 = sparse_ops.sparse_slice(sp_input, [0, 0], [4, 2]) sparse_tensor1 = sparse_ops.sparse_slice(sp_input, [0, 2], [5, 2]) sparse_tensor2 = sparse_ops.sparse_slice(sp_input, [0, 4], [5, 3]) self.assertAllEqual(sparse_tensor0.indices.eval(), [[0, 0], [1, 1], [2, 0], [3, 0]]) self.assertAllEqual(sparse_tensor0.values.eval(), [0, 11, 20, 30]) self.assertAllEqual(sparse_tensor0.dense_shape.eval(), [4, 2]) self.assertAllEqual(sparse_tensor1.indices.eval(), [[0, 0], [1, 1], [2, 1], [3, 0], [3, 1]]) self.assertAllEqual(sparse_tensor1.values.eval(), [2, 13, 23, 32, 33]) self.assertAllEqual(sparse_tensor1.dense_shape.eval(), [4, 2]) self.assertAllEqual(sparse_tensor2.indices.eval(), [[0, 0], [0, 1], [1, 0], [2, 1], [3, 1]]) self.assertAllEqual(sparse_tensor2.values.eval(), [4, 5, 14, 25, 35]) self.assertAllEqual(sparse_tensor2.dense_shape.eval(), [4, 2])
def testSliceAllRows(self): with self.session(): sp_input = self._SparseTensor_4x6() sp_tensor0 = sparse_ops.sparse_slice(sp_input, [0, 0], [1, 6]) sp_tensor1 = sparse_ops.sparse_slice(sp_input, [1, 0], [1, 6]) sp_tensor2 = sparse_ops.sparse_slice(sp_input, [2, 0], [1, 7]) sp_tensor3 = sparse_ops.sparse_slice(sp_input, [3, 0], [2, 7]) self.assertAllEqual(sp_tensor0.indices, [[0, 0], [0, 2], [0, 4], [0, 5]]) self.assertAllEqual(sp_tensor0.values, [0, 2, 4, 5]) self.assertAllEqual(sp_tensor0.dense_shape, [1, 6]) self.assertAllEqual(sp_tensor1.indices, [[0, 1], [0, 3], [0, 4]]) self.assertAllEqual(sp_tensor1.values, [11, 13, 14]) self.assertAllEqual(sp_tensor1.dense_shape, [1, 6]) self.assertAllEqual(sp_tensor2.indices, [[0, 0], [0, 3], [0, 5]]) self.assertAllEqual(sp_tensor2.values, [20, 23, 25]) self.assertAllEqual(sp_tensor2.dense_shape, [1, 6]) self.assertAllEqual(sp_tensor3.indices, [[0, 0], [0, 2], [0, 3], [0, 5]]) self.assertAllEqual(sp_tensor3.values, [30, 32, 33, 35]) self.assertAllEqual(sp_tensor3.dense_shape, [1, 6])
def testSliceAllColumns(self): with self.session(use_gpu=False): sp_input = self._SparseTensor_4x6() sparse_tensor0 = sparse_ops.sparse_slice(sp_input, [0, 0], [4, 1]) sparse_tensor1 = sparse_ops.sparse_slice(sp_input, [0, 1], [4, 1]) sparse_tensor2 = sparse_ops.sparse_slice(sp_input, [0, 2], [4, 1]) sparse_tensor3 = sparse_ops.sparse_slice(sp_input, [0, 3], [4, 1]) sparse_tensor4 = sparse_ops.sparse_slice(sp_input, [0, 4], [5, 1]) sparse_tensor5 = sparse_ops.sparse_slice(sp_input, [0, 5], [6, 3]) self.assertAllEqual(sparse_tensor0.indices, [[0, 0], [2, 0], [3, 0]]) self.assertAllEqual(sparse_tensor0.values, [0, 20, 30]) self.assertAllEqual(sparse_tensor0.dense_shape, [4, 1]) self.assertAllEqual(sparse_tensor1.indices, [[1, 0]]) self.assertAllEqual(sparse_tensor1.values, [11]) self.assertAllEqual(sparse_tensor1.dense_shape, [4, 1]) self.assertAllEqual(sparse_tensor2.indices, [[0, 0], [3, 0]]) self.assertAllEqual(sparse_tensor2.values, [2, 32]) self.assertAllEqual(sparse_tensor2.dense_shape, [4, 1]) self.assertAllEqual(sparse_tensor3.indices, [[1, 0], [2, 0], [3, 0]]) self.assertAllEqual(sparse_tensor3.dense_shape, [4, 1]) self.assertAllEqual(sparse_tensor3.values, [13, 23, 33]) self.assertAllEqual(sparse_tensor4.indices, [[0, 0], [1, 0]]) self.assertAllEqual(sparse_tensor4.values, [4, 14]) self.assertAllEqual(sparse_tensor4.dense_shape, [4, 1]) self.assertAllEqual(sparse_tensor5.indices, [[0, 0], [2, 0], [3, 0]]) self.assertAllEqual(sparse_tensor5.values, [5, 25, 35]) self.assertAllEqual(sparse_tensor5.dense_shape, [4, 1])
def testSliceAllColumns(self): with self.test_session(use_gpu=False): sp_input = self._SparseTensor_4x6() sparse_tensor0 = sparse_ops.sparse_slice(sp_input, [0, 0], [4, 1]) sparse_tensor1 = sparse_ops.sparse_slice(sp_input, [0, 1], [4, 1]) sparse_tensor2 = sparse_ops.sparse_slice(sp_input, [0, 2], [4, 1]) sparse_tensor3 = sparse_ops.sparse_slice(sp_input, [0, 3], [4, 1]) sparse_tensor4 = sparse_ops.sparse_slice(sp_input, [0, 4], [5, 1]) sparse_tensor5 = sparse_ops.sparse_slice(sp_input, [0, 5], [6, 3]) self.assertAllEqual(sparse_tensor0.indices.eval(), [[0, 0], [2, 0], [3, 0]]) self.assertAllEqual(sparse_tensor0.values.eval(), [0, 20, 30]) self.assertAllEqual(sparse_tensor0.dense_shape.eval(), [4, 1]) self.assertAllEqual(sparse_tensor1.indices.eval(), [[1, 0]]) self.assertAllEqual(sparse_tensor1.values.eval(), [11]) self.assertAllEqual(sparse_tensor1.dense_shape.eval(), [4, 1]) self.assertAllEqual(sparse_tensor2.indices.eval(), [[0, 0], [3, 0]]) self.assertAllEqual(sparse_tensor2.values.eval(), [2, 32]) self.assertAllEqual(sparse_tensor2.dense_shape.eval(), [4, 1]) self.assertAllEqual(sparse_tensor3.indices.eval(), [[1, 0], [2, 0], [3, 0]]) self.assertAllEqual(sparse_tensor3.dense_shape.eval(), [4, 1]) self.assertAllEqual(sparse_tensor3.values.eval(), [13, 23, 33]) self.assertAllEqual(sparse_tensor4.indices.eval(), [[0, 0], [1, 0]]) self.assertAllEqual(sparse_tensor4.values.eval(), [4, 14]) self.assertAllEqual(sparse_tensor4.dense_shape.eval(), [4, 1]) self.assertAllEqual(sparse_tensor5.indices.eval(), [[0, 0], [2, 0], [3, 0]]) self.assertAllEqual(sparse_tensor5.values.eval(), [5, 25, 35]) self.assertAllEqual(sparse_tensor5.dense_shape.eval(), [4, 1])
def testGradients(self): sp_input = self._SparseTensor_4x6(val_dtype=np.float32) start_and_size = [([0, 0], [4, 2]), ([0, 2], [5, 2]), ([0, 4], [5, 3])] with self.session(use_gpu=False): for start, size in start_and_size: sp_output = sparse_ops.sparse_slice(sp_input, start, size) nnz_in = len(self.evaluate(sp_input.values)) nnz_out = len(self.evaluate(sp_output.values)) err = gradient_checker.compute_gradient_error( [sp_input.values], [(nnz_in, )], sp_output.values, (nnz_out, )) self.assertLess(err, 1e-3)
def testGradients(self): sp_input = self._SparseTensor_4x6(val_dtype=np.float32) start_and_size = [([0, 0], [4, 2]), ([0, 2], [5, 2]), ([0, 4], [5, 3])] with self.session(use_gpu=False): for start, size in start_and_size: sp_output = sparse_ops.sparse_slice(sp_input, start, size) nnz_in = len(sp_input.values.eval()) nnz_out = len(sp_output.values.eval()) err = gradient_checker.compute_gradient_error( [sp_input.values], [(nnz_in,)], sp_output.values, (nnz_out,)) self.assertLess(err, 1e-3)
def _embedding_lookup_for_sparse_tensor( inp: sparse_tensor.SparseTensor, weight: Optional[sparse_tensor.SparseTensor], table: tf_variables.Variable, feature: tpu_embedding_v2_utils.FeatureConfig) -> ops.Tensor: """Embedding lookup for sparse tensor based on its feature config. Args: inp: a single SparseTensor input. weight: None or SparseTensor which has the same shape of the input. table: a table variable. feature: a feature config. Returns: Embedding lookup result. """ if not feature.output_shape and feature.max_sequence_length > 0: batch_size = math_ops.cast(array_ops.shape(inp)[0], dtype=dtypes.int64) sparse_shape = array_ops.stack( [batch_size, feature.max_sequence_length], axis=0) # TPU Embedding truncates sequences to max_sequence_length, and if we # don't truncate, scatter_nd will error out if the index was out of # bounds. truncated_inp = sparse_ops.sparse_slice(inp, start=[0, 0], size=sparse_shape) dense_output_shape = array_ops.stack( [batch_size, feature.max_sequence_length, feature.table.dim], axis=0) return array_ops.scatter_nd( truncated_inp.indices, array_ops.gather(table.read_value(), truncated_inp.values), dense_output_shape) else: inp_rank = inp.dense_shape.get_shape()[0] if (not feature.validate_weights_and_indices and inp_rank is not None and inp_rank <= 2): return embedding_ops.embedding_lookup_sparse_v2( table, inp, sp_weights=weight, combiner=feature.table.combiner) else: return embedding_ops.safe_embedding_lookup_sparse_v2( table, inp, sparse_weights=weight, combiner=feature.table.combiner)
def _transform_feature(self, inputs): """Returns dense `Tensor` representing feature. Args: inputs: A `_LazyBuilder` object to access inputs. Returns: Transformed feature `Tensor`. Raises: ValueError: if input rank is not known at graph building time. """ id_weight_pair = self.categorical_column._get_sparse_tensors(inputs) # pylint: disable=protected-access id_tensor = id_weight_pair.id_tensor weight_tensor = id_weight_pair.weight_tensor # If the underlying column is weighted, return the input as a dense tensor. if weight_tensor is not None: weighted_column = sparse_ops.sparse_merge( sp_ids=id_tensor, sp_values=weight_tensor, vocab_size=int(self._variable_shape[-1])) # Remove (?, -1) index weighted_column = sparse_ops.sparse_slice(weighted_column, [0, 0], weighted_column.dense_shape) #return sparse_ops.sparse_tensor_to_dense(weighted_column) return array_ops.scatter_nd(weighted_column.indices, weighted_column.values, weighted_column.dense_shape) dense_id_tensor = sparse_ops.sparse_tensor_to_dense( id_tensor, default_value=-1) # One hot must be float for tf.concat reasons since all other inputs to # input_layer are float32. one_hot_id_tensor = array_ops.one_hot( dense_id_tensor, depth=self._variable_shape[-1], on_value=1.0, off_value=0.0) # Reduce to get a multi-hot per example. return math_ops.reduce_sum(one_hot_id_tensor, axis=[-2])
def testSliceMatrixUnevenCols(self): with self.session(use_gpu=False): sp_input = self._SparseTensor_5x7() sp_tensor0 = sparse_ops.sparse_slice(sp_input, [0, 0], [5, 3]) sp_tensor1 = sparse_ops.sparse_slice(sp_input, [0, 3], [5, 2]) sp_tensor2 = sparse_ops.sparse_slice(sp_input, [0, 5], [5, 2]) self.assertAllEqual( sp_tensor0.indices.eval(), [[0, 0], [0, 2], [1, 1], [2, 0], [3, 0], [3, 2], [4, 1]]) self.assertAllEqual(sp_tensor0.values.eval(), [0, 2, 11, 20, 30, 32, 41]) self.assertAllEqual(sp_tensor0.dense_shape.eval(), [5, 3]) self.assertAllEqual( sp_tensor1.indices.eval(), [[0, 1], [1, 0], [1, 1], [2, 0], [3, 0], [4, 1]]) self.assertAllEqual(sp_tensor1.values.eval(), [4, 13, 14, 23, 33, 44]) self.assertAllEqual(sp_tensor1.dense_shape.eval(), [5, 2]) self.assertAllEqual(sp_tensor2.indices.eval(), [[0, 0], [1, 1], [2, 0], [3, 0], [4, 1]]) self.assertAllEqual(sp_tensor2.values.eval(), [5, 16, 25, 35, 46]) self.assertAllEqual(sp_tensor2.dense_shape.eval(), [5, 2]) sp_tensor0 = sparse_ops.sparse_slice(sp_input, [0, 0], [5, 2]) sp_tensor1 = sparse_ops.sparse_slice(sp_input, [0, 2], [5, 2]) sp_tensor2 = sparse_ops.sparse_slice(sp_input, [0, 4], [5, 2]) sp_tensor3 = sparse_ops.sparse_slice(sp_input, [0, 6], [5, 2]) self.assertAllEqual(sp_tensor0.indices.eval(), [[0, 0], [1, 1], [2, 0], [3, 0], [4, 1]]) self.assertAllEqual(sp_tensor0.values.eval(), [0, 11, 20, 30, 41]) self.assertAllEqual(sp_tensor0.dense_shape.eval(), [5, 2]) self.assertAllEqual(sp_tensor1.indices.eval(), [[0, 0], [1, 1], [2, 1], [3, 0], [3, 1]]) self.assertAllEqual(sp_tensor1.values.eval(), [2, 13, 23, 32, 33]) self.assertAllEqual(sp_tensor1.dense_shape.eval(), [5, 2]) self.assertAllEqual( sp_tensor2.indices.eval(), [[0, 0], [0, 1], [1, 0], [2, 1], [3, 1], [4, 0]]) self.assertAllEqual(sp_tensor2.values.eval(), [4, 5, 14, 25, 35, 44]) self.assertAllEqual(sp_tensor2.dense_shape.eval(), [5, 2]) self.assertAllEqual(sp_tensor3.indices.eval(), [[1, 0], [4, 0]]) self.assertAllEqual(sp_tensor3.values.eval(), [16, 46]) self.assertAllEqual(sp_tensor3.dense_shape.eval(), [5, 1])
def testSliceMatrixUnevenCols(self): with self.test_session(use_gpu=False): sp_input=self._SparseTensor_5x7() sp_tensor0 = sparse_ops.sparse_slice(sp_input, [0, 0], [5, 3]) sp_tensor1 = sparse_ops.sparse_slice(sp_input, [0, 3], [5, 2]) sp_tensor2 = sparse_ops.sparse_slice(sp_input, [0, 5], [5, 2]) self.assertAllEqual(sp_tensor0.indices.eval(), [[0, 0], [0, 2], [1, 1], [2, 0], [3, 0], [3, 2], [4, 1]]) self.assertAllEqual(sp_tensor0.values.eval(), [0, 2, 11, 20, 30, 32, 41]) self.assertAllEqual(sp_tensor0.dense_shape.eval(), [5, 3]) self.assertAllEqual(sp_tensor1.indices.eval(), [[0, 1], [1, 0], [1, 1], [2, 0], [3, 0], [4, 1]]) self.assertAllEqual(sp_tensor1.values.eval(), [4, 13, 14, 23, 33, 44]) self.assertAllEqual(sp_tensor1.dense_shape.eval(), [5, 2]) self.assertAllEqual(sp_tensor2.indices.eval(), [[0, 0], [1, 1], [2, 0], [3, 0], [4, 1]]) self.assertAllEqual(sp_tensor2.values.eval(), [5, 16, 25, 35, 46]) self.assertAllEqual(sp_tensor2.dense_shape.eval(), [5, 2]) sp_tensor0 = sparse_ops.sparse_slice(sp_input, [0, 0], [5, 2]) sp_tensor1 = sparse_ops.sparse_slice(sp_input, [0, 2], [5, 2]) sp_tensor2 = sparse_ops.sparse_slice(sp_input, [0, 4], [5, 2]) sp_tensor3 = sparse_ops.sparse_slice(sp_input, [0, 6], [5, 2]) self.assertAllEqual(sp_tensor0.indices.eval(), [[0, 0], [1, 1], [2, 0], [3, 0], [4, 1]]) self.assertAllEqual(sp_tensor0.values.eval(), [0, 11, 20, 30, 41]) self.assertAllEqual(sp_tensor0.dense_shape.eval(), [5, 2]) self.assertAllEqual(sp_tensor1.indices.eval(), [[0, 0], [1, 1], [2, 1], [3, 0], [3, 1]]) self.assertAllEqual(sp_tensor1.values.eval(), [2, 13, 23, 32, 33]) self.assertAllEqual(sp_tensor1.dense_shape.eval(), [5, 2]) self.assertAllEqual(sp_tensor2.indices.eval(), [[0, 0], [0, 1], [1, 0], [2, 1], [3, 1], [4, 0]]) self.assertAllEqual(sp_tensor2.values.eval(), [4, 5, 14, 25, 35, 44]) self.assertAllEqual(sp_tensor2.dense_shape.eval(), [5, 2]) self.assertAllEqual(sp_tensor3.indices.eval(), [[1, 0], [4, 0]]) self.assertAllEqual(sp_tensor3.values.eval(), [16, 46]) self.assertAllEqual(sp_tensor3.dense_shape.eval(), [5, 1])
def pad_sparse_embedding_lookup_indices(sparse_indices, padded_size): """Creates statically-sized Tensors containing indices and weights. From third_party/cloud_tpu/models/movielens/tpu_embedding.py Also computes sparse_indices.values % embedding_table_size, for equivalent functionality to sparse_column_with_integerized_feature. The returned padded weight Tensor also doubles as a mask indicating which values in the returned padded indices Tensor are indices versus padded zeros. Args: sparse_indices: SparseTensor of embedding lookup indices. padded_size: Number of columns of the returned Tensors. Indices which fall out of bounds will be truncated to the padded size. Returns: (sparse_indices.values padded to the specified size, a mask the same size as the returned padded values in which 0s indicate padded locations and 1s (or values from sparse_weights) indicate actual values) """ batch_size = sparse_indices.dense_shape[0] sparse_indices = sparse_ops.sparse_slice(sparse_indices, [0, 0], [batch_size, padded_size]) indices, values = sparse_indices.indices, sparse_indices.values padded_values = array_ops.scatter_nd(indices, math_ops.cast(values, dtypes.int32), shape=(batch_size, padded_size)) weights = array_ops.ones_like(values, dtype=dtypes.float32) padded_mask = array_ops.scatter_nd(indices, weights, shape=(batch_size, padded_size)) return padded_values, padded_mask
def _ExtractVolumePatchesGrad(op, grad): batch_size, planes_in, rows_in, cols_in, channels = [ dim.value for dim in op.inputs[0].shape.dims ] input_bphwc = array_ops.shape(op.inputs[0]) batch_size = input_bphwc[0] channels = input_bphwc[4] # Create indices matrix for input tensor. # Note that 0 is preserved for padding location, # so indices for input start from 1 to 1 + rows_in * cols_in. input_indices_num = 1 + planes_in * rows_in * cols_in input_idx = array_ops.reshape( math_ops.range(1, input_indices_num, dtype=ops.dtypes.int64), (1, planes_in, rows_in, cols_in, 1)) input_idx_patched = gen_array_ops.extract_volume_patches( input_idx, op.get_attr("ksizes"), op.get_attr("strides"), op.get_attr("padding")) # Create indices matrix for output tensor. _, planes_out, rows_out, cols_out, _ = [ dim.value for dim in op.outputs[0].shape.dims ] _, ksize_p, ksize_r, ksize_c, _ = op.get_attr("ksizes") # Indices for output start from 0. prc_indices_num = planes_out * rows_out * cols_out output_indices_num = prc_indices_num * ksize_p * ksize_r * ksize_c output_idx = array_ops.reshape( math_ops.range(output_indices_num, dtype=ops.dtypes.int64), (1, planes_out, rows_out, cols_out, ksize_p * ksize_r * ksize_c)) # Construct mapping table for indices: (input -> output). idx_matrix = array_ops.concat([ array_ops.expand_dims(input_idx_patched, axis=-1), array_ops.expand_dims(output_idx, axis=-1) ], axis=-1) idx_map = array_ops.reshape(idx_matrix, (-1, 2)) sp_shape = (input_indices_num, output_indices_num) sp_mat_full = sparse_tensor.SparseTensor( idx_map, array_ops.ones([output_indices_num], dtype=grad.dtype), sp_shape) # Remove all padding locations [0, :]. sp_mat = sparse_ops.sparse_slice(sp_mat_full, (1, 0), (input_indices_num - 1, output_indices_num)) with warnings.catch_warnings(): warnings.filterwarnings( "ignore", message="Converting sparse IndexedSlices to a dense Tensor.*") grad_expanded = array_ops.transpose( array_ops.reshape(grad, (batch_size, planes_out, rows_out, cols_out, ksize_p, ksize_r, ksize_c, channels)), (1, 2, 3, 4, 5, 6, 0, 7)) grad_flat = array_ops.reshape(grad_expanded, (-1, batch_size * channels)) jac = sparse_ops.sparse_tensor_dense_matmul(sp_mat, grad_flat) grad_out = array_ops.reshape( jac, (planes_in, rows_in, cols_in, batch_size, channels)) grad_out = array_ops.transpose(grad_out, (3, 0, 1, 2, 4)) return [grad_out]