我们从Python开源项目中,提取了以下43个代码示例,用于说明如何使用tensorflow.python.ops.math_ops.div()。
def inference_graph(self, input_data, data_spec=None): """Constructs a TF graph for evaluating a random forest. Args: input_data: A tensor or SparseTensor or placeholder for input data. data_spec: A list of tf.dtype values specifying the original types of each column. Returns: The last op in the random forest inference graph. """ data_spec = [constants.DATA_FLOAT] if data_spec is None else data_spec probabilities = [] for i in range(self.params.num_trees): with ops.device(self.device_assigner.get_device(i)): tree_data = input_data if self.params.bagged_features: tree_data = self._bag_features(i, input_data) probabilities.append(self.trees[i].inference_graph(tree_data, data_spec)) with ops.device(self.device_assigner.get_device(0)): all_predict = array_ops.pack(probabilities) return math_ops.div( math_ops.reduce_sum(all_predict, 0), self.params.num_trees, name='probabilities')
def _safe_div(numerator, denominator, name="value"): """Computes a safe divide which returns 0 if the denominator is zero. Note that the function contains an additional conditional check that is necessary for avoiding situations where the loss is zero causing NaNs to creep into the gradient computation. Args: numerator: An arbitrary `Tensor`. denominator: A `Tensor` whose shape matches `numerator` and whose values are assumed to be non-negative. name: An optional name for the returned op. Returns: The element-wise value of the numerator divided by the denominator. """ return math_ops.select( math_ops.greater(denominator, 0), math_ops.div(numerator, math_ops.select( math_ops.equal(denominator, 0), array_ops.ones_like(denominator), denominator)), array_ops.zeros_like(numerator), name=name)
def _rescale_eval_loss(loss, weights): """Rescales evaluation loss according to the given weights. The rescaling is needed because in the training loss weights are not considered in the denominator, whereas for the evaluation loss we should divide by the sum of weights. The rescaling factor is: R = sum_{i} 1 / sum_{i} w_{i} Args: loss: the scalar weighted loss. weights: weight coefficients. Either a scalar, or a `Tensor` of shape [batch_size]. Returns: The given loss multiplied by the rescaling factor. """ rescaling_factor = math_ops.reduce_mean(weights) return math_ops.div(loss, rescaling_factor)
def _safe_scalar_div(numerator, denominator, name): """Divides two values, returning 0 if the denominator is != 0. Args: numerator: A scalar `float64` `Tensor`. denominator: A scalar `float64` `Tensor`. name: Name for the returned op. Returns: 0 if `denominator` == 0, else `numerator` / `denominator` """ numerator.get_shape().with_rank_at_most(1) denominator.get_shape().with_rank_at_most(1) return control_flow_ops.cond( math_ops.equal( array_ops.constant(0.0, dtype=dtypes.float64), denominator), lambda: array_ops.constant(0.0, dtype=dtypes.float64), lambda: math_ops.div(numerator, denominator), name=name)
def _safe_scalar_div(numerator, denominator, name): """Divides two values, returning 0 if the denominator is 0. Args: numerator: A scalar `float64` `Tensor`. denominator: A scalar `float64` `Tensor`. name: Name for the returned op. Returns: 0 if `denominator` == 0, else `numerator` / `denominator` """ numerator.get_shape().with_rank_at_most(1) denominator.get_shape().with_rank_at_most(1) return control_flow_ops.cond( math_ops.equal( array_ops.constant(0.0, dtype=dtypes.float64), denominator), lambda: array_ops.constant(0.0, dtype=dtypes.float64), lambda: math_ops.div(numerator, denominator), name=name)
def __call__(self, inputs, state, scope=None): """Gated recurrent unit (GRU) with nunits cells.""" with vs.variable_scope(scope or type(self).__name__): # "GRUCell" with vs.variable_scope("Gates"): # Reset gate and update gate. # We start with bias of 1.0 to not reset and not update. r, u, g = array_ops.split(1, 3, _linear([inputs, state], 3 * self._num_units, True, 1.0)) r, u, g = sigmoid(r), sigmoid(u), sigmoid(g) with vs.variable_scope("Candidate"): c = self._activation(_linear([inputs, r * state], self._num_units, True)) new_h = u * state + (1 - u) * c eps = 1e-13 temp = math_ops.div(math_ops.reduce_sum(math_ops.mul(new_h, state),1), \ math_ops.reduce_sum(math_ops.mul(state,state),1) + eps) m = array_ops.transpose(g) t1 = math_ops.mul(m , temp) t1 = array_ops.transpose(t1) distract_h = new_h - state * t1 return distract_h, distract_h
def _safe_div(numerator, denominator, name="value"): """Computes a safe divide which returns 0 if the denominator is zero. Note that the function contains an additional conditional check that is necessary for avoiding situations where the loss is zero causing NaNs to creep into the gradient computation. Args: numerator: An arbitrary `Tensor`. denominator: A `Tensor` whose shape matches `numerator` and whose values are assumed to be non-negative. name: An optional name for the returned op. Returns: The element-wise value of the numerator divided by the denominator. """ return array_ops.where( math_ops.greater(denominator, 0), math_ops.div(numerator, array_ops.where( math_ops.equal(denominator, 0), array_ops.ones_like(denominator), denominator)), array_ops.zeros_like(numerator), name=name)
def _optimal_step_size(last_step, error_ratio, safety=0.9, ifactor=10.0, dfactor=0.2, order=5, name=None): """Calculate the optimal size for the next Runge-Kutta step.""" with ops.name_scope( name, 'optimal_step_size', [last_step, error_ratio]) as scope: error_ratio = math_ops.cast(error_ratio, last_step.dtype) exponent = math_ops.cast(1 / order, last_step.dtype) # this looks more complex than necessary, but importantly it keeps # error_ratio in the numerator so we can't divide by zero: factor = math_ops.maximum( 1 / ifactor, math_ops.minimum(error_ratio ** exponent / safety, 1 / dfactor)) return math_ops.div(last_step, factor, name=scope)
def _sample_n(self, n, seed=None): sample_shape = array_ops.concat(([n], array_ops.shape(self.logits)), 0) logits = self.logits * array_ops.ones(sample_shape) if logits.get_shape().ndims == 2: logits_2d = logits else: logits_2d = array_ops.reshape(logits, [-1, self.event_size]) np_dtype = self.dtype.as_numpy_dtype() minval = np.nextafter(np_dtype(0), np_dtype(1)) uniform = random_ops.random_uniform(shape=array_ops.shape(logits_2d), minval=minval, maxval=1, dtype=self.dtype, seed=seed) gumbel = - math_ops.log(- math_ops.log(uniform)) noisy_logits = math_ops.div(gumbel + logits_2d, self.temperature) samples = nn_ops.log_softmax(noisy_logits) ret = array_ops.reshape(samples, sample_shape) return ret
def _testDivision(self, dtype): """Test cases for division operators.""" self._testBinary( math_ops.div, np.array([10, 20], dtype=dtype), np.array([10, 2], dtype=dtype), expected=np.array([1, 10], dtype=dtype)) self._testBinary( math_ops.div, dtype(40), np.array([2, 20], dtype=dtype), expected=np.array([20, 2], dtype=dtype)) self._testBinary( math_ops.div, np.array([[10], [4]], dtype=dtype), dtype(2), expected=np.array([[5], [2]], dtype=dtype)) self._testBinary( gen_math_ops._floor_div, np.array([3, 3, -1, -9, -8], dtype=dtype), np.array([2, -2, 7, 2, -4], dtype=dtype), expected=np.array([1, -2, -1, -5, 2], dtype=dtype))
def _input_dropout(self,inputs): # This implementation of dropout dropouts an entire feature along the time dim random_tensor = self._keep_prob random_tensor += random_ops.random_uniform([self._batch_size,self._num_inputs], dtype=inputs.dtype) random_tensor = tf.tile(random_tensor,[1,self._num_unrollings]) binary_tensor = math_ops.floor(random_tensor) ret = math_ops.div(inputs, self._keep_prob) * binary_tensor ret.set_shape(inputs.get_shape()) return ret
def _weighted_loss(loss, weight_tensor): unweighted_loss = array_ops.reshape(loss, shape=(-1,)) weighted_loss = math_ops.mul( unweighted_loss, array_ops.reshape(weight_tensor, shape=(-1,))) return math_ops.div( math_ops.reduce_sum(weighted_loss), math_ops.to_float(math_ops.reduce_sum(weight_tensor)), name="loss")
def unit_norm(inputs, dim, epsilon=1e-7, scope=None): """Normalizes the given input across the specified dimension to unit length. Note that the rank of `input` must be known. Args: inputs: A `Tensor` of arbitrary size. dim: The dimension along which the input is normalized. epsilon: A small value to add to the inputs to avoid dividing by zero. scope: Optional scope for variable_scope. Returns: The normalized `Tensor`. Raises: ValueError: If dim is smaller than the number of dimensions in 'inputs'. """ with variable_scope.variable_scope(scope, 'UnitNorm', [inputs]): if not inputs.get_shape(): raise ValueError('The input rank must be known.') input_rank = len(inputs.get_shape().as_list()) if dim < 0 or dim >= input_rank: raise ValueError( 'dim must be positive but smaller than the input rank.') lengths = math_ops.sqrt(epsilon + math_ops.reduce_sum( math_ops.square(inputs), dim, True)) multiples = [] if dim > 0: multiples.append(array_ops.ones([dim], dtypes.int32)) multiples.append(array_ops.slice(array_ops.shape(inputs), [dim], [1])) if dim < (input_rank - 1): multiples.append(array_ops.ones([input_rank - 1 - dim], dtypes.int32)) multiples = array_ops.concat(0, multiples) return math_ops.div(inputs, array_ops.tile(lengths, multiples))
def inference_graph(self, input_data, data_spec=None, **inference_args): """Constructs a TF graph for evaluating a random forest. Args: input_data: A tensor or SparseTensor or placeholder for input data. data_spec: A list of tf.dtype values specifying the original types of each column. **inference_args: Keyword arguments to pass through to each tree. Returns: The last op in the random forest inference graph. """ data_spec = [constants.DATA_FLOAT] if data_spec is None else data_spec probabilities = [] for i in range(self.params.num_trees): with ops.device(self.device_assigner.get_device(i)): tree_data = input_data if self.params.bagged_features: tree_data = self._bag_features(i, input_data) probabilities.append(self.trees[i].inference_graph( tree_data, data_spec, **inference_args)) with ops.device(self.device_assigner.get_device(0)): all_predict = array_ops.pack(probabilities) return math_ops.div( math_ops.reduce_sum(all_predict, 0), self.params.num_trees, name='probabilities')
def _loss(loss_unweighted, weight, name): """Returns loss.""" if weight is None: loss = math_ops.reduce_mean(loss_unweighted, name=name) return loss, loss else: loss_weighted = _weighted_loss(loss_unweighted, weight) weighted_average_loss = math_ops.div( math_ops.reduce_sum(loss_weighted), math_ops.to_float(math_ops.reduce_sum(weight)), name="weighted_average_loss") loss = math_ops.reduce_mean(loss_weighted, name=name) return loss, weighted_average_loss
def loss(self, logits, target, features): """Returns loss tensor for this head. The loss returned is the weighted average. L = sum_{i} w_{i} * l_{i} / sum_{i} w_{i} Args: logits: logits, a float tensor. target: either a tensor for labels or in multihead case, a dict of string to target tensor. features: features dict. Returns: Loss tensor. """ target = target[self.name] if isinstance(target, dict) else target loss_unweighted = self._loss_fn(logits, target) weight_tensor = self.get_weight_tensor(features) if weight_tensor is None: return math_ops.reduce_mean(loss_unweighted, name="loss") loss_weighted = self._weighted_loss(loss_unweighted, weight_tensor) return math_ops.div( math_ops.reduce_sum(loss_weighted), math_ops.to_float(math_ops.reduce_sum(weight_tensor)), name="loss")
def accuracy(predictions, labels, weights=None): """Computes the percentage of times that predictions matches labels. Args: predictions: the predicted values, a `Tensor` whose dtype and shape matches 'labels'. labels: the ground truth values, a `Tensor` of any shape and bool, integer, or string dtype. weights: None or `Tensor` of float values to reweight the accuracy. Returns: Accuracy `Tensor`. Raises: ValueError: if dtypes don't match or if dtype is not bool, integer, or string. """ if not (labels.dtype.is_integer or labels.dtype in (dtypes.bool, dtypes.string)): raise ValueError( 'Labels should have bool, integer, or string dtype, not %r' % labels.dtype) if not labels.dtype.is_compatible_with(predictions.dtype): raise ValueError('Dtypes of predictions and labels should match. ' 'Given: predictions (%r) and labels (%r)' % (predictions.dtype, labels.dtype)) with ops.name_scope('accuracy', values=[predictions, labels]): is_correct = math_ops.cast( math_ops.equal(predictions, labels), dtypes.float32) if weights is not None: is_correct = math_ops.mul(is_correct, weights) num_values = math_ops.mul(weights, array_ops.ones_like(is_correct)) return math_ops.div(math_ops.reduce_sum(is_correct), math_ops.reduce_sum(num_values)) return math_ops.reduce_mean(is_correct)
def __truediv__(self, other): return div(self, other)
def __rtruediv__(self, other): return div(other, self)
def __call__(self, inputs, state, scope=None): """Run the cell with the declared dropouts.""" output, state = self._cell(inputs, state, scope) (c, h) = state with tf.name_scope("Dropout"): if (isinstance(self._output_keep_prob, float) and self._output_keep_prob == 1): return new_h_out = math_ops.div(h, self._output_keep_prob) * self._output_mask new_h_fb = math_ops.div(h, self._state_keep_prob) * self._state_mask new_state = core_rnn_cell.LSTMStateTuple(c, new_h_fb) return new_h_out, new_state
def __call__(self, inputs, state, scope=None): """Gated recurrent unit (GRU) with nunits cells.""" with vs.variable_scope(scope or type(self).__name__): # "GRUCell" with vs.variable_scope("Gates"): # Reset gate and update gate. # We start with bias of 1.0 to not reset and not update. r, u = array_ops.split(1, 2, _linear([inputs, state], 2 * self._num_units, True, 1.0)) r, u = sigmoid(r), sigmoid(u) with vs.variable_scope("Candidate"): c = self._activation(_linear([inputs, r * state], self._num_units, True)) new_h = u * state + (1 - u) * c eps = 1e-13 temp = math_ops.div(math_ops.reduce_sum(math_ops.mul(new_h, state), 1), \ math_ops.reduce_sum(math_ops.mul(state,state), 1) + eps) dummy = array_ops.transpose(state) t1 = math_ops.mul(dummy, temp) t1 = array_ops.transpose(t1) distract_h = new_h - state * t1 return distract_h, distract_h
def __call__(self, inputs, state, scope=None): """Long short-term memory cell (LSTM).""" with vs.variable_scope(scope or type(self).__name__): # Parameters of gates are concatenated into one multiply for efficiency. if self._state_is_tuple: c, h = state else: c, h = array_ops.split(1, 2, state) concat = _linear([inputs, h], 5 * self._num_units, True) # i = input_gate, j = new_input, f = forget_gate, o = output_gate, g= distract_gate i, j, f, o, g = array_ops.split(1, 5, concat) new_c = (c * sigmoid(f + self._forget_bias) + sigmoid(i) * self._activation(j)) eps = 1e-13 temp = math_ops.div(math_ops.reduce_sum(math_ops.mul(c, new_c),1),math_ops.reduce_sum(math_ops.mul(c,c),1) + eps) m = array_ops.transpose(sigmoid(g)) t1 = math_ops.mul(m , temp) t1 = array_ops.transpose(t1) distract_c = new_c - c * t1 new_h = self._activation(distract_c) * sigmoid(o) if self._state_is_tuple: new_state = LSTMStateTuple(new_c, new_h) else: new_state = array_ops.concat(1, [new_c, new_h]) return new_h, new_state
def __call__(self, inputs, state, scope=None): """Long short-term memory cell (LSTM).""" with vs.variable_scope(scope or type(self).__name__): # Parameters of gates are concatenated into one multiply for efficiency. if self._state_is_tuple: c, h = state else: c, h = array_ops.split(1, 2, state) concat = _linear([inputs, h], 4 * self._num_units, True) # i = input_gate, j = new_input, f = forget_gate, o = output_gate i, j, f, o = array_ops.split(1, 4, concat) new_c = (c * sigmoid(f + self._forget_bias) + sigmoid(i) * self._activation(j)) eps = 1e-13 temp = math_ops.div(math_ops.reduce_sum(math_ops.mul(c, new_c),1),math_ops.reduce_sum(math_ops.mul(c,c),1) + eps) dummy = array_ops.transpose(c) t1 = math_ops.mul(dummy, temp) t1 = array_ops.transpose(t1) distract_c = new_c - t1 new_h = self._activation(distract_c) * sigmoid(o) if self._state_is_tuple: new_state = LSTMStateTuple(new_c, new_h) else: new_state = array_ops.concat(1, [new_c, new_h]) return new_h, new_state
def unit_norm(inputs, dim, epsilon=1e-7, scope=None): """Normalizes the given input across the specified dimension to unit length. Note that the rank of `input` must be known. Args: inputs: A `Tensor` of arbitrary size. dim: The dimension along which the input is normalized. epsilon: A small value to add to the inputs to avoid dividing by zero. scope: Optional scope for variable_scope. Returns: The normalized `Tensor`. Raises: ValueError: If dim is smaller than the number of dimensions in 'inputs'. """ with variable_scope.variable_scope(scope, 'UnitNorm', [inputs]): if not inputs.get_shape(): raise ValueError('The input rank must be known.') input_rank = len(inputs.get_shape().as_list()) if dim < 0 or dim >= input_rank: raise ValueError( 'dim must be positive but smaller than the input rank.') lengths = math_ops.sqrt(epsilon + math_ops.reduce_sum( math_ops.square(inputs), dim, True)) multiples = [] if dim > 0: multiples.append(array_ops.ones([dim], dtypes.int32)) multiples.append( array_ops.strided_slice(array_ops.shape(inputs), [dim], [dim + 1])) if dim < (input_rank - 1): multiples.append(array_ops.ones([input_rank - 1 - dim], dtypes.int32)) multiples = array_ops.concat(multiples, 0) return math_ops.div(inputs, array_ops.tile(lengths, multiples))
def _loss(loss_unweighted, weight, name): """Returns a tuple of (loss, weighted_average_loss).""" with ops.name_scope(name, values=(loss_unweighted, weight)) as name_scope: if weight is None: loss = math_ops.reduce_mean(loss_unweighted, name=name_scope) return loss, loss loss_weighted = _weighted_loss(loss_unweighted, weight) # TODO(ptucker): This might be wrong if weights are broadcast to loss shape. # We should use tf.losses here. weighted_average_loss = math_ops.div( math_ops.reduce_sum(loss_weighted), math_ops.to_float(math_ops.reduce_sum(weight)), name="weighted_average_loss") loss = math_ops.reduce_mean(loss_weighted, name=name_scope) return loss, weighted_average_loss
def accuracy(predictions, labels, weights=None): """Computes the percentage of times that predictions matches labels. Args: predictions: the predicted values, a `Tensor` whose dtype and shape matches 'labels'. labels: the ground truth values, a `Tensor` of any shape and bool, integer, or string dtype. weights: None or `Tensor` of float values to reweight the accuracy. Returns: Accuracy `Tensor`. Raises: ValueError: if dtypes don't match or if dtype is not bool, integer, or string. """ if not (labels.dtype.is_integer or labels.dtype in (dtypes.bool, dtypes.string)): raise ValueError( 'Labels should have bool, integer, or string dtype, not %r' % labels.dtype) if not labels.dtype.is_compatible_with(predictions.dtype): raise ValueError('Dtypes of predictions and labels should match. ' 'Given: predictions (%r) and labels (%r)' % (predictions.dtype, labels.dtype)) with ops.name_scope('accuracy', values=[predictions, labels]): is_correct = math_ops.cast( math_ops.equal(predictions, labels), dtypes.float32) if weights is not None: is_correct = math_ops.multiply(is_correct, weights) num_values = math_ops.multiply(weights, array_ops.ones_like(is_correct)) return math_ops.div(math_ops.reduce_sum(is_correct), math_ops.reduce_sum(num_values)) return math_ops.reduce_mean(is_correct)
def setUp(self): super(CoreBinaryOpsTest, self).setUp() self.x_probs_broadcast_tensor = array_ops.reshape( self.x_probs_lt.tensor, [self.x_size, 1, self.probs_size]) self.channel_probs_broadcast_tensor = array_ops.reshape( self.channel_probs_lt.tensor, [1, self.channel_size, self.probs_size]) # == and != are not element-wise for tf.Tensor, so they shouldn't be # elementwise for LabeledTensor, either. self.ops = [ ('add', operator.add, math_ops.add, core.add), ('sub', operator.sub, math_ops.subtract, core.sub), ('mul', operator.mul, math_ops.multiply, core.mul), ('div', operator.truediv, math_ops.div, core.div), ('mod', operator.mod, math_ops.mod, core.mod), ('pow', operator.pow, math_ops.pow, core.pow_function), ('equal', None, math_ops.equal, core.equal), ('less', operator.lt, math_ops.less, core.less), ('less_equal', operator.le, math_ops.less_equal, core.less_equal), ('not_equal', None, math_ops.not_equal, core.not_equal), ('greater', operator.gt, math_ops.greater, core.greater), ('greater_equal', operator.ge, math_ops.greater_equal, core.greater_equal), ] self.test_lt_1 = self.x_probs_lt self.test_lt_2 = self.channel_probs_lt self.test_lt_1_broadcast = self.x_probs_broadcast_tensor self.test_lt_2_broadcast = self.channel_probs_broadcast_tensor self.broadcast_axes = [self.a0, self.a1, self.a3]
def _variational_recurrent_dropout_value( self, index, value, noise, keep_prob): """Performs dropout given the pre-calculated noise tensor.""" # uniform [keep_prob, 1.0 + keep_prob) random_tensor = keep_prob + noise # 0. if [keep_prob, 1.0) and 1. if [1.0, 1.0 + keep_prob) binary_tensor = math_ops.floor(random_tensor) ret = math_ops.div(value, keep_prob) * binary_tensor ret.set_shape(value.get_shape()) return ret
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 streaming_mean_relative_error(predictions, labels, normalizer, weights=None, metrics_collections=None, updates_collections=None, name=None): """Computes the mean relative error by normalizing with the given values. The `streaming_mean_relative_error` function creates two local variables, `total` and `count` that are used to compute the mean relative absolute error. This average is weighted by `weights`, and it is ultimately returned as `mean_relative_error`: an idempotent operation that simply divides `total` by `count`. For estimation of the metric over a stream of data, the function creates an `update_op` operation that updates these variables and returns the `mean_reative_error`. Internally, a `relative_errors` operation divides the absolute value of the differences between `predictions` and `labels` by the `normalizer`. Then `update_op` increments `total` with the reduced sum of the product of `weights` and `relative_errors`, and it increments `count` with the reduced sum of `weights`. If `weights` is `None`, weights default to 1. Use weights of 0 to mask values. Args: predictions: A `Tensor` of arbitrary shape. labels: A `Tensor` of the same shape as `predictions`. normalizer: A `Tensor` of the same shape as `predictions`. weights: An optional `Tensor` whose shape is broadcastable to `predictions`. metrics_collections: An optional list of collections that `mean_relative_error` should be added to. updates_collections: An optional list of collections that `update_op` should be added to. name: An optional variable_scope name. Returns: mean_relative_error: A tensor representing the current mean, the value of `total` divided by `count`. update_op: An operation that increments the `total` and `count` variables appropriately and whose value matches `mean_relative_error`. Raises: ValueError: If `predictions` and `labels` have mismatched shapes, or if `weights` is not `None` and its shape doesn't match `predictions`, or if either `metrics_collections` or `updates_collections` are not a list or tuple. """ predictions, labels = metric_ops_util.remove_squeezable_dimensions( predictions, labels) predictions.get_shape().assert_is_compatible_with(labels.get_shape()) predictions, normalizer = metric_ops_util.remove_squeezable_dimensions( predictions, normalizer) predictions.get_shape().assert_is_compatible_with(normalizer.get_shape()) relative_errors = math_ops.select( math_ops.equal(normalizer, 0.0), array_ops.zeros_like(labels), math_ops.div(math_ops.abs(labels - predictions), normalizer)) return streaming_mean(relative_errors, weights, metrics_collections, updates_collections, name or 'mean_relative_error')
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 size [4, 5], then `weights` 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]. weights: 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. """ # If weights is a scalar, its easy to compute: if weights.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(weights, 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 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.mul(num_nonzero_per_batch, num_to_broadcast) return num_per_batch if per_batch else math_ops.reduce_sum(num_per_batch)
def weighted_moving_average(value, decay, weight, truediv=True, collections=None, name=None): """Compute the weighted moving average of `value`. Conceptually, the weighted moving average is: `moving_average(value * weight) / moving_average(weight)`, where a moving average updates by the rule `new_value = decay * old_value + (1 - decay) * update` Internally, this Op keeps moving average variables of both `value * weight` and `weight`. Args: value: A numeric `Tensor`. decay: A float `Tensor` or float value. The moving average decay. weight: `Tensor` that keeps the current value of a weight. Shape should be able to multiply `value`. truediv: Boolean, if `True`, dividing by `moving_average(weight)` is floating point division. If `False`, use division implied by dtypes. collections: List of graph collections keys to add the internal variables `value * weight` and `weight` to. Defaults to `[GraphKeys.VARIABLES]`. name: Optional name of the returned operation. Defaults to "WeightedMovingAvg". Returns: An Operation that updates and returns the weighted moving average. """ # Unlike assign_moving_average, the weighted moving average doesn't modify # user-visible variables. It is the ratio of two internal variables, which are # moving averages of the updates. Thus, the signature of this function is # quite different than assign_moving_average. if collections is None: collections = [ops.GraphKeys.VARIABLES] with variable_scope.variable_op_scope( [value, weight, decay], name, "WeightedMovingAvg") as scope: value_x_weight_var = variable_scope.get_variable( "value_x_weight", initializer=init_ops.zeros_initializer(value.get_shape(), dtype=value.dtype), trainable=False, collections=collections) weight_var = variable_scope.get_variable( "weight", initializer=init_ops.zeros_initializer(weight.get_shape(), dtype=weight.dtype), trainable=False, collections=collections) numerator = assign_moving_average(value_x_weight_var, value * weight, decay) denominator = assign_moving_average(weight_var, weight, decay) if truediv: return math_ops.truediv(numerator, denominator, name=scope.name) else: return math_ops.div(numerator, denominator, name=scope.name)
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 size [4, 5], then `weights` 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]. weights: 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. """ # If weights is a scalar, its easy to compute: if weights.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 = 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 weights 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 _define_maximization_operation(self, num_batches): """Maximization operations.""" # TODO(xavigonzalvo): some of these operations could be moved to C++. # Compute the effective number of data points assigned to component k. with ops.control_dependencies(self._w): points_in_k = array_ops.squeeze( math_ops.add_n(self._points_in_k), squeeze_dims=[0]) # Update alpha. if 'w' in self._params: final_points_in_k = points_in_k / num_batches num_examples = math_ops.to_float(math_ops.reduce_sum(final_points_in_k)) self._alpha_op = self._alpha.assign(final_points_in_k / (num_examples + MEPS)) else: self._alpha_op = control_flow_ops.no_op() self._train_ops = [self._alpha_op] # Update means. points_in_k_expanded = array_ops.reshape(points_in_k, [self._num_classes, 1, 1]) if 'm' in self._params: self._means_op = self._means.assign( math_ops.div( math_ops.add_n(self._w_mul_x), points_in_k_expanded + MEPS)) else: self._means_op = control_flow_ops.no_op() # means are (num_classes x 1 x dims) # Update covariances. with ops.control_dependencies([self._means_op]): b = math_ops.add_n(self._w_mul_x2) / (points_in_k_expanded + MEPS) new_covs = [] for k in range(self._num_classes): mean = self._means.value()[k, :, :] square_mean = math_ops.matmul(mean, mean, transpose_a=True) new_cov = b[k, :, :] - square_mean + self._min_var if self._covariance_type == FULL_COVARIANCE: new_covs.append(array_ops.expand_dims(new_cov, 0)) elif self._covariance_type == DIAG_COVARIANCE: new_covs.append( array_ops.expand_dims(array_ops.diag_part(new_cov), 0)) new_covs = array_ops.concat(new_covs, 0) if 'c' in self._params: # Train operations don't need to take care of the means # because covariances already depend on it. with ops.control_dependencies([self._means_op, new_covs]): self._train_ops.append( state_ops.assign( self._covs, new_covs, validate_shape=False))