def testNotEqual(self): # Scalar inputs. tf_val = math_ops.not_equal(constant_op.constant(1), constant_op.constant(1)) self.assertEqual(tensor_util.constant_value(tf_val), False) tf_val = math_ops.not_equal(constant_op.constant(1), constant_op.constant(0)) self.assertEqual(tensor_util.constant_value(tf_val), True) # Shaped inputs with broadcast semantics. tf_val = math_ops.not_equal(constant_op.constant([[0, 1]]), constant_op.constant([[0], [1]])) c_val = tensor_util.constant_value(tf_val) self.assertAllEqual(c_val, [[False, True], [True, False]])
def compute_mean_iou(_, total_cm): """Compute the mean intersection-over-union via the confusion matrix.""" sum_over_row = math_ops.to_float(math_ops.reduce_sum(total_cm, 0)) sum_over_col = math_ops.to_float(math_ops.reduce_sum(total_cm, 1)) cm_diag = math_ops.to_float(array_ops.diag_part(total_cm)) denominator = sum_over_row + sum_over_col - cm_diag # The mean is only computed over classes that appear in the # label or prediction tensor. If the denominator is 0, we need to # ignore the class. num_valid_entries = math_ops.reduce_sum( math_ops.cast(math_ops.not_equal(denominator, 0), dtype=dtypes.float32)) # If the value of the denominator is 0, set it to 1 to avoid # zero division. denominator = array_ops.where(math_ops.greater(denominator, 0), denominator, array_ops.ones_like(denominator)) iou = math_ops.div(cm_diag, denominator) # If the number of valid entries is 0 (no classes) we return 0. result = array_ops.where( math_ops.greater(num_valid_entries, 0), math_ops.reduce_sum(iou, name='mean_iou') / num_valid_entries, 0) return result
def _split_indexed_slices_v2(sp_input=None, num_split=None, dim_size=0, name=None): ids_per_partition = dim_size // num_split extras = dim_size % num_split with ops.name_scope(name): # When the partitioned dim cannot be divided by num_split, the reminders are # evenly assigned from the first partition to the last. p_assignments = math_ops.maximum( sp_input.indices // (ids_per_partition + 1), (sp_input.indices - extras) // ids_per_partition) split_grads = [] for i in range(0, num_split): with ops.name_scope(f"part_{i}"): ids_not_in_i = array_ops.where( math_ops.not_equal(p_assignments, i)) flat_ids_not_in_i = array_ops.reshape(ids_not_in_i, [-1]) if sp_input.indices.dtype == dtypes.int64: flat_ids_not_in_i = math_ops.cast( flat_ids_not_in_i, dtypes.int64) else: flat_ids_not_in_i = math_ops.cast( flat_ids_not_in_i, dtypes.int32) s = array_ops.sparse_mask(sp_input, flat_ids_not_in_i) if i < extras: s._indices = math_ops.floor_mod( s.indices, ids_per_partition + 1) else: s._indices = math_ops.floor_mod( s.indices - extras, ids_per_partition) split_grads.append(s) return split_grads
def collapse_repeated(labels, seq_length, name=None): """Merge repeated labels into single labels. Args: labels: Tensor of shape [batch, max value in seq_length] seq_length: Tensor of shape [batch], sequence length of each batch element. name: A name for this `Op`. Defaults to "collapse_repeated_labels". Returns: A tuple `(collapsed_labels, new_seq_length)` where collapsed_labels: Tensor of shape [batch, max_seq_length] with repeated labels collapsed and padded to max_seq_length, eg: `[[A, A, B, B, A], [A, B, C, D, E]] => [[A, B, A, 0, 0], [A, B, C, D, E]]` new_seq_length: int tensor of shape [batch] with new sequence lengths. """ with ops.name_scope(name, "collapse_repeated_labels", [labels, seq_length]): labels = ops.convert_to_tensor(labels, name="labels") seq_length = ops.convert_to_tensor(seq_length, name="seq_length") # Mask labels that don't equal previous label. label_mask = array_ops.concat([ array_ops.ones_like(labels[:, :1], dtypes.bool), math_ops.not_equal(labels[:, 1:], labels[:, :-1]) ], axis=1) # Filter labels that aren't in the original sequence. maxlen = _get_dim(labels, 1) seq_mask = array_ops.sequence_mask(seq_length, maxlen=maxlen) label_mask = math_ops.logical_and(label_mask, seq_mask) # Count masks for new sequence lengths. new_seq_len = math_ops.reduce_sum( math_ops.cast(label_mask, dtypes.int32), axis=1) # Mask indexes based on sequence length mask. new_maxlen = math_ops.reduce_max(new_seq_len) idx_mask = array_ops.sequence_mask(new_seq_len, maxlen=new_maxlen) # Flatten everything and mask out labels to keep and sparse indices. flat_labels = array_ops.reshape(labels, [-1]) flat_label_mask = array_ops.reshape(label_mask, [-1]) flat_idx_mask = array_ops.reshape(idx_mask, [-1]) idx = math_ops.range(_get_dim(flat_idx_mask, 0)) # Scatter to flat shape. flat = array_ops.scatter_nd( indices=array_ops.expand_dims( array_ops.boolean_mask(idx, flat_idx_mask), axis=1), updates=array_ops.boolean_mask(flat_labels, flat_label_mask), shape=array_ops.shape(flat_idx_mask)) # Reshape back to square batch. batch_size = _get_dim(labels, 0) new_shape = [batch_size, new_maxlen] return (array_ops.reshape(flat, new_shape), math_ops.cast(new_seq_len, seq_length.dtype))
def compute_iou(name): """Compute the mean intersection-over-union via the confusion matrix.""" # sum_over_row = math_ops.to_float(math_ops.reduce_sum(total_cm, 0), dtypes.float32) # sum_over_col = math_ops.to_float(math_ops.reduce_sum(total_cm, 1), dtypes.float32) # cm_diag = math_ops.to_float(array_ops.diag_part(total_cm), dtypes.float32) # denominator = sum_over_row + sum_over_col - cm_diag sum_over_row = math_ops.cast(math_ops.reduce_sum(total_cm, 0), dtypes.float32) sum_over_col = math_ops.cast(math_ops.reduce_sum(total_cm, 1), dtypes.float32) cm_diag = math_ops.cast(array_ops.diag_part(total_cm), dtypes.float32) denominator = sum_over_row + sum_over_col - cm_diag # The mean is only computed over classes that appear in the # label or prediction tensor. If the denominator is 0, we need to # ignore the class. num_valid_entries = math_ops.reduce_sum( math_ops.cast(math_ops.not_equal(denominator, 0), dtype=dtypes.float32)) # If the value of the denominator is 0, set it to 1 to avoid # zero division. denominator = array_ops.where(math_ops.greater(denominator, 0), denominator, array_ops.ones_like(denominator)) # iou iou = math_ops.div(cm_diag, denominator) return iou
def weighted(y_true, y_pred, weights, mask=None): """Wrapper function. Arguments: y_true: `y_true` argument of `fn`. y_pred: `y_pred` argument of `fn`. weights: Weights tensor. mask: Mask tensor. Returns: Scalar tensor. """ # score_array has ndim >= 2 score_array = fn(y_true, y_pred) if mask is not None: # Cast the mask to floatX to avoid float64 upcasting in theano mask = math_ops.cast(mask, K.floatx()) # mask should have the same shape as score_array score_array *= mask # the loss per batch should be proportional # to the number of unmasked samples. score_array /= K.mean(mask) # apply sample weighting if weights is not None: # reduce score_array to same ndim as weight array ndim = K.ndim(score_array) weight_ndim = K.ndim(weights) score_array = K.mean(score_array, axis=list(range(weight_ndim, ndim))) score_array *= weights score_array /= K.mean( math_ops.cast(math_ops.not_equal(weights, 0), K.floatx())) return K.mean(score_array)
def _filter_input(input_tensor, vocab_freq_table, vocab_min_count, vocab_subsampling, corpus_size, seed): """Filters input tensor based on vocab freq, threshold, and subsampling.""" if vocab_freq_table is None: return input_tensor if not isinstance(vocab_freq_table, lookup.InitializableLookupTableBase): raise ValueError( "vocab_freq_table must be a subclass of " "InitializableLookupTableBase (such as HashTable) instead of type " "{}.".format(type(vocab_freq_table))) with ops.name_scope( "filter_vocab", values=[vocab_freq_table, input_tensor, vocab_min_count]): freq = vocab_freq_table.lookup(input_tensor) # Filters out elements in input_tensor that are not found in # vocab_freq_table (table returns a default value of -1 specified above when # an element is not found). mask = math_ops.not_equal(freq, vocab_freq_table.default_value) # Filters out elements whose vocab frequencies are less than the threshold. if vocab_min_count is not None: cast_threshold = math_ops.cast(vocab_min_count, freq.dtype) mask = math_ops.logical_and(mask, math_ops.greater_equal(freq, cast_threshold)) input_tensor = array_ops.boolean_mask(input_tensor, mask) freq = array_ops.boolean_mask(freq, mask) if not vocab_subsampling: return input_tensor if vocab_subsampling < 0 or vocab_subsampling > 1: raise ValueError( "Invalid vocab_subsampling={} - it should be within range [0, 1].". format(vocab_subsampling)) # Subsamples the input tokens based on vocabulary frequency and # vocab_subsampling threshold (ie randomly discard commonly appearing # tokens). with ops.name_scope( "subsample_vocab", values=[input_tensor, freq, vocab_subsampling]): corpus_size = math_ops.cast(corpus_size, dtypes.float64) freq = math_ops.cast(freq, dtypes.float64) vocab_subsampling = math_ops.cast(vocab_subsampling, dtypes.float64) # From tensorflow_models/tutorials/embedding/word2vec_kernels.cc, which is # suppose to correlate with Eq. 5 in http://arxiv.org/abs/1310.4546. keep_prob = ((math_ops.sqrt(freq / (vocab_subsampling * corpus_size)) + 1.0) * (vocab_subsampling * corpus_size / freq)) random_prob = random_ops.random_uniform( array_ops.shape(freq), minval=0, maxval=1, dtype=dtypes.float64, seed=seed) mask = math_ops.less_equal(random_prob, keep_prob) return array_ops.boolean_mask(input_tensor, mask)
def call(self, inputs): boolean_mask = K.any( math_ops.not_equal(inputs, self.mask_value), axis=-1, keepdims=True) outputs = inputs * math_ops.cast(boolean_mask, inputs.dtype) # Compute the mask and outputs simultaneously. outputs._keras_mask = array_ops.squeeze(boolean_mask, axis=-1) # pylint: disable=protected-access return outputs
def result(self): """Compute the mean intersection-over-union via the confusion matrix.""" sum_over_row = math_ops.cast(math_ops.reduce_sum(self.total_cm, axis=0), dtype=self._dtype) sum_over_col = math_ops.cast(math_ops.reduce_sum(self.total_cm, axis=1), dtype=self._dtype) true_positives = math_ops.cast(array_ops.diag_part(self.total_cm), dtype=self._dtype) # sum_over_row + sum_over_col = # 2 * true_positives + false_positives + false_negatives. denominator = sum_over_row + sum_over_col numerator = true_positives + true_positives # The mean is only computed over classes that appear in the # label or prediction tensor. If the denominator is 0, we need to # ignore the class. num_valid_entries = math_ops.reduce_sum( math_ops.cast(math_ops.not_equal(denominator, 0), dtype=self._dtype)) dice = math_ops.div_no_nan(true_positives, denominator) return math_ops.div_no_nan(math_ops.reduce_sum(dice, name='mean_dice'), num_valid_entries)
def dense_to_sparse_tensor(dense_tensor, ignore_value=None): """Converts dense `Tensor` to `SparseTensor`, dropping `ignore_value` cells. Args: dense_tensor: A `Tensor`. ignore_value: Entries in `dense_tensor` equal to this value will be absent from the return `SparseTensor`. If `None`, default value of `dense_tensor` dtype will be used (e.g. '' for `str`, 0 for `int`). Returns: A `SparseTensor` with the same shape as `dense_tensor`. Raises: ValueError: when `dense_tensor`'s rank is `None`. """ with ops.name_scope("DenseToSparseTensor"): dense_tensor = ops.convert_to_tensor(dense_tensor) ignore_value = _ignore_value_tensor(dense_tensor.dtype, ignore_value) indices = array_ops.where( math_ops.not_equal(dense_tensor, ignore_value), name="indices") return sparse_tensor.SparseTensor( indices=indices, values=array_ops.gather_nd(dense_tensor, indices, name="values"), dense_shape=array_ops.shape( dense_tensor, out_type=dtypes.int64, name="dense_shape"))
def dense_put(tensor, sp_updates, name="dense_put"): """ Changes a given dense ``Tensor`` according to the updates specified in a ``SparseTensor``. Creates a new ``Tensor`` where the values of the updates override the values in the original tensor. The tensor `shape` must be the same as the updates `dense_shape`. Args: tensor: a ``Tensor`` we want to change. sp_updates: a ``SparseTensor`` with the indices to be changed and the respective values. name: the name for this operation (optional). Returns: ``Tensor``: a ``Tensor`` with the updated values. """ with ops.name_scope(name): tensor = ops.convert_to_tensor(tensor) if sp_updates.dtype != tensor.dtype: sp_updates = math_ops.cast(sp_updates, tensor.dtype) markers = array_ops.ones(shape=array_ops.shape(sp_updates.values)) sparse_marker_tensor = SparseTensor(indices=sp_updates.indices, values=markers, dense_shape=sp_updates.dense_shape) dense_update_marker = sp_ops.sparse_tensor_to_dense( sparse_marker_tensor) dense_updates = sp_ops.sparse_tensor_to_dense(sp_updates) new_tensor = array_ops.where( math_ops.not_equal(dense_update_marker, 0), dense_updates, tensor) return new_tensor
def sparse_dropout(sp_tensor, keep_prob=0.2, seed=None, name="sparse_dropout"): """Performs a dropout on a ``SparseTensor``. With probability `keep_prob`, outputs the input element scaled up by `1 / keep_prob`, otherwise outputs `0`. The scaling is so that the expected sum is unchanged. Args: sp_tensor: a ``SparseTensor`` on which the dropout is performed. keep_prob: A scalar `Tensor` with the same type as x. The probability that each element is kept. seed: A Python integer. Used to create random seeds. (See `TensorFlow` documentation for ``tf.set_random_seed`` for behavior.) name: A name for this operation (optional). """ with ops.name_scope(name): dense_shape = sp_tensor.dense_shape drop_values = dropout(sp_tensor.values, keep_prob, seed=seed) not_zero = math_ops.not_equal(drop_values, 0) # new indices (after dropout) # not_zero_indices = array_ops.where(not_zero) # indices = array_ops.gather_nd(sp_indices.indices, not_zero_indices) values = array_ops.boolean_mask(drop_values, not_zero) indices = array_ops.boolean_mask(sp_tensor.indices, not_zero) new_tensor = SparseTensor(indices, values, dense_shape) return new_tensor
def call(self, inputs): inputs_embed = self.embedding(inputs) inputs_mask = math_ops.not_equal(inputs, 0) valid_inputs_embed = mask_for_high_rank(inputs_embed, inputs_mask) # batch_size,skip_window,visit_len,vec inputs_merged = tf.reduce_sum(valid_inputs_embed, 2) # batch_size,skip_window,vec inputs_merged = self.learner(inputs_merged) return inputs_merged
def dense_to_sparse_tensor(dense_tensor, ignore_value=None): """Converts dense `Tensor` to `SparseTensor`, dropping `ignore_value` cells. Args: dense_tensor: A `Tensor`. ignore_value: Entries in `dense_tensor` equal to this value will be absent from the return `SparseTensor`. If `None`, default value of `dense_tensor` dtype will be used (e.g. '' for `str`, 0 for `int`). Returns: A `SparseTensor` with the same shape as `dense_tensor`. Raises: ValueError: when `dense_tensor`'s rank is `None`. """ with ops.name_scope("DenseToSparseTensor"): dense_tensor = ops.convert_to_tensor(dense_tensor) ignore_value = _ignore_value_tensor(dense_tensor.dtype, ignore_value) indices = array_ops.where(math_ops.not_equal(dense_tensor, ignore_value), name="indices") return sparse_tensor.SparseTensor( indices=indices, values=array_ops.gather_nd(dense_tensor, indices, name="values"), dense_shape=array_ops.shape(dense_tensor, out_type=dtypes.int64, name="dense_shape"))
def _PowGrad(op, grad): """Returns grad * (y*x^(y-1), z*log(x)).""" x = op.inputs[0] y = op.inputs[1] z = op.outputs[0] sx = array_ops.shape(x) sy = array_ops.shape(y) rx, ry = gen_array_ops.broadcast_gradient_args(sx, sy) x = math_ops.conj(x) y = math_ops.conj(y) z = math_ops.conj(z) gx = array_ops.reshape( math_ops.reduce_sum(grad * y * math_ops.pow(x, y - 1), rx), sx) # Avoid false singularity at x = 0 if x.dtype.is_complex: # real(x) < 0 is fine for the complex case mask = math_ops.not_equal(x, 0) else: # There's no sensible real value to return if x < 0, so return 0 mask = x > 0 safe_x = array_ops.where(mask, x, array_ops.ones_like(x)) log_x = array_ops.where(mask, math_ops.log(safe_x), array_ops.zeros_like(x)) gy = array_ops.reshape(math_ops.reduce_sum(grad * z * log_x, ry), sy) return gx, gy
def finalize(self, output, final_state, sequence_lengths): # Gather according to beam search result # now predicted_ids is [M, N/B] predicted_ids = beam_search.gather_tree(output.predicted_ids, output.beam_parent_ids) # TODO(Shancheng): pay attention beam_width = output.beam_parent_ids.get_shape().as_list() parent_ids = tf.concat([tf.zeros([1, beam_width[-1]], dtype=tf.int32), output.beam_parent_ids[:-1, :]], 0) # now logits is [M, N/B, C] logits = beam_search.gather_tree(output.logits, parent_ids) # now attention scores is [M, N/B, L, H, W] attention_scores = beam_search.gather_tree(output.attention_scores, parent_ids) # orginal length is the length of ungathered logits sequence_lengths = math_ops.not_equal(predicted_ids, self.end_token) sequence_lengths = tf.to_int32(sequence_lengths) sequence_lengths = tf.reduce_sum(sequence_lengths, axis=0) + 1 # choose the top score item predicted_ids = predicted_ids[:, 0:1] logits = logits[:, 0:1] attention_scores = attention_scores[:, 0:1] # mask out length = sequence_lengths[0] logits = logits[0:length, :] attention_scores = attention_scores[0:length, :] final_outputs = DecoderOutput( logits=self._padding(logits), predicted_ids=self._padding(predicted_ids), attention_scores=attention_scores) return final_outputs, final_state
def to_sparse(tensor, name="to_sparse"): """ Returns a ``SparseTensor` for a`given dense ``Tensor``. Example: For a dense ``Tensor`` such as:: tensor = [[1,0], [2,3]] this returns an op that creates the following two ``SparseTensor``:: SparseTensor(indices = [[0,0],[1,0],[1,1]], values = [1,2,3], dense_shape = [2,2]) Args: tensor: a dense ``Tensor`` name: name for this operation (optional) Returns: ``SparseTensor``: a sparse tensor with sparse index and value tensors with the non-zero entries of the given input. """ with ops.name_scope(name): indices = array_ops.where(math_ops.not_equal(tensor, 0)) dense_shape = array_ops.shape(tensor, out_type=dtypes.int64) values = array_ops.gather_nd(tensor, indices) sp_tensor = SparseTensor(indices, values, dense_shape) return sp_tensor
def __ne__(self, other): # math_ops.not_equal raises an error if shapes are not compatible, so check # explicitly first. if common_shapes.is_broadcast_compatible( self.shape, ops.convert_to_tensor(other).shape): return math_ops.not_equal(self, other) return True
def testStringComparison(self): x = np.array([["abc", "bh"], ["c", ""]]) y = np.array([["abc", "bh"], ["def", "hi"]]) with self.test_session(use_gpu=False) as sess: cmp_eq = math_ops.equal(x, y) cmp_not_eq = math_ops.not_equal(x, y) values = sess.run([cmp_eq, cmp_not_eq]) self.assertAllEqual([[True, True], [False, False]], values[0]) self.assertAllEqual([[False, False], [True, True]], values[1])
def testStringComparison(self): x = np.array([["abc", "bh"], ["c", ""]]) y = np.array([["abc", "bh"], ["def", "hi"]]) with test_util.force_cpu(): cmp_eq = math_ops.equal(x, y) cmp_not_eq = math_ops.not_equal(x, y) values = self.evaluate([cmp_eq, cmp_not_eq]) self.assertAllEqual([[True, True], [False, False]], values[0]) self.assertAllEqual([[False, False], [True, True]], values[1])
def _dense_to_sparse_tensor(dense_tensor): """Returns a SparseTensor for the input dense_tensor.""" ignore_value = 0.0 sparse_indices = array_ops.where(math_ops.not_equal( dense_tensor, math_ops.cast(ignore_value, dense_tensor.dtype))) sparse_values = array_ops.gather_nd(dense_tensor, sparse_indices) # SparseTensor needs the shape to be converted to int64. int64_shape = math_ops.to_int64(array_ops.shape(dense_tensor)) return ops.SparseTensor(sparse_indices, sparse_values, shape=int64_shape)
def _tf_dataset_len(s): l = cardinality.cardinality(s) msg = gen_string_ops.string_join([ 'len requires dataset with definitive cardinality, got ', gen_string_ops.as_string(l) ]) # TODO (yongtang): UNKNOWN is treated as an error. # In case there are more UNKNOWN cases for dataset, we could # use dataset.reduce() to find out the length (in an expensive way). with ops.control_dependencies([ control_flow_ops.Assert( math_ops.logical_and( math_ops.not_equal(l, cardinality.INFINITE), math_ops.not_equal(l, cardinality.UNKNOWN)), [msg]) ]): l = array_ops.identity(l) return l
def update_state(self, labels, predicts, weights=None): predicts = engine.int64(predicts) labels = engine.int64(labels) if labels.get_shape().ndims > 1: labels = array_ops.reshape(labels, [-1]) if predicts.get_shape().ndims > 1: predicts = array_ops.reshape(predicts, [-1]) if weights is not None and weights.get_shape().ndims > 1: weights = array_ops.reshape(weights, [-1]) add_value = confusion_matrix(labels, predicts, num_classes=self.num_classes, weights=weights, dtype=dtypes.float64) with fops.control_dependencies([self.total_value]): self.update_ops.append( state_ops.assign_add(self.total_value, add_value)) sum_alone_row = engine.float32(math_ops.reduce_sum( self.total_value, 0)) sum_alone_col = engine.float32(math_ops.reduce_sum( self.total_value, 1)) diag = engine.float32(array_ops.diag_part(self.total_value)) denominator = sum_alone_row + sum_alone_col - diag valid_entries = math_ops.reduce_sum( engine.float32(math_ops.not_equal(denominator, 0))) denominator = array_ops.where(math_ops.greater(denominator, 0), denominator, array_ops.ones_like(denominator)) iou = math_ops.div(diag, denominator) self._mean_iou = array_ops.where(math_ops.greater(valid_entries, 0), math_ops.reduce_sum(iou) / valid_entries, 0, name='mean_iou') self._classes_iou = array_ops.where(math_ops.not_equal(denominator, 0), iou, array_ops.zeros_like(denominator), name='classes_iou')
def _create_cond(self, x): def branch_fn(): # Use a random value so the adds can't be constant folded. return x + sum(random_ops.random_normal([]) for _ in range(self.NUM_INTERMEDIATES)) # Use a dynamic predicate to make sure the cond isn't constant folded. return control_flow_ops.cond(math_ops.not_equal(x, -1), branch_fn, lambda: 0.0)
def testFilterRange(self): dataset = dataset_ops.Dataset.range(100).filter( lambda x: math_ops.not_equal(math_ops.mod(x, 3), 2)) iterator = dataset.make_one_shot_iterator() get_next = iterator.get_next() with self.test_session() as sess: self.assertEqual(0, sess.run(get_next)) self.assertEqual(1, sess.run(get_next)) self.assertEqual(3, sess.run(get_next))
def eval_perform(cm_array, name): """Compute the mean intersection-over-union via the confusion matrix.""" # Transfer numpy to tensor cm_tensor = tf.convert_to_tensor(cm_array) # print("cm_tensor=",type(cm_tensor)) # Compute using tensor sum_over_row = math_ops.to_float(math_ops.reduce_sum(cm_tensor, 0)) sum_over_col = math_ops.to_float(math_ops.reduce_sum(cm_tensor, 1)) cm_diag = math_ops.to_float(array_ops.diag_part(cm_tensor)) # 交集,对角线值 denominator = sum_over_row + sum_over_col - cm_diag # 分母,即并集 # The mean is only computed over classes that appear in the label or prediction tensor. If the denominator is 0, we need to ignore the class. num_valid_entries = math_ops.reduce_sum( math_ops.cast(math_ops.not_equal(denominator, 0), dtype=tf.float32)) # 类别个数 ## for IoU # If the value of the denominator is 0, set it to 1 to avoid zero division. denominator = array_ops.where(math_ops.greater(denominator, 0), denominator, array_ops.ones_like(denominator)) iou = math_ops.div(cm_diag, denominator) # 各类IoU # If the number of valid entries is 0 (no classes) we return 0. miou_tensor = array_ops.where(math_ops.greater(num_valid_entries, 0), math_ops.reduce_sum(iou, name=name) / num_valid_entries, 0) #mIoU # weight iou by liaowj weight1 = 0.4 weight2 = 0.4 weight3 = 0.1 weight4 = 0.1 weight0 = 0.0 Wiou_tensor = weight0 * iou[0] + weight1 * iou[1] + weight2 * iou[ 2] + weight3 * iou[3] + weight4 * iou[4] ## for PA: pixel accuracy PA_tensor = math_ops.div(math_ops.reduce_sum(cm_diag), math_ops.reduce_sum(sum_over_row)) # 创建session,执行计算 sess = tf.Session() sess.run(miou_tensor) # tensor转化为numpy数组 # sum_over_row_array = sum_over_row.eval(session=sess) # cm_diag_array = cm_diag.eval(session=sess) ious_array = iou.eval(session=sess) miou_array = miou_tensor.eval(session=sess) Wiou_array = Wiou_tensor.eval(session=sess) PA_array = PA_tensor.eval(session=sess) return ious_array, miou_array, Wiou_array, PA_array
def tensor_not_equals(self: ragged_tensor.RaggedOrDense, other: ragged_tensor.RaggedOrDense): """Ragged version of the operation invoked by `Tensor.__ne__`.""" if other is None: return False elif _use_legacy_mode_for_tensor_equality(self): return self is not other else: try: return math_ops.not_equal(self, other) except (errors.InvalidArgumentError, ValueError): return True # values are not broadcast-compatbile.
def compute_m_iou_accu(labels, predictions, num_classes, weights=None, name=None): """Calculate per-step mean Intersection-Over-Union (mIOU). """ # Check if shape is compatible. predictions.get_shape().assert_is_compatible_with(labels.get_shape()) predictions = math_ops.to_int64(predictions) labels = math_ops.to_int64(labels) num_classes = math_ops.to_int64(num_classes) current_cm = confusion_matrix.confusion_matrix(labels, predictions, num_classes, weights=weights, dtype=dtypes.float64) sum_over_row = math_ops.to_float(math_ops.reduce_sum(current_cm, 0)) sum_over_col = math_ops.to_float(math_ops.reduce_sum(current_cm, 1)) cm_diag = math_ops.to_float(array_ops.diag_part(current_cm)) denominator = sum_over_row + sum_over_col - cm_diag # The mean is only computed over classes that appear in the # label or prediction tensor. If the denominator is 0, we need to # ignore the class. num_valid_entries = math_ops.reduce_sum( math_ops.cast(math_ops.not_equal(denominator, 0), dtype=dtypes.float32)) # If the value of the denominator is 0, set it to 1 to avoid # zero division. denominator = array_ops.where(math_ops.greater(denominator, 0), denominator, array_ops.ones_like(denominator)) iou = math_ops.div(cm_diag, denominator) # If the number of valid entries is 0 (no classes) we return 0. m_iou = array_ops.where(math_ops.greater(num_valid_entries, 0), math_ops.reduce_sum(iou) / num_valid_entries, 0) class_count = array_ops.where(math_ops.greater(sum_over_col, 0), sum_over_col, array_ops.ones_like(sum_over_col)) accu_per_class = math_ops.div(cm_diag, class_count) m_accu = array_ops.where( math_ops.greater(num_valid_entries, 0), math_ops.reduce_sum(accu_per_class) / num_valid_entries, 0) return m_iou, m_accu
def assert_none_equal(x, y, data=None, summarize=None, message=None, name=None): """Assert the condition `x != y` holds for all elements. Example of adding a dependency to an operation: ```python with tf.control_dependencies([tf.assert_none_equal(x, y)]): output = tf.reduce_sum(x) ``` This condition holds if for every pair of (possibly broadcast) elements `x[i]`, `y[i]`, we have `x[i] != y[i]`. If both `x` and `y` are empty, this is trivially satisfied. Args: x: Numeric `Tensor`. y: Numeric `Tensor`, same dtype as and broadcastable to `x`. data: The tensors to print out if the condition is False. Defaults to error message and first few entries of `x`, `y`. summarize: Print this many entries of each tensor. message: A string to prefix to the default message. name: A name for this operation (optional). Defaults to "assert_none_equal". Returns: Op that raises `InvalidArgumentError` if `x != y` is ever False. """ message = message or '' with ops.name_scope(name, 'assert_none_equal', [x, y, data]): x = ops.convert_to_tensor(x, name='x') y = ops.convert_to_tensor(y, name='y') if context.executing_eagerly(): x_name = _shape_and_dtype_str(x) y_name = _shape_and_dtype_str(y) else: x_name = x.name y_name = y.name if data is None: data = [ message, 'Condition x != y did not hold for every single element:', 'x (%s) = ' % x_name, x, 'y (%s) = ' % y_name, y ] condition = math_ops.reduce_all(math_ops.not_equal(x, y)) return control_flow_ops.Assert(condition, data, summarize=summarize)
def _gif(): # Create assert op to check that bytes are GIF decodable is_gif = math_ops.equal(substr, b'\x47\x49\x46\x38', name='is_gif') decode_msg = 'Unable to decode bytes as JPEG, PNG, or GIF' assert_decode = control_flow_ops.Assert(is_gif, [decode_msg]) # Create assert to make sure that channels is not set to 1 # Already checked above that channels is in (None, 0, 1, 3) gif_channels = 0 if channels is None else channels good_channels = math_ops.not_equal(gif_channels, 1, name='check_channels') channels_msg = 'Channels must be in (None, 0, 3) when decoding GIF images' assert_channels = control_flow_ops.Assert(good_channels, [channels_msg]) with ops.control_dependencies([assert_decode, assert_channels]): return gen_image_ops.decode_gif(contents)
def _dense_to_sparse_tensor(dense_tensor): """Returns a SparseTensor for the input dense_tensor.""" ignore_value = 0.0 sparse_indices = array_ops.where( math_ops.not_equal( dense_tensor, math_ops.cast(ignore_value, dense_tensor.dtype))) sparse_values = array_ops.gather_nd(dense_tensor, sparse_indices) # SparseTensor needs the shape to be converted to int64. int64_shape = math_ops.to_int64(array_ops.shape(dense_tensor)) return ops.SparseTensor(sparse_indices, sparse_values, shape=int64_shape)
def _num_present(losses, weights, per_batch=False): """Computes the number of elements in the loss function induced by `weights`. A given weights tensor induces different numbers of usable elements in the `losses` tensor. The `weights` tensor is broadcast across `losses` for all possible dimensions. For example, if `losses` is a tensor of dimension `[4, 5, 6, 3]` and `weights` is a tensor of shape `[4, 5]`, then `weights` is, in effect, tiled to match the shape of `losses`. Following this effective tile, the total number of present elements is the number of non-zero weights. Args: losses: `Tensor` of shape `[batch_size, d1, ... dN]`. weights: `Tensor` of shape `[]`, `[batch_size]` or `[batch_size, d1, ... dK]`, where K < N. per_batch: Whether to return the number of elements per batch or as a sum total. Returns: The number of present (non-zero) elements in the losses tensor. If `per_batch` is `True`, the value is returned as a tensor of size `[batch_size]`. Otherwise, a single scalar tensor is returned. """ # If weights is a scalar, its easy to compute: if weights.get_shape().ndims == 0: if losses.get_shape().ndims == 0: batch_size = 1 else: batch_size = array_ops.reshape(array_ops.slice(array_ops.shape(losses), [0], [1]), []) num_per_batch = math_ops.div(math_ops.to_float(array_ops.size(losses)), math_ops.to_float(batch_size)) num_per_batch = array_ops.where(math_ops.equal(weights, 0), 0.0, num_per_batch) num_per_batch = math_ops.multiply(array_ops.ones( array_ops.reshape(batch_size, [1])), num_per_batch) return num_per_batch if per_batch else math_ops.reduce_sum(num_per_batch) # First, count the number of nonzero weights. if weights.get_shape().ndims >= 1: reduction_indices = list(range(1, weights.get_shape().ndims)) num_nonzero_per_batch = math_ops.reduce_sum( math_ops.to_float(math_ops.not_equal(weights, 0)), reduction_indices=reduction_indices) # Next, determine the number of elements that weight would broadcast to: broadcast_dims = array_ops.slice(array_ops.shape(losses), [weights.get_shape().ndims], [-1]) num_to_broadcast = math_ops.to_float(math_ops.reduce_prod(broadcast_dims)) num_per_batch = math_ops.multiply(num_nonzero_per_batch, num_to_broadcast) return num_per_batch if per_batch else math_ops.reduce_sum(num_per_batch)
def _num_present(losses, weight, per_batch=False): """Computes the number of elements in the loss function induced by `weight`. A given weight tensor induces different numbers of usable elements in the `losses` tensor. The `weight` tensor is broadcast across `losses` for all possible dimensions. For example, if `losses` is a tensor of dimension [4, 5, 6, 3] and weight is a tensor of size [4, 5], then weight is, in effect, tiled to match the size of `losses`. Following this effective tile, the total number of present elements is the number of non-zero weights. Args: losses: A tensor of size [batch_size, d1, ... dN]. weight: A tensor of size [1] or [batch_size, d1, ... dK] where K < N. per_batch: Whether to return the number of elements per batch or as a sum total. Returns: The number of present (non-zero) elements in the losses tensor. If `per_batch` is True, the value is returned as a tensor of size [batch_size]. Otherwise, a single scalar tensor is returned. """ # To ensure that dims of [2, 1] gets mapped to [2,] weight = array_ops.squeeze(weight) # If the weight is a scalar, its easy to compute: if weight.get_shape().ndims == 0: batch_size = array_ops.reshape(array_ops.slice(array_ops.shape(losses), [0], [1]), []) num_per_batch = math_ops.div(math_ops.to_float(array_ops.size(losses)), math_ops.to_float(batch_size)) num_per_batch = math_ops.select(math_ops.equal(weight, 0), 0.0, num_per_batch) num_per_batch = math_ops.mul(array_ops.ones( array_ops.reshape(batch_size, [1])), num_per_batch) return num_per_batch if per_batch else math_ops.reduce_sum(num_per_batch) # First, count the number of nonzero weights: if weight.get_shape().ndims >= 1: reduction_indices = list(range(1, weight.get_shape().ndims)) num_nonzero_per_batch = math_ops.reduce_sum( math_ops.to_float(math_ops.not_equal(weight, 0)), reduction_indices=reduction_indices) # Next, determine the number of elements that weight would broadcast to: broadcast_dims = array_ops.slice(array_ops.shape(losses), [weight.get_shape().ndims], [-1]) num_to_broadcast = math_ops.to_float(math_ops.reduce_prod(broadcast_dims)) num_per_batch = math_ops.mul(num_nonzero_per_batch, num_to_broadcast) return num_per_batch if per_batch else math_ops.reduce_sum(num_per_batch)
def _tensor_to_sparse_feature_column(dense_tensor): """Returns SparseFeatureColumn for the input dense_tensor.""" ignore_value = 0.0 sparse_indices = array_ops.where( math_ops.not_equal(dense_tensor, math_ops.cast(ignore_value, dense_tensor.dtype)) ) sparse_values = array_ops.gather_nd(dense_tensor, sparse_indices) # TODO(sibyl-Aix6ihai, sibyl-vie3Poto): Makes this efficient, as now SDCA supports # very sparse features with weights and not weights. return sdca_ops.SparseFeatureColumn( array_ops.reshape(array_ops.split(1, 2, sparse_indices)[0], [-1]), array_ops.reshape(array_ops.split(1, 2, sparse_indices)[1], [-1]), array_ops.reshape(math_ops.to_float(sparse_values), [-1]), )
def _XDivyGrad(op, grad): """Returns gradient of xdivy(x, y) with respect to x and y.""" x = op.inputs[0] y = op.inputs[1] sx = array_ops.shape(x) sy = array_ops.shape(y) rx, ry = gen_array_ops.broadcast_gradient_args(sx, sy) with ops.control_dependencies([grad]): not_zero_x = math_ops.cast( math_ops.not_equal(x, math_ops.cast(0., dtype=x.dtype)), dtype=x.dtype) partial_x = gen_math_ops.xdivy(not_zero_x, y) partial_y = gen_math_ops.xdivy(math_ops.negative(x), y**2) return (array_ops.reshape(math_ops.reduce_sum(partial_x * grad, rx), sx), array_ops.reshape(math_ops.reduce_sum(partial_y * grad, ry), sy))
def assert_none_equal( x, y, data=None, summarize=None, message=None, name=None): """Assert the condition `x != y` holds for all elements. Example of adding a dependency to an operation: ```python with tf.control_dependencies([tf.assert_none_equal(x, y)]): output = tf.reduce_sum(x) ``` This condition holds if for every pair of (possibly broadcast) elements `x[i]`, `y[i]`, we have `x[i] != y[i]`. If both `x` and `y` are empty, this is trivially satisfied. Args: x: Numeric `Tensor`. y: Numeric `Tensor`, same dtype as and broadcastable to `x`. data: The tensors to print out if the condition is False. Defaults to error message and first few entries of `x`, `y`. summarize: Print this many entries of each tensor. message: A string to prefix to the default message. name: A name for this operation (optional). Defaults to "assert_none_equal". Returns: Op that raises `InvalidArgumentError` if `x != y` is ever False. """ message = message or '' with ops.name_scope(name, 'assert_none_equal', [x, y, data]): x = ops.convert_to_tensor(x, name='x') y = ops.convert_to_tensor(y, name='y') if context.executing_eagerly(): x_name = _shape_and_dtype_str(x) y_name = _shape_and_dtype_str(y) else: x_name = x.name y_name = y.name if data is None: data = [ message, 'Condition x != y did not hold for every single element:', 'x (%s) = ' % x_name, x, 'y (%s) = ' % y_name, y ] condition = math_ops.reduce_all(math_ops.not_equal(x, y)) return control_flow_ops.Assert(condition, data, summarize=summarize)
def lookup(self, keys, name=None): """Looks up `keys` in the table, outputs the corresponding values. It assigns out-of-vocabulary keys to buckets based in their hashes. Args: keys: Keys to look up. May be either a `SparseTensor` or dense `Tensor`. name: Optional name for the op. Returns: A `SparseTensor` if keys are sparse, otherwise a dense `Tensor`. Raises: TypeError: when `keys` doesn't match the table key data type. """ if keys.dtype.base_dtype != self._key_dtype: raise TypeError("Signature mismatch. Keys must be dtype %s, got %s." % (self._key_dtype, keys.dtype)) values = keys if isinstance(keys, sparse_tensor.SparseTensor): values = keys.values if self._table and (self._table.key_dtype.base_dtype == dtypes.int64): values = math_ops.to_int64(values) if self._num_oov_buckets == 0: ids = self._table.lookup(values, name=name) else: # TODO(yleon): Consider moving this functionality to its own kernel. with ops.name_scope(name, "%s_Lookup" % self.name) as scope: str_to_hash_bucket = self._get_string_to_hash_bucket_fn( self._hasher_spec) buckets = str_to_hash_bucket( _as_string(values), num_buckets=self._num_oov_buckets, name="hash_bucket") if self._table: ids = self._table.lookup(values) buckets = math_ops.add(buckets, self._table.size()) is_id_non_default = math_ops.not_equal(ids, self._table.default_value) ids = array_ops.where(is_id_non_default, ids, buckets, name=scope) else: ids = buckets if isinstance(keys, sparse_tensor.SparseTensor): return sparse_tensor.SparseTensor(keys.indices, ids, keys.dense_shape) return ids
def _PowGrad(op, grad): """Returns grad * (y*x^(y-1), z*log(x)).""" x = op.inputs[0] y = op.inputs[1] z = op.outputs[0] sx = array_ops.shape(x) sy = array_ops.shape(y) rx, ry = gen_array_ops._broadcast_gradient_args(sx, sy) gx = array_ops.reshape(math_ops.reduce_sum(grad * y * math_ops.pow(x, y - 1), rx), sx) # Avoid false singularity at x = 0 if x.dtype.is_complex: # real(x) < 0 is fine for the complex case log_x = math_ops.select(math_ops.not_equal(x, 0), math_ops.log(x), array_ops.zeros_like(x)) else: # There's no sensible real value to return if x < 0, so return 0 log_x = math_ops.select(x > 0, math_ops.log(x), array_ops.zeros_like(x)) gy = array_ops.reshape(math_ops.reduce_sum(grad * z * log_x, ry), sy) return gx, gy
def dense_to_sparse_tensor(dense_tensor, ignore_value=None): """Converts a dense Tensor to a SparseTensor, dropping ignore_value cells. Args: dense_tensor: A `Tensor`. ignore_value: Entries in `dense_tensor` equal to this value will be absent from the return `SparseTensor`. If `None`, default value of dense_tensor's dtype will be used (e.g. '' for `str`, 0 for `int`). Returns: A `SparseTensor` with the same shape as `dense_tensor`. Raises: ValueError: when `dense_tensor`'s rank is `None`. """ with ops.name_scope("DenseToSparseTensor"): dense_t = ops.convert_to_tensor(dense_tensor) if dense_t.get_shape().ndims is None: # TODO(b/32318825): Implement dense_to_sparse_tensor for undefined rank. raise ValueError("dense_tensor.get_shape() should be defined, got None.") if ignore_value is None: if dense_t.dtype == dtypes.string: # Exception due to TF strings are converted to numpy objects by default. ignore_value = "" else: ignore_value = dense_t.dtype.as_numpy_dtype() dense_shape = math_ops.cast(array_ops.shape(dense_t), dtypes.int64) indices = array_ops.where( math_ops.not_equal(dense_t, math_ops.cast(ignore_value, dense_t.dtype))) index_dims = len(dense_t.get_shape()) # Flattens the tensor and indices for use with gather. flat_tensor = array_ops.reshape(dense_t, [-1]) flat_indices = indices[:, index_dims - 1] # Computes the correct flattened indices for 2d (or higher) tensors. if index_dims > 1: higher_dims = indices[:, :index_dims - 1] shape_multipliers = array_ops.stack( _multiplier_helper(array_ops.unstack(dense_shape)[1:])) offsets = math_ops.reduce_sum( math_ops.multiply(higher_dims, shape_multipliers), reduction_indices=[1]) flat_indices = math_ops.add(flat_indices, offsets) values = array_ops.gather(flat_tensor, flat_indices) return sparse_tensor.SparseTensor(indices, values, dense_shape)
def _make_csv_dataset(self, filenames, defaults, label_key=LABEL, batch_size=1, num_epochs=1, shuffle=False, shuffle_seed=None): return readers.make_csv_dataset( filenames, column_keys=self.COLUMNS, column_defaults=defaults, label_key=label_key, batch_size=batch_size, num_epochs=num_epochs, shuffle=shuffle, shuffle_seed=shuffle_seed, skip=1, filter_fn= lambda line: math_ops.not_equal(string_ops.substr(line, 0, 1), "#"), )
def _assert_sparse_indices_are_ragged_right(indices): """Checks that the given SparseTensor.indices tensor is ragged-right. Example: `indices = [[0, 0], [0, 1], [2, 0], [3, 1]]` is not ragged right because the entry `[3, 1]` skips a cell. Args: indices: The SparseTensor indices to check. Returns: A list of control dependency op tensors. """ index_prefix = indices[:, :-1] index_suffix = indices[:, -1] # Check whether each index is starting a new row in the innermost dimension # (prefix[i] != prefix[i-1]) or continuing a row (prefix[i] == prefix[i-1]). # (Note: this skips the first index; we will check that separately below.) index_prefix_changed = math_ops.reduce_any( math_ops.not_equal(index_prefix[1:], index_prefix[:-1]), axis=1) # Check two cases: # * For indices that start a new row: index_suffix[i] must be zero. # * For indices that continue a row: index_suffix[i] must be equal to # index_suffix[i-1]+1. index_ok = array_ops.where( index_prefix_changed, math_ops.equal(index_suffix[1:], 0), math_ops.equal(index_suffix[1:], index_suffix[:-1] + 1)) # Also check that the very first index didn't skip any cells. The first # index starts a new row (by definition), so its suffix should be zero. sparse_indices_are_ragged_right = math_ops.logical_and( math_ops.reduce_all(math_ops.equal(index_suffix[:1], 0)), math_ops.reduce_all(index_ok)) message = [ 'SparseTensor is not right-ragged', 'SparseTensor.indices =', indices ] return [control_flow_ops.Assert(sparse_indices_are_ragged_right, message)]
def _build_filter_range_graph(self, div): return dataset_ops.Dataset.range(100).filter( lambda x: math_ops.not_equal(math_ops.mod(x, div), 2))
def filter_fn(line): return math_ops.not_equal(string_ops.substr(line, 0, 1), comment)
def predict(self, mode): """Returns predictions given the features and mode. Args: mode: Mode the graph is running in (train|predict|eval). Returns: A dict of predictions tensors. Raises: ValueError: if features is not valid. """ # Use the current ensemble to predict on the current batch of input. # For faster prediction we check if the inputs are on the same device # as the model. If not, we create a copy of the model on the worker. input_deps = (self._dense_floats + self._sparse_float_indices + self._sparse_int_indices) if not input_deps: raise ValueError("No input tensors for prediction.") if any(i.device != input_deps[0].device for i in input_deps): raise ValueError("All input tensors should be on the same device.") # Get most current model stamp. ensemble_stamp = model_ops.tree_ensemble_stamp_token(self._ensemble_handle) # Determine if ensemble is colocated with the inputs. if self._ensemble_handle.device != input_deps[0].device: # Create a local ensemble and get its local stamp. with ops.name_scope("local_ensemble", "TreeEnsembleVariable") as name: local_ensemble_handle = ( gen_model_ops.decision_tree_ensemble_resource_handle_op(name=name)) create_op = gen_model_ops.create_tree_ensemble_variable( local_ensemble_handle, stamp_token=-1, tree_ensemble_config="") with ops.control_dependencies([create_op]): local_stamp = model_ops.tree_ensemble_stamp_token( local_ensemble_handle) # Determine whether the local ensemble is stale and update it if needed. def _refresh_local_ensemble_fn(): # Serialize the model from parameter server after reading all inputs. with ops.control_dependencies(input_deps): (ensemble_stamp, serialized_model) = ( model_ops.tree_ensemble_serialize(self._ensemble_handle)) # Update local ensemble with the serialized model from parameter server. with ops.control_dependencies([create_op]): return model_ops.tree_ensemble_deserialize( local_ensemble_handle, stamp_token=ensemble_stamp, tree_ensemble_config=serialized_model), ensemble_stamp refresh_local_ensemble, ensemble_stamp = control_flow_ops.cond( math_ops.not_equal(ensemble_stamp, local_stamp), _refresh_local_ensemble_fn, lambda: (control_flow_ops.no_op(), ensemble_stamp)) # Once updated, use the local model for prediction. with ops.control_dependencies([refresh_local_ensemble]): return self._predict_and_return_dict(local_ensemble_handle, ensemble_stamp, mode) else: # Use ensemble_handle directly, if colocated. with ops.device(self._ensemble_handle.device): return self._predict_and_return_dict(self._ensemble_handle, ensemble_stamp, mode)
def call(self, inputs): boolean_mask = K.any( math_ops.not_equal(inputs, self.mask_value), axis=-1, keepdims=True) return inputs * math_ops.cast(boolean_mask, inputs.dtype)
def compute_mask(self, inputs, mask=None): return K.any(math_ops.not_equal(inputs, self.mask_value), axis=-1)
def stratified_sample(tensors, labels, target_probs, batch_size, init_probs=None, enqueue_many=False, queue_capacity=16, threads_per_queue=1, name=None): """Stochastically creates batches based on per-class probabilities. This method discards examples. Internally, it creates one queue to amortize the cost of disk reads, and one queue to hold the properly-proportioned batch. See `stratified_sample_unknown_dist` for a function that performs stratified sampling with one queue per class and doesn't require knowing the class data-distribution ahead of time. Args: tensors: List of tensors for data. All tensors are either one item or a batch, according to enqueue_many. labels: Tensor for label of data. Label is a single integer or a batch, depending on enqueue_many. It is not a one-hot vector. target_probs: Target class proportions in batch. An object whose type has a registered Tensor conversion function. batch_size: Size of batch to be returned. init_probs: Class proportions in the data. An object whose type has a registered Tensor conversion function, or `None` for estimating the initial distribution. enqueue_many: Bool. If true, interpret input tensors as having a batch dimension. queue_capacity: Capacity of the large queue that holds input examples. threads_per_queue: Number of threads for the large queue that holds input examples and for the final queue with the proper class proportions. name: Optional prefix for ops created by this function. Raises: ValueError: enqueue_many is True and labels doesn't have a batch dimension, or if enqueue_many is False and labels isn't a scalar. ValueError: enqueue_many is True, and batch dimension on data and labels don't match. ValueError: if probs don't sum to one. ValueError: if a zero initial probability class has a nonzero target probability. TFAssertion: if labels aren't integers in [0, num classes). Returns: (data_batch, label_batch), where data_batch is a list of tensors of the same length as `tensors` Example: # Get tensor for a single data and label example. data, label = data_provider.Get(['data', 'label']) # Get stratified batch according to per-class probabilities. target_probs = [...distribution you want...] [data_batch], labels = tf.contrib.training.stratified_sample( [data], label, target_probs) # Run batch through network. ... """ with ops.name_scope(name, 'stratified_sample', tensors + [labels]): tensor_list = ops.convert_n_to_tensor_or_indexed_slices(tensors) labels = ops.convert_to_tensor(labels) target_probs = ops.convert_to_tensor(target_probs, dtype=dtypes.float32) # Reduce the case of a single example to that of a batch of size 1. if not enqueue_many: tensor_list = [array_ops.expand_dims(tensor, 0) for tensor in tensor_list] labels = array_ops.expand_dims(labels, 0) # If `init_probs` is `None`, set up online estimation of data distribution. if init_probs is None: # We use `target_probs` to get the number of classes, so its shape must be # fully defined at graph construction time. target_probs.get_shape().assert_is_fully_defined() init_probs = _estimate_data_distribution( labels, target_probs.get_shape().num_elements()) else: init_probs = ops.convert_to_tensor(init_probs, dtype=dtypes.float32) # Validate that input is consistent. tensor_list, labels, [init_probs, target_probs] = _verify_input( tensor_list, labels, [init_probs, target_probs]) # Check that all zero initial probabilities also have zero target # probabilities. assert_op = control_flow_ops.Assert( math_ops.reduce_all(math_ops.logical_or( math_ops.not_equal(init_probs, 0), math_ops.equal(target_probs, 0))), ['All classes with zero initial probability must also have zero target ' 'probability: ', init_probs, target_probs]) init_probs = control_flow_ops.with_dependencies([assert_op], init_probs) # Calculate acceptance sampling probabilities. accept_probs = _calculate_acceptance_probabilities(init_probs, target_probs) proportion_rejected = math_ops.reduce_sum((1 - accept_probs) * init_probs) accept_probs = control_flow_ops.cond( math_ops.less(proportion_rejected, .5), lambda: accept_probs, lambda: logging_ops.Print( # pylint: disable=g-long-lambda accept_probs, [accept_probs], message='Proportion of examples rejected by sampler is high.', first_n=10)) # Make a single queue to hold input examples. Reshape output so examples # don't have singleton batch dimension. batched = input_ops.batch(tensor_list + [labels], batch_size=1, num_threads=threads_per_queue, capacity=queue_capacity, enqueue_many=True) val_list = [array_ops.squeeze(x, [0]) for x in batched[:-1]] label = array_ops.squeeze(batched[-1], [0]) # Set up second queue containing batches that have the desired class # proportions. cur_prob = array_ops.gather(accept_probs, label) keep_input = random_ops.random_uniform([]) < cur_prob batched = _conditional_batch( val_list + [label], keep_input, batch_size, num_threads=threads_per_queue) return batched[:-1], batched[-1]
def compute_mask(self, inputs, mask=None): if not self.mask_zero: return None return math_ops.not_equal(inputs, 0)
def predict(self, mode): """Returns predictions given the features and mode. Args: mode: Mode the graph is running in (train|predict|eval). Returns: A dict of predictions tensors. Raises: ValueError: if features is not valid. """ apply_averaging = mode != learn.ModeKeys.TRAIN # Use the current ensemble to predict on the current batch of input. # For faster prediction we check if the inputs are on the same device # as the model. If not, we create a copy of the model on the worker. input_deps = (self._dense_floats + self._sparse_float_indices + self._sparse_int_indices) if not input_deps: raise ValueError("No input tensors for prediction.") if any(i.device != input_deps[0].device for i in input_deps): raise ValueError("All input tensors should be on the same device.") # Get most current model stamp. ensemble_stamp = model_ops.tree_ensemble_stamp_token(self._ensemble_handle) # Determine if ensemble is colocated with the inputs. if self._ensemble_handle.device != input_deps[0].device: # Create a local ensemble and get its local stamp. with ops.name_scope("local_ensemble", "TreeEnsembleVariable") as name: local_ensemble_handle = ( gen_model_ops.decision_tree_ensemble_resource_handle_op(name=name)) create_op = gen_model_ops.create_tree_ensemble_variable( local_ensemble_handle, stamp_token=-1, tree_ensemble_config="") with ops.control_dependencies([create_op]): local_stamp = model_ops.tree_ensemble_stamp_token( local_ensemble_handle) # Determine whether the local ensemble is stale and update it if needed. def _refresh_local_ensemble_fn(): # Serialize the model from parameter server after reading all inputs. with ops.control_dependencies(input_deps): (ensemble_stamp, serialized_model) = ( model_ops.tree_ensemble_serialize(self._ensemble_handle)) # Update local ensemble with the serialized model from parameter server. with ops.control_dependencies([create_op]): return model_ops.tree_ensemble_deserialize( local_ensemble_handle, stamp_token=ensemble_stamp, tree_ensemble_config=serialized_model), ensemble_stamp refresh_local_ensemble, ensemble_stamp = control_flow_ops.cond( math_ops.not_equal(ensemble_stamp, local_stamp), _refresh_local_ensemble_fn, lambda: (control_flow_ops.no_op(), ensemble_stamp)) # Once updated, Use the the local model for prediction. with ops.control_dependencies([refresh_local_ensemble]): ensemble_stats = training_ops.tree_ensemble_stats( local_ensemble_handle, ensemble_stamp) apply_dropout, seed = _dropout_params(mode, ensemble_stats) # We don't need dropout info - we can always restore it based on the # seed. predictions, predictions_no_dropout, _ = ( prediction_ops.gradient_trees_prediction( local_ensemble_handle, seed, self._dense_floats, self._sparse_float_indices, self._sparse_float_values, self._sparse_float_shapes, self._sparse_int_indices, self._sparse_int_values, self._sparse_int_shapes, learner_config=self._learner_config_serialized, apply_dropout=apply_dropout, apply_averaging=apply_averaging, use_locking=False, center_bias=self._center_bias, reduce_dim=self._reduce_dim)) partition_ids = prediction_ops.gradient_trees_partition_examples( local_ensemble_handle, self._dense_floats, self._sparse_float_indices, self._sparse_float_values, self._sparse_float_shapes, self._sparse_int_indices, self._sparse_int_values, self._sparse_int_shapes, use_locking=False) else: with ops.device(self._ensemble_handle.device): ensemble_stats = training_ops.tree_ensemble_stats( self._ensemble_handle, ensemble_stamp) apply_dropout, seed = _dropout_params(mode, ensemble_stats) # We don't need dropout info - we can always restore it based on the # seed. predictions, predictions_no_dropout, _ = ( prediction_ops.gradient_trees_prediction( self._ensemble_handle, seed, self._dense_floats, self._sparse_float_indices, self._sparse_float_values, self._sparse_float_shapes, self._sparse_int_indices, self._sparse_int_values, self._sparse_int_shapes, learner_config=self._learner_config_serialized, apply_dropout=apply_dropout, apply_averaging=apply_averaging, use_locking=False, center_bias=self._center_bias, reduce_dim=self._reduce_dim)) partition_ids = prediction_ops.gradient_trees_partition_examples( self._ensemble_handle, self._dense_floats, self._sparse_float_indices, self._sparse_float_values, self._sparse_float_shapes, self._sparse_int_indices, self._sparse_int_values, self._sparse_int_shapes, use_locking=False) return _make_predictions_dict(ensemble_stamp, predictions, predictions_no_dropout, partition_ids, ensemble_stats)