def testNCELoss(self): # A simple test to verify the numerics. def _SigmoidCrossEntropyWithLogits(logits, targets): # logits, targets: float arrays of the same shape. assert logits.shape == targets.shape pred = 1.0 / (1.0 + np.exp(-logits)) eps = 0.0001 pred = np.minimum(np.maximum(pred, eps), 1 - eps) return -targets * np.log(pred) - (1.0 - targets) * np.log(1.0 - pred) weights, biases, hidden_acts, sharded_weights = self._GenerateTestInputs() labels = [0, 1, 2] true_w, true_b = weights[labels], biases[labels] sampled = [1, 0, 2, 3] num_sampled = len(sampled) true_exp = np.empty([self._batch_size, 1], dtype=np.float32) true_exp.fill(0.5) sampled_exp = np.empty([num_sampled], dtype=np.float32) sampled_exp.fill(0.5) sampled_w, sampled_b = weights[sampled], biases[sampled] test_sampled_vals = (sampled, true_exp, sampled_exp) with self.test_session(): logits_np, labels_np = self._ComputeSampledLogitsNP( true_w, true_b, sampled_w, sampled_b, hidden_acts, true_expected=true_exp, sampled_expected=sampled_exp ) nce_loss_np = np.sum(_SigmoidCrossEntropyWithLogits(logits_np, labels_np), 1) labels_tf = constant_op.constant(labels, shape=(self._batch_size, 1)) weights_tf = constant_op.constant(weights) biases_tf = constant_op.constant(biases) inputs_tf = constant_op.constant(hidden_acts) nce_loss_tf = nn.nce_loss( weights_tf, biases_tf, inputs_tf, labels_tf, num_sampled=1, num_classes=self._num_classes, num_true=1, sampled_values=test_sampled_vals, ) self.assertAllClose(nce_loss_np, nce_loss_tf.eval(), 1e-4) # Test with sharded weights nce_loss_tf = nn.nce_loss( [constant_op.constant(shard) for shard in sharded_weights], biases_tf, inputs_tf, labels_tf, num_sampled=1, num_classes=self._num_classes, num_true=1, sampled_values=test_sampled_vals, ) self.assertAllClose(nce_loss_np, nce_loss_tf.eval(), 1e-4)
def ones(shape, dtype=dtypes.float32, name=None): """Creates a tensor with all elements set to 1. This operation returns a tensor of type `dtype` with shape `shape` and all elements set to 1. For example: ```python tf.ones([2, 3], int32) ==> [[1, 1, 1], [1, 1, 1]] ``` Args: shape: Either a list of integers, or a 1-D `Tensor` of type `int32`. dtype: The type of an element in the resulting `Tensor`. name: A name for the operation (optional). Returns: A `Tensor` with all elements set to 1. """ with ops.op_scope([shape], name, "ones") as name: if isinstance(shape, list): output = constant(1, shape=shape, dtype=dtype, name=name) else: shape = ops.convert_to_tensor(shape, name="shape") output = fill(shape, constant(1, dtype=dtype), name=name) assert output.dtype.base_dtype == dtypes.as_dtype(dtype).base_dtype return output
def testNoOp(self): img_shape = [1, 6, 4, 1] single_shape = [6, 4, 1] data = [128, 128, 64, 64, 128, 128, 64, 64, 64, 64, 128, 128, 64, 64, 128, 128, 50, 50, 100, 100, 50, 50, 100, 100] img_np = np.array(data, dtype=np.uint8).reshape(img_shape) target_height = 6 target_width = 4 for opt in self.OPTIONS: with self.test_session() as sess: image = constant_op.constant(img_np, shape=img_shape) y = image_ops.resize_images(image, target_height, target_width, opt) yshape = array_ops.shape(y) resized, newshape = sess.run([y, yshape]) self.assertAllEqual(img_shape, newshape) self.assertAllClose(resized, img_np, atol=1e-5) # Resizing with a single image must leave the shape unchanged also. with self.test_session(): img_single = img_np.reshape(single_shape) image = constant_op.constant(img_single, shape=single_shape) y = image_ops.resize_images(image, target_height, target_width, self.OPTIONS[0]) yshape = array_ops.shape(y) newshape = yshape.eval() self.assertAllEqual(single_shape, newshape)
def testFetchSparseTensor(self): with session.Session() as s: indices = np.array([[3, 2, 0], [4, 5, 1]]).astype(np.int64) values = np.array([1.0, 2.0]).astype(np.float32) shape = np.array([7, 9, 2]).astype(np.int64) sp = ops.SparseTensor( constant_op.constant(indices), constant_op.constant(values), constant_op.constant(shape)) # Single fetch, use as tuple sp_out = s.run(sp) indices_out, values_out, shape_out = sp_out self.assertAllEqual(indices_out, indices) self.assertAllEqual(values_out, values) self.assertAllEqual(shape_out, shape) # Single fetch, use as SparseTensorValue sp_out = s.run(sp) self.assertAllEqual(sp_out.indices, indices) self.assertAllEqual(sp_out.values, values) self.assertAllEqual(sp_out.shape, shape) # Tuple fetch, use as tuple indices_out, values_out, shape_out = s.run(sp) self.assertAllEqual(indices_out, indices) self.assertAllEqual(values_out, values) self.assertAllEqual(shape_out, shape) # List fetch, use as tuple (indices_out, values_out, shape_out), = s.run([sp]) self.assertAllEqual(indices_out, indices) self.assertAllEqual(values_out, values) self.assertAllEqual(shape_out, shape) # List fetch, use as SparseTensorValue sp_out, = s.run([sp]) self.assertAllEqual(sp_out.indices, indices) self.assertAllEqual(sp_out.values, values) self.assertAllEqual(sp_out.shape, shape)
def _testDefaultGraphInThread(self, constructed_event, continue_event, i): with session.Session() as s: self.assertEqual(ops.get_default_graph(), s.graph) a = constant_op.constant(1.0, shape=[1, 2]) b = constant_op.constant(2.0, shape=[2, 3]) c = math_ops.matmul(a, b) v = variables.Variable(c, name='var_%d' % i) # Block here until all threads have constructed their graph. constructed_event.set() continue_event.wait() assign_c_to_v = state_ops.assign(v, c) v.initializer.run() assign_c_to_v.eval() v_val = v.eval() self.assertAllEqual([[4.0, 4.0, 4.0]], v_val) d = constant_op.constant(3.0, shape=[2, 3]) e = math_ops.matmul(a, d) assign_e_to_v = state_ops.assign(v, e) e_val = e.eval() self.assertAllEqual([[6.0, 6.0, 6.0]], e_val) v_val = v.eval() self.assertAllEqual([[4.0, 4.0, 4.0]], v_val) s.run(assign_e_to_v) v_val = v.eval() self.assertAllEqual([[6.0, 6.0, 6.0]], v_val) self.assertEqual(ops.get_default_graph(), s.graph)
def testFetchIndexedSlicesWithoutDenseShape(self): with session.Session() as s: indices = np.array([[3, 2, 0], [4, 5, 1]]).astype(np.int64) values = np.array([1.0, 2.0]).astype(np.float32) dense_shape = None ind = ops.IndexedSlices( constant_op.constant(values), constant_op.constant(indices), None) # Single fetch, use as tuple ind_out = s.run(ind) values_out, indices_out, dense_shape_out = ind_out self.assertAllEqual(values_out, values) self.assertAllEqual(indices_out, indices) self.assertAllEqual(dense_shape_out, dense_shape) # Single fetch, use as IndexedSlicesValue ind_out = s.run(ind) self.assertAllEqual(ind_out.values, values) self.assertAllEqual(ind_out.indices, indices) self.assertAllEqual(ind_out.dense_shape, dense_shape) # Tuple fetch, use as tuple values_out, indices_out, dense_shape_out = s.run(ind) self.assertAllEqual(values_out, values) self.assertAllEqual(indices_out, indices) self.assertAllEqual(dense_shape_out, dense_shape) # List fetch, use as tuple (values_out, indices_out, dense_shape_out), = s.run([ind]) self.assertAllEqual(values_out, values) self.assertAllEqual(indices_out, indices) self.assertAllEqual(dense_shape_out, dense_shape) # List fetch, use as IndexedSlicesValue ind_out, = s.run([ind]) self.assertAllEqual(ind_out.values, values) self.assertAllEqual(ind_out.indices, indices) self.assertAllEqual(ind_out.dense_shape, dense_shape)
def testMultiColocationGroups(self): a = constant_op.constant([2.0], name="a") b = constant_op.constant(3.0, name="b") with ops.colocate_with(a.op): with ops.colocate_with(b.op): c = constant_op.constant(4.0) self.assertEqual(set([b"loc:@a", b"loc:@b"]), set(c.op.colocation_groups()))
def testFetchByNameDifferentStringTypes(self): with session.Session() as sess: c = constant_op.constant(42.0, name='c') d = constant_op.constant(43.0, name=u'd') e = constant_op.constant(44.0, name=b'e') f = constant_op.constant(45.0, name=r'f') self.assertTrue(isinstance(c.name, six.text_type)) self.assertTrue(isinstance(d.name, six.text_type)) self.assertTrue(isinstance(e.name, six.text_type)) self.assertTrue(isinstance(f.name, six.text_type)) self.assertEqual(42.0, sess.run('c:0')) self.assertEqual(42.0, sess.run(u'c:0')) self.assertEqual(42.0, sess.run(b'c:0')) self.assertEqual(42.0, sess.run(r'c:0')) self.assertEqual(43.0, sess.run('d:0')) self.assertEqual(43.0, sess.run(u'd:0')) self.assertEqual(43.0, sess.run(b'd:0')) self.assertEqual(43.0, sess.run(r'd:0')) self.assertEqual(44.0, sess.run('e:0')) self.assertEqual(44.0, sess.run(u'e:0')) self.assertEqual(44.0, sess.run(b'e:0')) self.assertEqual(44.0, sess.run(r'e:0')) self.assertEqual(45.0, sess.run('f:0')) self.assertEqual(45.0, sess.run(u'f:0')) self.assertEqual(45.0, sess.run(b'f:0')) self.assertEqual(45.0, sess.run(r'f:0'))
def testWarnings(self): # Smaller than the threshold: no warning. c_sparse = ops.IndexedSlices(array_ops.placeholder(dtypes.float32), array_ops.placeholder(dtypes.int32), constant([4, 4, 4, 4])) with warnings.catch_warnings(record=True) as w: math_ops.mul(c_sparse, 1.0) self.assertEqual(0, len(w)) # Greater than or equal to the threshold: warning. c_sparse = ops.IndexedSlices(array_ops.placeholder(dtypes.float32), array_ops.placeholder(dtypes.int32), constant([100, 100, 100, 100])) with warnings.catch_warnings(record=True) as w: math_ops.mul(c_sparse, 1.0) self.assertEqual(1, len(w)) self.assertTrue( "with 100000000 elements. This may consume a large amount of memory." in str(w[0].message)) # Unknown dense shape: warning. c_sparse = ops.IndexedSlices(array_ops.placeholder(dtypes.float32), array_ops.placeholder(dtypes.int32), array_ops.placeholder(dtypes.int32)) with warnings.catch_warnings(record=True) as w: math_ops.mul(c_sparse, 1.0) self.assertEqual(1, len(w)) self.assertTrue( "of unknown shape. This may consume a large amount of memory." in str(w[0].message))
def testCircularConvolution(self): v = constant_op.constant([1,2,3,4,5,6,7], dtype=tf.float32) k = constant_op.constant([0,0,1], dtype=tf.float32) for use_gpu in [True, False]: with self.test_session(use_gpu=use_gpu): cir_conv = circular_convolution(v, k).eval() self.assertAllEqual(cir_conv, [7,1,2,3,4,5,6])
def testFetchByNameDifferentStringTypes(self): with session.Session() as sess: c = constant_op.constant(42.0, name="c") d = constant_op.constant(43.0, name=u"d") e = constant_op.constant(44.0, name=b"e") f = constant_op.constant(45.0, name=r"f") self.assertTrue(isinstance(c.name, six.text_type)) self.assertTrue(isinstance(d.name, six.text_type)) self.assertTrue(isinstance(e.name, six.text_type)) self.assertTrue(isinstance(f.name, six.text_type)) self.assertEqual(42.0, sess.run("c:0")) self.assertEqual(42.0, sess.run(u"c:0")) self.assertEqual(42.0, sess.run(b"c:0")) self.assertEqual(42.0, sess.run(r"c:0")) self.assertEqual(43.0, sess.run("d:0")) self.assertEqual(43.0, sess.run(u"d:0")) self.assertEqual(43.0, sess.run(b"d:0")) self.assertEqual(43.0, sess.run(r"d:0")) self.assertEqual(44.0, sess.run("e:0")) self.assertEqual(44.0, sess.run(u"e:0")) self.assertEqual(44.0, sess.run(b"e:0")) self.assertEqual(44.0, sess.run(r"e:0")) self.assertEqual(45.0, sess.run("f:0")) self.assertEqual(45.0, sess.run(u"f:0")) self.assertEqual(45.0, sess.run(b"f:0")) self.assertEqual(45.0, sess.run(r"f:0"))
def _testTypesForAdam(self, var, m, v, grad, use_gpu): self.setUp() with self.test_session(use_gpu=use_gpu): var_t = variables.Variable(var) m_t = variables.Variable(m) v_t = variables.Variable(v) t = 1 beta1 = np.array(0.9, dtype=var.dtype) beta2 = np.array(0.999, dtype=var.dtype) beta1_power = beta1**t beta2_power = beta2**t lr = np.array(0.001, dtype=var.dtype) epsilon = np.array(1e-8, dtype=var.dtype) beta1_t = constant_op.constant(beta1, self._toType(var.dtype), []) beta2_t = constant_op.constant(beta2, self._toType(var.dtype), []) beta1_power_t = variables.Variable(beta1_power) beta2_power_t = variables.Variable(beta2_power) lr_t = constant_op.constant(lr, self._toType(var.dtype), []) epsilon_t = constant_op.constant(epsilon, self._toType(var.dtype), []) variables.initialize_all_variables().run() self.assertAllCloseAccordingToType(var, var_t.eval()) new_var, _, _ = self._adamUpdateNumpy(var, grad, t, m, v, lr, beta1, beta2, epsilon) apply_adam = training_ops.apply_adam(var_t, m_t, v_t, beta1_power_t, beta2_power_t, lr_t, beta1_t, beta2_t, epsilon_t, grad) out = apply_adam.eval() self.assertShapeEqual(out, apply_adam) self.assertAllCloseAccordingToType(new_var, out)
def testScalarMul(self): with self.test_session(): values = constant_op.constant([2, 3, 5, 7], shape=[2, 2]) indices = constant_op.constant([0, 2]) x = math_ops.scalar_mul(-2, ops.IndexedSlices(values, indices)) self.assertAllEqual(x.values.eval(), [[-4, -6], [-10, -14]]) self.assertAllEqual(x.indices.eval(), [0, 2])
def testNegation(self): with self.test_session(): values = constant_op.constant([2, 3, 5, 7], shape=[2, 2]) indices = constant_op.constant([0, 2]) x = -ops.IndexedSlices(values, indices) self.assertAllEqual(x.values.eval(), [[-2, -3], [-5, -7]]) self.assertAllEqual(x.indices.eval(), [0, 2])
def _testBatchNormGradient(self, param_index, tag, scale_after_normalization, err_tolerance=1e-11): x_shape = [3, 5, 4, 5] param_shape = [5] np.random.seed(1) # Make it reproducible. x_val = np.random.random_sample(x_shape).astype(np.float64) m_val = np.random.random_sample(param_shape).astype(np.float64) v_val = np.random.random_sample(param_shape).astype(np.float64) beta_val = np.random.random_sample(param_shape).astype(np.float64) gamma_val = np.random.random_sample(param_shape).astype(np.float64) with self.test_session(): x = constant_op.constant(x_val, name="x") m = constant_op.constant(m_val, name="m") v = constant_op.constant(v_val, name="v") beta = constant_op.constant(beta_val, name="beta") gamma = constant_op.constant(gamma_val, name="gamma") epsilon = 0.001 # If scale_after_normalization is False, backprop for gamma # will be 0. gamma is unchanged. output = nn.batch_norm_with_global_normalization( x, m, v, beta, gamma, epsilon, scale_after_normalization) all_params = [x, m, v, beta, gamma] all_shapes = [x_shape, param_shape, param_shape, param_shape, param_shape] err = gc.ComputeGradientError(all_params[param_index], all_shapes[param_index], output, x_shape) print "Batch normalization %s gradient %s scale err = " % ( tag, "with" if scale_after_normalization else "without" ), err self.assertLess(err, err_tolerance)
def testBatchNorm(self): x_shape = [3, 5, 4, 2] param_shape = [2] x_val = np.random.random_sample(x_shape).astype(np.float32) m_val = np.random.random_sample(param_shape).astype(np.float32) v_val = np.random.random_sample(param_shape).astype(np.float32) beta_val = np.random.random_sample(param_shape).astype(np.float32) gamma_val = np.random.random_sample(param_shape).astype(np.float32) for use_gpu in [True, False]: with self.test_session(use_gpu=use_gpu) as sess: x = constant_op.constant(x_val, name="x") m = constant_op.constant(m_val, name="m") v = constant_op.constant(v_val, name="v") beta = constant_op.constant(beta_val, name="beta") gamma = constant_op.constant(gamma_val, name="gamma") epsilon = 0.001 for scale_after_normalization in [True, False]: bn = nn.batch_norm_with_global_normalization( x, m, v, beta, gamma, epsilon, scale_after_normalization) on = self._opsBatchNorm( x, m, v, beta, gamma, epsilon, scale_after_normalization) np_batch_norm = self._npBatchNorm( x_val, m_val, v_val, beta_val, gamma_val, epsilon, scale_after_normalization) tf_batch_norm, ops_batch_norm = sess.run([bn, on]) self.assertAllClose(np_batch_norm, tf_batch_norm, atol=0.000001) self.assertAllClose(np_batch_norm, ops_batch_norm, atol=0.000001) self.assertAllClose(tf_batch_norm, ops_batch_norm, atol=0.000001)
def testDeConv2DSame(self): with self.test_session(): strides = [1, 2, 2, 1] # Input, output: [batch, height, width, depth] x_shape = [2, 6, 4, 3] y_shape = [2, 12, 8, 2] # Filter: [kernel_height, kernel_width, output_depth, input_depth] f_shape = [3, 3, 2, 3] x = constant_op.constant(1.0, shape=x_shape, name="x", dtype=types.float32) f = constant_op.constant(1.0, shape=f_shape, name="filter", dtype=types.float32) output = nn.deconv2d(x, f, y_shape, strides=strides, padding="SAME") value = output.eval() for n in xrange(x_shape[0]): for k in xrange(f_shape[2]): for w in xrange(y_shape[2]): for h in xrange(y_shape[1]): target = 3.0 # We add a case for locations divisible by the stride. h_in = h % strides[1] == 0 and h > 0 and h < y_shape[1] - 1 w_in = w % strides[2] == 0 and w > 0 and w < y_shape[2] - 1 if h_in and w_in: target += 9.0 elif h_in or w_in: target += 3.0 self.assertAllClose(target, value[n, h, w, k])
def testRandomization(self): # Run 1x1 crop num_samples times in an image and ensure that one finds each # pixel 1/num_pixels of the time. num_samples = 1000 height = 5 width = 4 num_pixels = height * width data = np.arange(num_pixels).reshape([height, width, 1]) x_np = np.array(data).astype(np.int32) target_shape_np = np.array([1, 1], dtype=np.int64) y = [] with self.test_session(): x = constant_op.constant(x_np, shape=x_np.shape) target_shape = constant_op.constant(target_shape_np, shape=[2]) y_tf = image_ops.random_crop(x, target_shape) for _ in xrange(num_samples): y_np = y_tf.eval() self.assertAllEqual(y_np.shape, [1, 1, 1]) y.extend(y_np.flatten()) # Calculate the mean and 4 * standard deviation. mean = [num_samples / num_pixels] * num_pixels four_stddev = 4.0 * np.sqrt(mean) # Ensure that each entry is observed in 1/num_pixels of the samples # within 4 standard deviations. counts = np.bincount(y) self.assertAllClose(counts, mean, atol=four_stddev)
def testColocationIgnoreStack(self): a = constant_op.constant([2.0], name="a") b = constant_op.constant(3.0, name="b") with ops.colocate_with(a.op): with ops.colocate_with(b.op, ignore_existing=True): c = constant_op.constant(4.0) self.assertEqual(set([b"loc:@b"]), set(c.op.colocation_groups()))
def testNoOp(self): img_shape = [1, 6, 4, 1] single_shape = [6, 4, 1] # This test is also conducted with int8, so 127 is the maximum # value that can be used. data = [127, 127, 64, 64, 127, 127, 64, 64, 64, 64, 127, 127, 64, 64, 127, 127, 50, 50, 100, 100, 50, 50, 100, 100] target_height = 6 target_width = 4 for nptype in self.TYPES: img_np = np.array(data, dtype=nptype).reshape(img_shape) for opt in self.OPTIONS: with self.test_session() as sess: image = constant_op.constant(img_np, shape=img_shape) y = image_ops.resize_images(image, target_height, target_width, opt) yshape = array_ops.shape(y) resized, newshape = sess.run([y, yshape]) self.assertAllEqual(img_shape, newshape) self.assertAllClose(resized, img_np, atol=1e-5) # Resizing with a single image must leave the shape unchanged also. with self.test_session(): img_single = img_np.reshape(single_shape) image = constant_op.constant(img_single, shape=single_shape) y = image_ops.resize_images(image, target_height, target_width, self.OPTIONS[0]) yshape = array_ops.shape(y) newshape = yshape.eval() self.assertAllEqual(single_shape, newshape)
def testDeConv2DSingleStride(self): with self.test_session(): strides = [1, 1, 1, 1] # Input, output: [batch, height, width, depth] x_shape = [2, 6, 4, 3] y_shape = [2, 6, 4, 2] # Filter: [kernel_height, kernel_width, output_depth, input_depth] f_shape = [3, 3, 2, 3] x = constant_op.constant(1.0, shape=x_shape, name="x", dtype=dtypes.float32) f = constant_op.constant(1.0, shape=f_shape, name="filter", dtype=dtypes.float32) output = nn.deconv2d(x, f, y_shape, strides=strides, padding="SAME") value = output.eval() # We count the number of cells being added at the locations in the output. # At the center, #cells=kernel_height * kernel_width # At the corners, #cells=ceil(kernel_height/2) * ceil(kernel_width/2) # At the borders, #cells=ceil(kernel_height/2)*kernel_width or # kernel_height * ceil(kernel_width/2) for n in xrange(x_shape[0]): for k in xrange(f_shape[2]): for w in xrange(y_shape[2]): for h in xrange(y_shape[1]): target = 4 * 3.0 h_in = h > 0 and h < y_shape[1] - 1 w_in = w > 0 and w < y_shape[2] - 1 if h_in and w_in: target += 5 * 3.0 elif h_in or w_in: target += 2 * 3.0 self.assertAllClose(target, value[n, h, w, k])
def testSampledSoftmaxLoss(self): # A simple test to verify the numerics. def _SoftmaxCrossEntropyWithLogits(logits, targets): # logits, targets: float arrays of the same shape. assert logits.shape == targets.shape stable_exp_logits = np.exp(logits - np.amax(logits, axis=1, keepdims=True)) pred = stable_exp_logits / np.sum(stable_exp_logits, 1, keepdims=True) return -np.sum(targets * np.log(pred + 1.0e-20), axis=1) weights, biases, hidden_acts, sharded_weights = self._GenerateTestInputs() labels = [0, 1, 2] true_w, true_b = weights[labels], biases[labels] sampled = [1, 0, 2, 3] num_sampled = len(sampled) true_exp = np.full([self._batch_size, 1], fill_value=0.5, dtype=np.float32) sampled_exp = np.full([num_sampled], fill_value=0.5, dtype=np.float32) sampled_w, sampled_b = weights[sampled], biases[sampled] test_sampled_vals = (sampled, true_exp, sampled_exp) with self.test_session(): logits_np, labels_np = self._ComputeSampledLogitsNP( true_w, true_b, sampled_w, sampled_b, hidden_acts, true_expected=true_exp, sampled_expected=sampled_exp ) sampled_softmax_loss_np = _SoftmaxCrossEntropyWithLogits(logits_np, labels_np) labels_tf = constant_op.constant(labels, shape=(self._batch_size, 1)) weights_tf = constant_op.constant(weights) biases_tf = constant_op.constant(biases) inputs_tf = constant_op.constant(hidden_acts) sampled_softmax_loss_tf = nn.sampled_softmax_loss( weights_tf, biases_tf, inputs_tf, labels_tf, num_sampled=1, num_classes=self._num_classes, num_true=1, sampled_values=test_sampled_vals, remove_accidental_hits=False, ) self.assertAllClose(sampled_softmax_loss_np, sampled_softmax_loss_tf.eval(), 1e-4) # Test with sharded weights sampled_softmax_loss_tf = nn.sampled_softmax_loss( [constant_op.constant(shard) for shard in sharded_weights], biases_tf, inputs_tf, labels_tf, num_sampled=1, num_classes=self._num_classes, num_true=1, sampled_values=test_sampled_vals, remove_accidental_hits=False, ) self.assertAllClose(sampled_softmax_loss_np, sampled_softmax_loss_tf.eval(), 1e-4)
def testUseDefaultGraph(self): with ops.Graph().as_default(), ops.device('/cpu:0'): a = constant_op.constant(6.0, shape=[1, 1]) b = constant_op.constant(7.0, shape=[1, 1]) c = math_ops.matmul(a, b, name='matmul') with session.Session(): result = c.eval() self.assertAllEqual(result, [[42.0]])
def testDuplicatedInputs(self): with session.Session() as sess: a = constant_op.constant(1.0, shape=[1, 2]) b = constant_op.constant(2.0, shape=[1, 3]) a_val, b_val, a2_val = sess.run([a, b, a]) self.assertAllEqual(a_val, [[1.0, 1.0]]) self.assertAllEqual(b_val, [[2.0, 2.0, 2.0]]) self.assertAllEqual(a2_val, [[1.0, 1.0]])
def testToTensor(self): with self.test_session(): values = constant_op.constant([2, 3, 5, 7], shape=[2, 2]) indices = constant_op.constant([0, 2]) dense_shape = constant_op.constant([3, 2]) x = ops.IndexedSlices(values, indices, dense_shape) tensor = ops.convert_to_tensor(x, name="tensor") self.assertAllEqual(tensor.eval(), [[2, 3], [0, 0], [5, 7]])
def testNestedColocateWith(self): a = constant_op.constant([2.0], name="a") with ops.colocate_with(a.op): b = constant_op.constant(3.0) with ops.colocate_with(b.op): c = constant_op.constant(4.0) self.assertEqual([b"loc:@a"], b.op.colocation_groups()) self.assertEqual([b"loc:@a"], c.op.colocation_groups())
def testColocateGradients(self): with ops.Graph().as_default() as g: w = constant(1.0, shape=[1, 1]) x = constant(1.0, shape=[1, 2]) with g.device("/gpu:0"): wx = math_ops.matmul(w, x) gw = gradients.gradients(wx, [w], colocate_gradients_with_ops=True)[0] self.assertEquals("/gpu:0", gw.device)
def testUseExistingGraph(self): with ops.Graph().as_default() as g, ops.device("/cpu:0"): a = constant_op.constant(6.0, shape=[1, 1]) b = constant_op.constant(7.0, shape=[1, 1]) c = math_ops.matmul(a, b, name="matmul") with session.Session(graph=g): result = c.eval() self.assertAllEqual(result, [[42.0]])
def testConstant(self): np_val = np.random.rand(3, 4, 7).astype(np.float32) tf_val = constant_op.constant(np_val) self.assertAllClose(np_val, tensor_util.ConstantValue(tf_val)) np_val = np.random.rand(3, 0, 7).astype(np.float32) tf_val = constant_op.constant(np_val) self.assertAllClose(np_val, tensor_util.ConstantValue(tf_val))
def _SparseTensor_2x6(self): ind = np.array([[0, 0], [1, 0], [1, 3], [1, 4]]) val = np.array([0, 10, 13, 14]) shape = np.array([2, 6]) return ops.SparseTensor( constant_op.constant(ind, dtypes.int64), constant_op.constant(val, dtypes.int32), constant_op.constant(shape, dtypes.int64))
def _testTypesForSparseFtrl(self, x, y, z, lr, grad, indices, l1=0.0, l2=0.0, lr_power=-0.5): self.setUp() with self.test_session(use_gpu=False): var = variables.Variable(x) accum = variables.Variable(y) linear = variables.Variable(z) variables.initialize_all_variables().run() self.assertAllCloseAccordingToType(x, var.eval()) sparse_apply_ftrl = training_ops.sparse_apply_ftrl( var, accum, linear, grad, constant_op.constant(indices, self._toType(indices.dtype)), lr, l1, l2, lr_power=lr_power) out = sparse_apply_ftrl.eval() self.assertShapeEqual(out, sparse_apply_ftrl) for (i, index) in enumerate(indices): self.assertAllCloseAccordingToType( x[index] - lr * grad[i] * (y[index] + grad[i] * grad[i]) ** ( lr_power), var.eval()[index]) self.assertAllCloseAccordingToType(y[index] + grad[i] * grad[i], accum.eval()[index])
def testManyPartialRun(self): with session.Session() as sess: steps = 200 inputs = [] outputs = [] a = constant_op.constant(2.0, dtypes.float32) for i in xrange(steps): inputs.append(array_ops.placeholder(dtypes.float32, shape=[])) a = math_ops.mul(a, inputs[i]) outputs.append(a) h = sess.partial_run_setup(outputs, inputs) for i in xrange(steps): res = sess.partial_run(h, outputs[i], feed_dict={inputs[i]: 1.0}) self.assertEqual(2.0, res) feed_dict = {} for i in xrange(steps): feed_dict[inputs[i]] = 1.0 res = sess.run(outputs, feed_dict) self.assertEqual(steps, len(res)) self.assertEqual(2.0, res[-1])
def _AddShardedSaveOps(self, filename_tensor, per_device): """Add ops to save the params per shard. Args: filename_tensor: String Tensor. per_device: A list of (device, BaseSaverBuilder.VarToSave) pairs, as returned by _GroupByDevices(). Returns: An op to save the variables. """ num_shards = len(per_device) sharded_saves = [] num_shards_tensor = constant_op.constant(num_shards, name="num_shards") for shard, (device, vars_to_save) in enumerate(per_device): with ops.device(device): sharded_filename = self.sharded_filename( filename_tensor, shard, num_shards_tensor) sharded_saves.append( self._AddSaveOps(sharded_filename, vars_to_save)) # Return the sharded name for the save path. with ops.control_dependencies([x.op for x in sharded_saves]): return gen_io_ops._sharded_filespec(filename_tensor, num_shards_tensor)
def testBatch(self): # Build an arbitrary RGB image np.random.seed(7) batch_size = 5 shape = (batch_size, 2, 7, 3) inp = np.random.rand(*shape).astype(np.float32) # Convert to HSV and back, as a batch and individually with self.test_session() as sess: batch0 = constant_op.constant(inp) batch1 = image_ops.rgb_to_hsv(batch0) batch2 = image_ops.hsv_to_rgb(batch1) split0 = array_ops.unpack(batch0) split1 = list(map(image_ops.rgb_to_hsv, split0)) split2 = list(map(image_ops.hsv_to_rgb, split1)) join1 = array_ops.pack(split1) join2 = array_ops.pack(split2) batch1, batch2, join1, join2 = sess.run( [batch1, batch2, join1, join2]) # Verify that processing batch elements together is the same as separate self.assertAllClose(batch1, join1) self.assertAllClose(batch2, join2) self.assertAllClose(batch2, inp)
def clip_by_norm(t, clip_norm, name=None): """Clips tensor values to a maximum L2-norm. Given a tensor `t`, and a maximum clip value `clip_norm`, this operation normalizes `t` so that its L2-norm is less than or equal to `clip_norm`. Specifically, if the L2-norm is already less than or equal to `clip_norm`, then `t` is not modified. If the L2-norm is greater than `clip_norm`, then this operation returns a tensor of the same type and shape as `t` with its values set to: `t * clip_norm / l2norm(t)` In this case, the L2-norm of the output tensor is `clip_norm`. This operation is typically used to clip gradients before applying them with an optimizer. Args: t: A `Tensor`. clip_norm: A 0-D (scalar) `Tensor` > 0. A maximum clipping value. name: A name for the operation (optional). Returns: A clipped `Tensor`. """ with ops.op_scope([t, clip_norm], name, "clip_by_norm") as name: t = ops.convert_to_tensor(t, name="t") # Calculate L2-norm, clip elements by ratio of clip_norm to L2-norm l2norm_inv = math_ops.rsqrt( math_ops.reduce_sum(t * t, math_ops.range(array_ops.rank(t)))) tclip = array_ops.identity(t * clip_norm * math_ops.minimum( l2norm_inv, constant_op.constant(1.0 / clip_norm)), name=name) return tclip
def testExplicitDevice(self): with ops.Graph().as_default() as g: const_0 = constant_op.constant(5.0) with g.device("/device:GPU:0"): const_1 = constant_op.constant(5.0) with g.device("/device:GPU:1"): const_2 = constant_op.constant(5.0) with g.device("/device:CPU:0"): const_3 = constant_op.constant(5.0) with g.device("/device:CPU:1"): const_4 = constant_op.constant(5.0) with g.device("/job:ps"): const_5 = constant_op.constant(5.0) self.assertDeviceEqual(const_0.device, None) self.assertDeviceEqual(const_1.device, "/device:GPU:0") self.assertDeviceEqual(const_2.device, "/device:GPU:1") self.assertDeviceEqual(const_3.device, "/device:CPU:0") self.assertDeviceEqual(const_4.device, "/device:CPU:1") self.assertDeviceEqual(const_5.device, "/job:ps")
def testBatchNormGradImpl(self): x_shape = [7, 5, 4, 6] param_shape = [6] np.random.seed(1) # Make it reproducible. x_val = np.random.random_sample(x_shape).astype(np.float32) m_val = np.random.random_sample(param_shape).astype(np.float32) v_val = np.random.random_sample(param_shape).astype(np.float32) beta_val = np.random.random_sample(param_shape).astype(np.float32) gamma_val = np.random.random_sample(param_shape).astype(np.float32) backprop_val = np.random.random_sample(x_shape).astype(np.float32) for use_gpu in [False, True]: with self.test_session(use_gpu=use_gpu) as sess: x = constant_op.constant(x_val, name="x") m = constant_op.constant(m_val, name="m") v = constant_op.constant(v_val, name="v") beta = constant_op.constant(beta_val, name="beta") gamma = constant_op.constant(gamma_val, name="gamma") backprop = constant_op.constant(backprop_val, name="backprop") epsilon = 0.001 for scale_after_normalization in [True, False]: dx, dm, dv, db, dg = ( gen_nn_ops._batch_norm_with_global_normalization_grad( x, m, v, gamma, backprop, epsilon, scale_after_normalization)) on = self._opsBatchNorm(x, m, v, beta, gamma, epsilon, scale_after_normalization) odx, odm, odv, odb, odg = gradients.gradients( [on], [x, m, v, beta, gamma], [backprop]) if scale_after_normalization: all_grads = sess.run( [dx, dm, dv, db, dg, odx, odm, odv, odb, odg]) to_check = ["dx", "dm", "dv", "db", "dg"] else: all_grads = sess.run( [dx, dm, dv, db, odx, odm, odv, odb]) to_check = ["dx", "dm", "dv", "db"] for i, n in enumerate(to_check): print(n) self.assertAllClose(all_grads[i + len(to_check)], all_grads[i], atol=0.000001)
def testDefaultDevice(self): with ops.Graph().as_default() as g, g.device( test_device_func_pin_variable_to_cpu): with g.device("/job:ps"): const_0 = constant_op.constant(5.0) with g.device("/device:GPU:0"): const_1 = constant_op.constant(5.0) with g.device("/device:GPU:1"): const_2 = constant_op.constant(5.0) with g.device("/device:CPU:0"): const_3 = constant_op.constant(5.0) with g.device("/device:CPU:1"): const_4 = constant_op.constant(5.0) with g.device("/replica:0"): const_5 = constant_op.constant(5.0) self.assertDeviceEqual(const_0.device, "/job:ps") self.assertDeviceEqual(const_1.device, "/device:GPU:0") self.assertDeviceEqual(const_2.device, "/device:GPU:1") self.assertDeviceEqual(const_3.device, "/device:CPU:0") self.assertDeviceEqual(const_4.device, "/device:CPU:1") self.assertDeviceEqual(const_5.device, "/replica:0")
def _setup_training(self): """Sets up graph, model and trainer.""" # Create config if not given. if self._config is None: self._config = RunConfig(verbose=self.verbose) # Create new graph. self._graph = ops.Graph() self._graph.add_to_collection("IS_TRAINING", True) with self._graph.as_default(): random_seed.set_random_seed(self._config.tf_random_seed) self._global_step = variables.Variable(0, name="global_step", trainable=False) # Setting up inputs and outputs. self._inp, self._out = self._data_feeder.input_builder() # If class weights are provided, add them to the graph. # Different loss functions can use this tensor by name. if self.class_weight: self._class_weight_node = constant_op.constant( self.class_weight, name='class_weight') # Add histograms for X and y if they are floats. if self._data_feeder.input_dtype in (np.float32, np.float64): logging_ops.histogram_summary("X", self._inp) if self._data_feeder.output_dtype in (np.float32, np.float64): logging_ops.histogram_summary("y", self._out) # Create model's graph. self._model_predictions, self._model_loss = self.model_fn( self._inp, self._out) # Set up a single operator to merge all the summaries self._summaries = logging_ops.merge_all_summaries() # Create trainer and augment graph with gradients and optimizer. # Additionally creates initialization ops. learning_rate = self.learning_rate optimizer = self.optimizer if callable(learning_rate): learning_rate = learning_rate(self._global_step) if callable(optimizer): optimizer = optimizer(learning_rate) self._train = optimizers.optimize_loss( self._model_loss, self._global_step, learning_rate=learning_rate, optimizer=optimizer, clip_gradients=self.clip_gradients) # Update ops during training, e.g. batch_norm_ops self._train = control_flow_ops.group( self._train, *ops.get_collection('update_ops')) # Get all initializers for all trainable variables. self._initializers = variables.initialize_all_variables() # Create model's saver capturing all the nodes created up until now. self._saver = train.Saver( max_to_keep=self._config.keep_checkpoint_max, keep_checkpoint_every_n_hours=self._config. keep_checkpoint_every_n_hours) # Enable monitor to create validation data dict with appropriate tf placeholders self._monitor.create_val_feed_dict(self._inp, self._out) # Create session to run model with. self._session = session.Session(self._config.tf_master, config=self._config.tf_config) # Run parameter initializers. self._session.run(self._initializers)
def sufficient_statistics(x, axes, shift=True, keep_dims=False, name=None): """Calculate the sufficient statistics for the mean and variance of `x`. These sufficient statistics are computed using the one pass algorithm on an input that's optionally shifted using the value of the 1st element in `x`. See: https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Computing_shifted_data Args: x: A `Tensor`. axes: Array of ints. Axes along which to compute mean and variance. shift: If true, shift the data to provide more numerically stable results. keep_dims: produce statistics with the same dimensionality as the input. name: Name used to scope the operations that compute the sufficient stats. Returns: Four `Tensor` objects of the same type as `x`: * the count (number of elements to average over). * the (possibly shifted) sum of the elements in the array. * the (possibly shifted) sum of squares of the elements in the array. * the shift by which the mean must be corrected or None if `shift` is False. """ with ops.op_scope([x, axes], name, "sufficient_statistics"): x = ops.convert_to_tensor(x, name="x") x_shape = x.get_shape() if x_shape.is_fully_defined(): counts = 1 m_shape = [] for d in xrange(x_shape.ndims): dim = x_shape[d].value if d in set(axes): counts *= dim dim = 1 m_shape.append(dim) counts = constant_op.constant(counts, dtype=x.dtype) else: # shape needs to be inferred at runtime. x_shape = array_ops.shape(x) select_axes = sparse_ops.sparse_to_dense(axes, array_ops.shape(x_shape), True, False) m_shape = math_ops.select(select_axes, array_ops.ones_like(x_shape), x_shape) counts = math_ops.cast(math_ops.reduce_prod(x_shape / m_shape), x.dtype, name="count") if shift: shift_value = array_ops.slice(x, array_ops.zeros_like(m_shape), m_shape) m_ss = math_ops.sub(x, shift_value) v_ss = math_ops.squared_difference(x, shift_value) if keep_dims: shift_value = array_ops.identity(shift_value, name="shift") else: shift_value = array_ops.squeeze(shift_value, squeeze_dims=axes, name="shift") else: # not shift. m_ss = x v_ss = math_ops.square(x) shift_value = None m_ss = math_ops.reduce_sum(m_ss, axes, keep_dims=keep_dims, name="mean_ss") v_ss = math_ops.reduce_sum(v_ss, axes, keep_dims=keep_dims, name="var_ss") return counts, m_ss, v_ss, shift_value
def _create_slots(self, var_list): for v in var_list: with ops.device(v.device): val = constant_op.constant(self._initial_accumulator_value, shape=v.get_shape()) self._get_or_make_slot(v, val, "accumulator", self._name)
def _testBrightness(self, x_np, y_np, delta): with self.test_session(): x = constant_op.constant(x_np, shape=x_np.shape) y = image_ops.adjust_brightness(x, delta) y_tf = y.eval() self.assertAllClose(y_tf, y_np, 1e-6)
def _ErfGrad(op, grad): """Returns grad * 2/sqrt(pi) * exp(-x**2).""" x = op.inputs[0] two_over_root_pi = constant_op.constant(2 / np.sqrt(np.pi), dtype=grad.dtype) with ops.control_dependencies([grad.op]): return grad * two_over_root_pi * math_ops.exp(-math_ops.square(x))
def _ImagGrad(_, grad): """Returns 'grad' as the imaginary part and set the real part 0.""" zero = constant_op.constant(0, dtype=grad.dtype) return math_ops.complex(zero, grad)
def scan(fn, elems, initializer=None, parallel_iterations=10, back_prop=True, swap_memory=False, name=None, pass_index=False): """scan on the list of tensors unpacked from `elems` on dimension 0. This scan operator repeatedly applies the callable `fn` to a sequence of elements from first to last. The elements are made of the tensors unpacked from `elems` on dimension 0. The callable fn takes two tensors as arguments. The first argument is the accumulated value computed from the preceding invocation of fn. If `initializer` is None, `elems` must contain at least one element, and its first element is used as the initializer. Suppose that `elems` is unpacked into `values`, a list of tensors. The shape of the result tensor is `[len(values)] + fn(initializer, values[0]).shape`. Args: fn: The callable to be performed. elems: A tensor to be unpacked on dimension 0. initializer: (optional) The initial value for the accumulator. parallel_iterations: (optional) The number of iterations allowed to run in parallel. back_prop: (optional) True enables back propagation. swap_memory: (optional) True enables GPU-CPU memory swapping. name: (optional) Name prefix for the returned tensors. pass_index: (optional) True calls fn(accum, elem, index) instead of fn(accum, elem). Default is False. Returns: A tensor that packs the results of applying `fn` to the list of tensors unpacked from `elems`, from first to last. Raises: TypeError: if `fn` is not callable. Example: ```python elems = [1, 2, 3, 4, 5, 6] sum = scan(lambda a, x: a + x, elems) # sum == [1, 3, 6, 10, 15, 21] ``` """ if not callable(fn): raise TypeError("fn must be callable.") with vs.variable_op_scope([elems], name, "scan") as varscope: # Any get_variable calls fn will cache the first call locally # and not issue repeated network I/O requests for each iteration. if varscope.caching_device is None: varscope.set_caching_device(lambda op: op.device) # Convert elems to tensor array. n = array_ops.shape(elems)[0] elems_ta = tensor_array_ops.TensorArray(dtype=elems.dtype, size=n, dynamic_size=False, infer_shape=True) elems_ta = elems_ta.unpack(elems) if initializer is None: a = elems_ta.read(0) i = constant_op.constant(1) else: a = ops.convert_to_tensor(initializer) i = constant_op.constant(0) # Create a tensor array to store the intermediate values. acc_ta = tensor_array_ops.TensorArray(dtype=a.dtype, size=n, dynamic_size=False, infer_shape=True) if initializer is None: acc_ta = acc_ta.write(0, a) def compute(i, a, ta): item = elems_ta.read(i) if pass_index: a = fn(a, item, i) else: a = fn(a, item) ta = ta.write(i, a) return [i + 1, a, ta] _, _, r_a = control_flow_ops.while_loop( lambda i, a, ta: i < n, compute, [i, a, acc_ta], parallel_iterations=parallel_iterations, back_prop=back_prop, swap_memory=swap_memory) result = r_a.pack() elems_dims = ops.convert_to_tensor(elems).get_shape().dims result_dims = result.get_shape().dims if elems_dims and result_dims: result.set_shape([elems_dims[0]] + result_dims[1:]) return result
def clip_by_global_norm(t_list, clip_norm, use_norm=None, name=None): """Clips values of multiple tensors by the ratio of the sum of their norms. Given a tuple or list of tensors `t_list`, and a clipping ratio `clip_norm`, this operation returns a list of clipped tensors `list_clipped` and the global norm (`global_norm`) of all tensors in `t_list`. Optionally, if you've already computed the global norm for `t_list`, you can specify the global norm with `use_norm`. To perform the clipping, the values `t_list[i]` are set to: t_list[i] * clip_norm / max(global_norm, clip_norm) where: global_norm = sqrt(sum([l2norm(t)**2 for t in t_list])) If `clip_norm > global_norm` then the entries in `t_list` remain as they are, otherwise they're all shrunk by the global ratio. Any of the entries of `t_list` that are of type `None` are ignored. This is the correct way to perform gradient clipping (for example, see R. Pascanu, T. Mikolov, and Y. Bengio, "On the difficulty of training Recurrent Neural Networks". http://arxiv.org/abs/1211.5063) However, it is slower than `clip_by_norm()` because all the parameters must be ready before the clipping operation can be performed. Args: t_list: A tuple or list of mixed `Tensors`, `IndexedSlices`, or None. clip_norm: A 0-D (scalar) `Tensor` > 0. The clipping ratio. use_norm: A 0-D (scalar) `Tensor` of type `float` (optional). The global norm to use. If not provided, `global_norm()` is used to compute the norm. name: A name for the operation (optional). Returns: list_clipped: A list of `Tensors` of the same type as `list_t`. global_norm: A 0-D (scalar) `Tensor` representing the global norm. Raises: TypeError: If `t_list` is not a sequence. """ if (not isinstance(t_list, collections.Sequence) or isinstance(t_list, six.string_types)): raise TypeError("t_list should be a sequence") t_list = list(t_list) if use_norm is None: use_norm = global_norm(t_list, name) with ops.op_scope(t_list + [clip_norm], name, "clip_by_global_norm") as name: # Calculate L2-norm, clip elements by ratio of clip_norm to L2-norm scale = clip_norm * math_ops.minimum( 1.0 / use_norm, constant_op.constant(1.0 / clip_norm, dtype=use_norm.dtype)) values = [ ops.convert_to_tensor( t.values if isinstance(t, ops.IndexedSlices) else t, name="t_%d" % i) if t is not None else t for i, t in enumerate(t_list) ] values_clipped = [ array_ops.identity(v * scale, name="%s_%d" % (name, i)) if v is not None else None for i, v in enumerate(values) ] list_clipped = [ ops.IndexedSlices(c_v, t.indices) if isinstance( t, ops.IndexedSlices) else c_v for (c_v, t) in zip(values_clipped, t_list) ] return list_clipped, use_norm
def testErrorsReported(self): with session.Session() as s: constant_op.constant(10.0, name='W1') with self.assertRaises(ValueError): s.run('foo:0')
def testStopGradient(self): with ops.Graph().as_default(): inp = constant(1.0, shape=[100, 32], name="in") out = array_ops.stop_gradient(inp) igrad = gradients.gradients(out, inp)[0] assert igrad is None
def testRank(self): np_val = np.array([3]) tf_val = array_ops.rank(constant_op.constant(0.0, shape=[1, 2, 3])) self.assertAllEqual(np_val, tensor_util.ConstantValue(tf_val))
def log_pdf(self, x, name=None): """Log pdf of observations `x` given these Multivariate Normals. Args: x: tensor of dtype `dtype`, must be broadcastable with `mu`. name: The name to give this op. Returns: log_pdf: tensor of dtype `dtype`, the log-PDFs of `x`. """ with ops.op_scope([self._mu, self._sigma_chol, x], name, "MultivariateNormalLogPdf"): x = ops.convert_to_tensor(x) contrib_tensor_util.assert_same_float_dtype((self._mu, x)) x_centered = x - self.mu x_rank = array_ops.rank(x_centered) sigma_rank = array_ops.rank(self._sigma_chol) x_rank_vec = array_ops.pack([x_rank]) sigma_rank_vec = array_ops.pack([sigma_rank]) x_shape = array_ops.shape(x_centered) # sigma_chol is shaped [D, E, F, ..., k, k] # x_centered shape is one of: # [D, E, F, ..., k], or [F, ..., k], or # [A, B, C, D, E, F, ..., k] # and we need to convert x_centered to shape: # [D, E, F, ..., k, A*B*C] (or 1 if A, B, C don't exist) # then transpose and reshape x_whitened back to one of the shapes: # [D, E, F, ..., k], or [1, 1, F, ..., k], or # [A, B, C, D, E, F, ..., k] # This helper handles the case where rank(x_centered) < rank(sigma) def _broadcast_x_not_higher_rank_than_sigma(): return array_ops.reshape( x_centered, array_ops.concat( # Reshape to ones(deficient x rank) + x_shape + [1] 0, (array_ops.ones(array_ops.pack( [sigma_rank - x_rank - 1]), dtype=x_rank.dtype), x_shape, [1]))) # These helpers handle the case where rank(x_centered) >= rank(sigma) def _broadcast_x_higher_rank_than_sigma(): x_shape_left = array_ops.slice(x_shape, [0], sigma_rank_vec - 1) x_shape_right = array_ops.slice(x_shape, sigma_rank_vec - 1, x_rank_vec - 1) x_shape_perm = array_ops.concat( 0, (math_ops.range(sigma_rank - 1, x_rank), math_ops.range(0, sigma_rank - 1))) return array_ops.reshape( # Convert to [D, E, F, ..., k, B, C] array_ops.transpose(x_centered, perm=x_shape_perm), # Reshape to [D, E, F, ..., k, B*C] array_ops.concat( 0, (x_shape_right, array_ops.pack( [math_ops.reduce_prod(x_shape_left, 0)])))) def _unbroadcast_x_higher_rank_than_sigma(): x_shape_left = array_ops.slice(x_shape, [0], sigma_rank_vec - 1) x_shape_right = array_ops.slice(x_shape, sigma_rank_vec - 1, x_rank_vec - 1) x_shape_perm = array_ops.concat( 0, (math_ops.range(sigma_rank - 1, x_rank), math_ops.range(0, sigma_rank - 1))) return array_ops.transpose( # [D, E, F, ..., k, B, C] => [B, C, D, E, F, ..., k] array_ops.reshape( # convert to [D, E, F, ..., k, B, C] x_whitened_broadcast, array_ops.concat(0, (x_shape_right, x_shape_left))), perm=x_shape_perm) # Step 1: reshape x_centered x_centered_broadcast = control_flow_ops.cond( # x_centered == [D, E, F, ..., k] => [D, E, F, ..., k, 1] # or == [F, ..., k] => [1, 1, F, ..., k, 1] x_rank <= sigma_rank - 1, _broadcast_x_not_higher_rank_than_sigma, # x_centered == [B, C, D, E, F, ..., k] => [D, E, F, ..., k, B*C] _broadcast_x_higher_rank_than_sigma) x_whitened_broadcast = linalg_ops.batch_matrix_triangular_solve( self._sigma_chol, x_centered_broadcast) # Reshape x_whitened_broadcast back to x_whitened x_whitened = control_flow_ops.cond( x_rank <= sigma_rank - 1, lambda: array_ops.reshape(x_whitened_broadcast, x_shape), _unbroadcast_x_higher_rank_than_sigma) x_whitened = array_ops.expand_dims(x_whitened, -1) # Reshape x_whitened to contain row vectors # Returns a batchwise scalar x_whitened_norm = math_ops.batch_matmul(x_whitened, x_whitened, adj_x=True) x_whitened_norm = control_flow_ops.cond( x_rank <= sigma_rank - 1, lambda: array_ops.squeeze(x_whitened_norm, [-2, -1]), lambda: array_ops.squeeze(x_whitened_norm, [-1])) log_two_pi = constant_op.constant(math.log(2 * math.pi), dtype=self.dtype) k = math_ops.cast(self._k, self.dtype) log_pdf_value = (-math_ops.log(self._sigma_det) - k * log_two_pi - x_whitened_norm) / 2 final_shaped_value = control_flow_ops.cond( x_rank <= sigma_rank - 1, lambda: log_pdf_value, lambda: array_ops.squeeze(log_pdf_value, [-1])) output_static_shape = x_centered.get_shape()[:-1] final_shaped_value.set_shape(output_static_shape) return final_shaped_value
def event_shape(self, name="event_shape"): with ops.name_scope(self.name): return constant_op.constant(1, name=name)
def embedding_lookup(params, ids, partition_strategy="mod", name=None, validate_indices=True): """Looks up `ids` in a list of embedding tensors. This function is used to perform parallel lookups on the list of tensors in `params`. It is a generalization of [`tf.gather()`](../../api_docs/python/array_ops.md#gather), where `params` is interpreted as a partition of a larger embedding tensor. If `len(params) > 1`, each element `id` of `ids` is partitioned between the elements of `params` according to the `partition_strategy`. In all strategies, if the id space does not evenly divide the number of partitions, each of the first `(max_id + 1) % len(params)` partitions will be assigned one more id. If `partition_strategy` is `"mod"`, we assign each id to partition `p = id % len(params)`. For instance, 13 ids are split across 5 partitions as: `[[0, 5, 10], [1, 6, 11], [2, 7, 12], [3, 8], [4, 9]]` If `partition_strategy` is `"div"`, we assign ids to partitions in a contiguous manner. In this case, 13 ids are split across 5 partitions as: `[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10], [11, 12]]` The results of the lookup are concatenated into a dense tensor. The returned tensor has shape `shape(ids) + shape(params)[1:]`. Args: params: A list of tensors with the same type and which can be concatenated along dimension 0. Each `Tensor` must be appropriately sized for the given `partition_strategy`. ids: A `Tensor` with type `int32` or `int64` containing the ids to be looked up in `params`. partition_strategy: A string specifying the partitioning strategy, relevant if `len(params) > 1`. Currently `"div"` and `"mod"` are supported. Default is `"mod"`. name: A name for the operation (optional). validate_indices: Whether or not to validate gather indices. Returns: A `Tensor` with the same type as the tensors in `params`. Raises: ValueError: If `params` is empty. """ if not isinstance(params, list): params = [params] with ops.op_scope(params + [ids], name, "embedding_lookup") as name: if not params: raise ValueError("Need at least one param") np = len(params) # Number of partitions params = ops.convert_n_to_tensor_or_indexed_slices(params, name="params") if np == 1: with ops.device(params[0].device): return array_ops.gather(params[0], ids, name=name, validate_indices=validate_indices) else: ids = ops.convert_to_tensor(ids, name="ids") flat_ids = array_ops.reshape(ids, [-1]) original_indices = math_ops.range(array_ops.size(flat_ids)) # Create p_assignments and set new_ids depending on the strategy. if partition_strategy == "mod": p_assignments = flat_ids % np new_ids = flat_ids // np elif partition_strategy == "div": # Compute num_total_ids as the sum of dim-0 of params, then assign to # partitions based on a constant number of ids per partition. Optimize # if we already know the full shape statically. dim_0_size = params[0].get_shape()[0] for p in xrange(1, np): dim_0_size += params[p].get_shape()[0] if dim_0_size.value: num_total_ids = constant_op.constant( dim_0_size.value, flat_ids.dtype) else: dim_0_sizes = [] for p in xrange(np): with ops.device(params[p].device): dim_0_sizes.append(array_ops.shape(params[p])[0]) num_total_ids = math_ops.reduce_sum( math_ops.cast(array_ops.pack(dim_0_sizes), flat_ids.dtype)) ids_per_partition = num_total_ids // np extras = num_total_ids % np p_assignments = math_ops.maximum( flat_ids // (ids_per_partition + 1), (flat_ids - extras) // ids_per_partition) # Emulate a conditional using a boolean indicator tensor is_in_first_extras_partitions = math_ops.cast( p_assignments < extras, flat_ids.dtype) new_ids = (is_in_first_extras_partitions * (flat_ids % (ids_per_partition + 1)) + (1 - is_in_first_extras_partitions) * ((flat_ids - extras) % ids_per_partition)) else: raise ValueError("Unrecognized partition strategy: " + partition_strategy) # Cast partition assignments to int32 for use in dynamic_partition. # There really should not be more than 2^32 partitions. p_assignments = math_ops.cast(p_assignments, dtypes.int32) # Partition list of ids based on assignments into np separate lists gather_ids = data_flow_ops.dynamic_partition( new_ids, p_assignments, np) # Similarly, partition the original indices. pindices = data_flow_ops.dynamic_partition(original_indices, p_assignments, np) # Do np separate lookups, finding embeddings for plist[p] in params[p] partitioned_result = [] for p in xrange(np): with ops.device(params[p].device): partitioned_result.append( array_ops.gather(params[p], gather_ids[p], validate_indices=validate_indices)) # Stitch these back together ret = data_flow_ops.dynamic_stitch(pindices, partitioned_result, name=name) # Reshape to reverse the flattening of ids. # It's important that we compute params[0].shape on the right device # to avoid data motion. with ops.device(params[0].device): params_shape = array_ops.shape(params[0]) ret = array_ops.reshape( ret, array_ops.concat(0, [ array_ops.shape(ids), array_ops.slice(params_shape, [1], [-1]) ])) # output shape = ids.shape + params[*].shape[1:] # Normally the reshape is sufficient, but setting shape explicitly # teaches shape inference that params[1:].get_shape() matters. element_shape = params[0].get_shape()[1:] for p in params[1:]: element_shape = element_shape.merge_with(p.get_shape()[1:]) ret.set_shape(ids.get_shape().concatenate(element_shape)) return ret
def parse_example(serialized, names=None, sparse_keys=None, sparse_types=None, dense_keys=None, dense_types=None, dense_defaults=None, dense_shapes=None, name="ParseExample"): """Parses `Example` protos. Parses a number of serialized [`Example`] (https://tensorflow.googlesource.com/tensorflow/+/master/tensorflow/core/example/example.proto) protos given in `serialized`. `names` may contain descriptive names for the corresponding serialized protos. These may be useful for debugging purposes, but they have no effect on the output. If not `None`, `names` must be the same length as `serialized`. This op parses serialized examples into a dictionary mapping keys to `Tensor` and `SparseTensor` objects respectively, depending on whether the keys appear in `sparse_keys` or `dense_keys`. The key `dense_keys[j]` is mapped to a `Tensor` of type `dense_types[j]` and of shape `(serialized.size(),) + dense_shapes[j]`. `dense_defaults` provides defaults for values referenced using `dense_keys`. If a key is not present in this dictionary, the corresponding dense `Feature` is required in all elements of `serialized`. `dense_shapes[j]` provides the shape of each `Feature` entry referenced by `dense_keys[j]`. The number of elements in the `Feature` corresponding to `dense_key[j]` must always have `np.prod(dense_shapes[j])` entries. The returned `Tensor` for `dense_key[j]` has shape `[N] + dense_shape[j]`, where `N` is the number of `Example`s in `serialized`. The key `sparse_keys[j]` is mapped to a `SparseTensor` of type `sparse_types[j]`. The `SparseTensor` represents a ragged matrix. Its indices are `[batch, index]` where `batch` is the batch entry the value is from, and `index` is the value's index in the list of values associated with that feature and example. Examples: For example, if one expects a `tf.float32` sparse feature `ft` and three serialized `Example`s are provided: ``` serialized = [ features: { feature: [ key: { "ft" value: float_list: { value: [1.0, 2.0] } } ] }, features: { feature: [] }, features: { feature: [ key: { "ft" value: float_list: { value: [3.0] } } ] } ] ``` then the output will look like: ``` {"ft": SparseTensor(indices=[[0, 0], [0, 1], [2, 0]], values=[1.0, 2.0, 3.0], shape=(3, 2)) } ``` Given two `Example` input protos in `serialized`: ``` [ features: { feature: { key: "kw" value: { bytes_list: { value: [ "knit", "big" ] } } } feature: { key: "gps" value: { float_list: { value: [] } } } }, features: { feature: { key: "kw" value: { bytes_list: { value: [ "emmy" ] } } } feature: { key: "dank" value: { int64_list: { value: [ 42 ] } } } feature: { key: "gps" value: { } } } ] ``` And arguments ``` names: ["input0", "input1"], sparse_keys: ["kw", "dank", "gps"] sparse_types: [DT_STRING, DT_INT64, DT_FLOAT] ``` Then the output is a dictionary: ```python { "kw": SparseTensor( indices=[[0, 0], [0, 1], [1, 0]], values=["knit", "big", "emmy"] shape=[2, 2]), "dank": SparseTensor( indices=[[1, 0]], values=[42], shape=[2, 1]), "gps": SparseTensor( indices=[], values=[], shape=[2, 0]), } ``` For dense results in two serialized `Example`s: ``` [ features: { feature: { key: "age" value: { int64_list: { value: [ 0 ] } } } feature: { key: "gender" value: { bytes_list: { value: [ "f" ] } } } }, features: { feature: { key: "age" value: { int64_list: { value: [] } } } feature: { key: "gender" value: { bytes_list: { value: [ "f" ] } } } } ] ``` We can use arguments: ``` names: ["input0", "input1"], dense_keys: np.array(["age", "gender"]), dense_types: [tf.int64, tf.string], dense_defaults: { "age": -1 # "age" defaults to -1 if missing # "gender" has no specified default so it's required } dense_shapes: [(1,), (1,)], # age, gender, label, weight ``` And the expected output is: ```python { "age": [[0], [-1]], "gender": [["f"], ["f"]], } ``` Args: serialized: A vector (1-D Tensor) of strings, a batch of binary serialized `Example` protos. names: A vector (1-D Tensor) of strings (optional), the names of the serialized protos. sparse_keys: A list of string keys in the examples' features. The results for these keys will be returned as `SparseTensor` objects. sparse_types: A list of `DTypes` of the same length as `sparse_keys`. Only `tf.float32` (`FloatList`), `tf.int64` (`Int64List`), and `tf.string` (`BytesList`) are supported. dense_keys: A list of string keys in the examples' features. The results for these keys will be returned as `Tensor`s dense_types: A list of DTypes of the same length as `dense_keys`. Only `tf.float32` (`FloatList`), `tf.int64` (`Int64List`), and `tf.string` (`BytesList`) are supported. dense_defaults: A dict mapping string keys to `Tensor`s. The keys of the dict must match the dense_keys of the feature. dense_shapes: A list of tuples with the same length as `dense_keys`. The shape of the data for each dense feature referenced by `dense_keys`. name: A name for this operation (optional). Returns: A `dict` mapping keys to `Tensor`s and `SparseTensor`s. Raises: ValueError: If sparse and dense key sets intersect, or input lengths do not match up. """ with ops.op_scope([serialized, names], name, "parse_example"): names = [] if names is None else names dense_defaults = {} if dense_defaults is None else dense_defaults sparse_keys = [] if sparse_keys is None else sparse_keys sparse_types = [] if sparse_types is None else sparse_types dense_keys = [] if dense_keys is None else dense_keys dense_types = [] if dense_types is None else dense_types dense_shapes = [[]] * len( dense_keys) if dense_shapes is None else dense_shapes num_dense = len(dense_keys) num_sparse = len(sparse_keys) if len(dense_shapes) != num_dense: raise ValueError( "len(dense_shapes) != len(dense_keys): %d vs. %d" % (len(dense_shapes), num_dense)) if len(dense_types) != num_dense: raise ValueError("len(dense_types) != len(num_dense): %d vs. %d" % (len(dense_types), num_dense)) if len(sparse_types) != num_sparse: raise ValueError( "len(sparse_types) != len(sparse_keys): %d vs. %d" % (len(sparse_types), num_sparse)) if num_dense + num_sparse == 0: raise ValueError( "Must provide at least one sparse key or dense key") if not set(dense_keys).isdisjoint(set(sparse_keys)): raise ValueError( "Dense and sparse keys must not intersect; intersection: %s" % set(dense_keys).intersection(set(sparse_keys))) dense_defaults_vec = [] for i, key in enumerate(dense_keys): default_value = dense_defaults.get(key) if default_value is None: default_value = constant_op.constant([], dtype=dense_types[i]) elif not isinstance(default_value, ops.Tensor): key_name = "key_" + re.sub("[^A-Za-z0-9_.\\-/]", "_", key) default_value = ops.convert_to_tensor(default_value, dtype=dense_types[i], name=key_name) default_value = array_ops.reshape(default_value, dense_shapes[i]) dense_defaults_vec.append(default_value) dense_shapes = [ tensor_util.MakeTensorShapeProto(shape) if isinstance( shape, (list, tuple)) else shape for shape in dense_shapes ] outputs = gen_parsing_ops._parse_example( serialized=serialized, names=names, dense_defaults=dense_defaults_vec, sparse_keys=sparse_keys, sparse_types=sparse_types, dense_keys=dense_keys, dense_shapes=dense_shapes, name=name) (sparse_indices, sparse_values, sparse_shapes, dense_values) = outputs sparse_tensors = [ ops.SparseTensor(ix, val, shape) for (ix, val, shape) in zip(sparse_indices, sparse_values, sparse_shapes) ] return dict( zip(sparse_keys + dense_keys, sparse_tensors + dense_values))
def build(self, names_to_variables, reshape=False, sharded=False, max_to_keep=5, keep_checkpoint_every_n_hours=10000.0, name=None, restore_sequentially=False): """Adds save/restore nodes to the graph and creates a SaverDef proto. Args: names_to_variables: A dictionary mapping name to a Variable. Each name will be associated with the corresponding variable in the checkpoint. reshape: If True, allow restoring parameters from a checkpoint that where the parameters have a different shape. This is only needed when you try to restore from a Dist-Belief checkpoint, and only some times. sharded: If True, shard the checkpoints, one per device that has Parameters nodes. max_to_keep: maximum number of checkpoints to keep. As new checkpoints are created, old ones are deleted. If None or 0, no checkpoints are deleted. Presently the number is only roughly enforced. For example in case of restarts more than max_to_keep checkpoints may be kept. keep_checkpoint_every_n_hours: How often checkpoints should be kept. Defaults to 10,000 hours. name: string. Optional name to use as a prefix when adding operations. restore_sequentially: A Bool, which if true, causes restore of different variables to happen sequentially within each device. Returns: A SaverDef proto. Raises: TypeError: If 'names_to_variables' is not a dictionary mapping string keys to variable Tensors. ValueError: If any of the keys or values in 'names_to_variables' is not unique. """ vars_to_save = self._ValidateAndSliceInputs(names_to_variables) if max_to_keep is None: max_to_keep = 0 with ops.op_scope([vs.var for vs in vars_to_save], name, "save") as name: # Add the Constant string tensor for the filename. filename_tensor = constant_op.constant("model") # Add the save ops. if sharded: per_device = self._GroupByDevices(vars_to_save) save_tensor = self._AddShardedSaveOps(filename_tensor, per_device) restore_op = self._AddShardedRestoreOps( filename_tensor, per_device, restore_sequentially, reshape) else: save_tensor = self._AddSaveOps(filename_tensor, vars_to_save) restore_op = self._AddRestoreOps(filename_tensor, vars_to_save, restore_sequentially, reshape) assert restore_op.name.endswith("restore_all"), restore_op.name return saver_pb2.SaverDef( filename_tensor_name=filename_tensor.name, save_tensor_name=save_tensor.name, restore_op_name=restore_op.name, max_to_keep=max_to_keep, keep_checkpoint_every_n_hours=keep_checkpoint_every_n_hours, sharded=sharded)
def parse_example(serialized, names=None, sparse_keys=None, sparse_types=None, dense_keys=None, dense_types=None, dense_defaults=None, dense_shapes=None, name="ParseExample"): """Parse Example protos. Args: serialized: string vector, a batch of binary serialized Example protos. names: A string vector, the names of the serialized protos. "names" may contain, e.g., table key (descriptive) names for the corresponding serialized protos. These are purely useful for debugging purposes, and the presence of values here has no effect on the output. "names" may be an empty vector, if no names are available. If non-empty, this vector must be the same length as "serialized". sparse_keys: A string list of keys in the Examples' features. These keys are associated with sparse values. sparse_types: A list of DTypes. This list's length must match that of sparse_keys. Currently parse_example supports tf.float32 (FloatList), tf.int64 (Int64List), and tf.string (BytesList). dense_keys: A string list of keys in the Examples' features. These keys are associated with dense values. dense_types: A list of DTypes. This list's length must match that of dense_keys. Currently parse_example supports tf.float32 (FloatList), tf.int64 (Int64List), and tf.string (BytesList). dense_defaults: A dict of {key:Tensor} (some may be missing). The keys of the dict must match the dense_keys of the feature. If a key is not present in this dictionary, the corresponding dense Feature is required in all elements of serialized. dense_shapes: A list of tuples. Entries provide the shape of data in each dense Feature in features. The length of dense_shapes must be the same as the length of dense_keys. The number of elements in the Feature corresponding to dense_key[j] must always have np.prod(dense_shapes[j]) entries. If dense_shapes[j] == (D0, D1, ..., DN) then the the shape of output Tensor dense_values[j] will be (|serialized|, D0, D1, ..., DN): The dense outputs are just the inputs row-stacked by batch. name: (Optional) Name of Op in the graph. Returns: A dictionary mapping keys to Tensors and SparseTensors. The key dense_keys[j] is mapped to a tensor of type dense_types[j] and of shape (serialized.size(),) + dense_shapes[j] (i.e., the dense outputs are inputs, reshaped in row-major format and then row-stacked by batch). The key sparse_keys[j] is mapped to a SparseTensor of type sparse_types[j]. The SparseTensor represents a ragged matrix. Its indices are [batch, index] where "batch" is is the batch entry the value is from, and "index" is the value's index in the list of values associated with that feature and example. For example, if one expects a tf.float32 sparse feature "ft" and three serialized examples are provided: serialized = [ features: { feature: [ key: { "ft" value: float_list: { value: [1.0, 2.0] } } ] }, features: { feature: [] }, features: { feature: [ key: { "ft" value: float_list: { value: [3.0] } } ] } ] then the output will look like: {"ft": SparseTensor(indices=[[0, 0], [0, 1], [2, 0]], values=[1.0, 2.0, 3.0], shape=(3, 2)) } Raises: ValueError: If sparse and dense keys intersect, or input lengths do not match up for sparse_* (similarly for dense_*). TypeError: If an input is malformed. Example input, format, and output: Just Sparse Inputs ================================================ Given two brain.Example input protos: serialized: // serialized versions of the protos below [features: { feature: { key: "kw" value: { bytes_list: { value: [ "knit", "big" ] } } } feature: { key: "gps" value: { float_list: { value: [] } } } }, features: { feature: { key: "kw" value: { bytes_list: { value: [ "emmy" ] } } } feature: { key: "dank" value: { int64_list: { value: [ 42 ] } } } feature: { key: "gps" value: { } } }] names: ["input0", "input1"], sparse_keys: ["kw", "dank", "gps"] sparse_types: [DT_STRING, DT_INT64, DT_FLOAT] Then the expected output is a dictionary: { "kw": SparseTensor( indices=[[0, 0], [0, 1], [1, 0]], values=["knit", "big", "emmy"] shape=[2, 2]), "dank": SparseTensor( indices=[[1, 0]], values=[42], shape=[2, 1]), "gps": SparseTensor( indices=[], values=[], shape=[2, 0]), } Example input, format, and output: Dense Inputs (without defaults) ================================================================== Given two brain.Example input protos: serialized: // serialized versions of the protos below [features: { feature: { key: "age" value: { int64_list: { value: [ 0 ] } } } feature: { key: "gender" value: { bytes_list: { value: [ "f" ] } } } }, features: { feature: { key: "age" value: { int64_list: { value: [] } } } feature: { key: "gender" value: { bytes_list: { value: [ "f" ] } } } }] names: ["input0", "input1"], dense_keys: np.array(["age", "gender"]) dense_types: [tf.int64, tf.string] dense_defaults: { "age": -1 # defaults to -1 if missing # "gender" has no specified default so it's required } dense_shapes: [(1,), (1,)] # age, gender, label, weight Then the expected output is a dictionary: { "age": [[0], [-1]], "gender": [["f"], ["f"]], } Example input, format, and output: Dense Inputs (with defaults) =============================================================== Given two brain.Example input protos: serialized: // serialized versions of the protos below [features: { feature: { key: "weight" value: { float_list: { value: [ 1.0 ] } } } }, features: { feature: { key: "label" value: { float_list: { value: [ -1.0, 0.0 ] } } } }] names: ["input0", "input1"], dense_keys: np.array(["label", "weight"]) dense_defaults: { "label": [1.0, 2.0], # float (default: vector) "weight": 5.0 # float (default: scalar, 5.0) } dense_shapes: [(2,), (1,)] # age, gender, label, weight Then the expected output is a dictionary: { "label": [[1.0, 2.0], [-1.0, 0.0]], "weight": [[1.0], [5.0]], } """ names = [] if names is None else names dense_defaults = {} if dense_defaults is None else dense_defaults sparse_keys = [] if sparse_keys is None else sparse_keys sparse_types = [] if sparse_types is None else sparse_types dense_keys = [] if dense_keys is None else dense_keys dense_types = [] if dense_types is None else dense_types dense_shapes = [[]] * len( dense_keys) if dense_shapes is None else dense_shapes num_dense = len(dense_keys) num_sparse = len(sparse_keys) if len(dense_shapes) != num_dense: raise ValueError("len(dense_shapes) != len(dense_keys): %d vs. %d" % (len(dense_shapes), num_dense)) if len(dense_types) != num_dense: raise ValueError("len(dense_types) != len(num_dense): %d vs. %d" % (len(dense_types), num_dense)) if len(sparse_types) != num_sparse: raise ValueError("len(sparse_types) != len(sparse_keys): %d vs. %d" % (len(sparse_types), num_sparse)) if num_dense + num_sparse == 0: raise ValueError("Must provide at least one sparse key or dense key") if not set(dense_keys).isdisjoint(set(sparse_keys)): raise ValueError( "Dense and sparse keys must not intersect; intersection: %s" % set(dense_keys).intersection(set(sparse_keys))) dense_defaults_vec = [] for i, key in enumerate(dense_keys): default_value = dense_defaults.get(key) if default_value is None: default_value = constant_op.constant([], dtype=dense_types[i]) elif not isinstance(default_value, ops.Tensor): default_value = ops.convert_to_tensor(default_value, dtype=dense_types[i], name=key) default_value = array_ops.reshape(default_value, dense_shapes[i]) dense_defaults_vec.append(default_value) dense_shapes = [ tensor_util.MakeTensorShapeProto(shape) if isinstance( shape, (list, tuple)) else shape for shape in dense_shapes ] outputs = gen_parsing_ops._parse_example(serialized=serialized, names=names, dense_defaults=dense_defaults_vec, sparse_keys=sparse_keys, sparse_types=sparse_types, dense_keys=dense_keys, dense_shapes=dense_shapes, name=name) (sparse_indices, sparse_values, sparse_shapes, dense_values) = outputs sparse_tensors = [ ops.SparseTensor(ix, val, shape) for (ix, val, shape) in zip(sparse_indices, sparse_values, sparse_shapes) ] return dict(zip(sparse_keys + dense_keys, sparse_tensors + dense_values))
def foldl(fn, elems, initializer=None, parallel_iterations=10, back_prop=True, swap_memory=False, name=None): """foldl on the list of tensors unpacked from `elems` on dimension 0. This foldl operator repeatedly applies the callable `fn` to a sequence of elements from first to last. The elements are made of the tensors unpacked from `elems` on dimension 0. The callable fn takes two tensors as arguments. The first argument is the accumulated value computed from the preceding invocation of fn. If `initializer` is None, `elems` must contain at least one element, and its first element is used as the initializer. Suppose that `elems` is unpacked into `values`, a list of tensors. The shape of the result tensor is fn(initializer, values[0]).shape`. Args: fn: The callable to be performed. elems: A tensor to be unpacked on dimension 0. initializer: (optional) The initial value for the accumulator. parallel_iterations: (optional) The number of iterations allowed to run in parallel. back_prop: (optional) True enables back propagation. swap_memory: (optional) True enables GPU-CPU memory swapping. name: (optional) Name prefix for the returned tensors. Returns: A tensor resulting from applying `fn` consecutively to the list of tensors unpacked from `elems`, from first to last. Raises: TypeError: if `fn` is not callable. Example: ```python elems = [1, 2, 3, 4, 5, 6] sum = foldl(lambda a, x: a + x, elems) # sum == 21 ``` """ with ops.op_scope([elems], name, "foldl") as name: if not callable(fn): raise TypeError("fn must be callable.") # Convert elems to tensor array. n = array_ops.shape(elems)[0] elems_ta = tensor_array_ops.TensorArray(dtype=elems.dtype, size=n, dynamic_size=False) elems_ta = elems_ta.unpack(elems) if initializer is None: a = elems_ta.read(0) i = constant_op.constant(1) else: a = ops.convert_to_tensor(initializer) i = constant_op.constant(0) def compute(i, a): a = fn(a, elems_ta.read(i)) return [i + 1, a] _, r_a = control_flow_ops.While(lambda i, a: i < n, compute, [i, a], parallel_iterations=parallel_iterations, back_prop=back_prop, swap_memory=swap_memory) return r_a
def testNoConvert(self): # Make sure converting to the same data type creates no ops with self.test_session(): image = constant_op.constant([1], dtype=dtypes.uint8) y = image_ops.convert_image_dtype(image, dtypes.uint8) self.assertEquals(image, y)
def __init__(self, dtype, size=None, dynamic_size=None, clear_after_read=None, tensor_array_name=None, handle=None, flow=None, infer_shape=True, name=None): """Construct a new TensorArray or wrap an existing TensorArray handle. Args: dtype: (required) data type of the TensorArray. size: (optional) int32 scalar `Tensor`: the size of the TensorArray. Required if handle is not provided. dynamic_size: (optional) Python bool: If true, writes to the TensorArray can grow the TensorArray past its initial size. Default: False. clear_after_read: Boolean (optional, default: True). If True, clear TensorArray values after reading them. This disables read-many semantics, but allows early release of memory. tensor_array_name: (optional) Python string: the name of the TensorArray. This is used when creating the TensorArray handle. If this value is set, handle should be None. handle: (optional) A `Tensor` handle to an existing TensorArray. If this is set, tensor_array_name should be None. flow: (optional) A float `Tensor` scalar coming from an existing `TensorArray.flow`. infer_shape: (optional, default: True) If True, shape inference is enabled. In this case, all elements must have the same shape. name: A name for the operation (optional). Raises: ValueError: if both handle and tensor_array_name are provided. TypeError: if handle is provided but is not a Tensor. """ if handle is not None and tensor_array_name: raise ValueError( "Cannot construct with both handle and tensor_array_name") if handle is not None and not isinstance(handle, ops.Tensor): raise TypeError("Handle must be a Tensor") if handle is None and size is None: raise ValueError("Size must be provided if handle is not provided") if handle is not None and size is not None: raise ValueError("Cannot provide both a handle and size " "at the same time") if handle is not None and dynamic_size is not None: raise ValueError("Cannot provide both a handle and dynamic_size " "at the same time") if handle is not None and clear_after_read is not None: raise ValueError( "Cannot provide both a handle and clear_after_read " "at the same time") if clear_after_read is None: clear_after_read = True dynamic_size = dynamic_size or False self._dtype = dtype self._infer_shape = infer_shape # Record the current static shape for the array elements. The first # write adds the shape of the tensor it writes, and all subsequent # writes checks for shape equality. self._elem_shape = [] with ops.op_scope([handle, size, flow], name, "TensorArray") as scope: if handle is not None: self._handle = handle else: if flow is not None: with ops.colocate_with(flow): self._handle = gen_data_flow_ops._tensor_array( dtype=dtype, size=size, dynamic_size=dynamic_size, clear_after_read=clear_after_read, tensor_array_name=tensor_array_name, name=scope) else: self._handle = gen_data_flow_ops._tensor_array( dtype=dtype, size=size, dynamic_size=dynamic_size, clear_after_read=clear_after_read, tensor_array_name=tensor_array_name, name=scope) if flow is not None: self._flow = flow else: with ops.colocate_with(self._handle): self._flow = constant_op.constant(0, dtype=_dtypes.float32)
def _model_fn(features, targets, mode): ops.get_default_graph().add_to_collection('IS_TRAINING', mode == 'train') if class_weight is not None: constant_op.constant(class_weight, name='class_weight') return model_fn(features, targets)
def testFeedDictKeyException(self): with session.Session() as sess: a = constant_op.constant(1.0, dtypes.float32, name='a') with self.assertRaisesRegexp(TypeError, "Cannot interpret feed_dict"): sess.run(a, feed_dict={'a': [2.0]})