コード例 #1
0
ファイル: batch_reshape.py プロジェクト: Ajaycs99/tensorflow
def calculate_reshape(original_shape, new_shape, validate=False, name=None):
  """Calculates the reshaped dimensions (replacing up to one -1 in reshape)."""
  batch_shape_static = tensor_util.constant_value_as_shape(new_shape)
  if batch_shape_static.is_fully_defined():
    return np.int32(batch_shape_static.as_list()), batch_shape_static, []
  with ops.name_scope(name, "calculate_reshape", [original_shape, new_shape]):
    original_size = math_ops.reduce_prod(original_shape)
    implicit_dim = math_ops.equal(new_shape, -1)
    size_implicit_dim = (
        original_size // math_ops.maximum(1, -math_ops.reduce_prod(new_shape)))
    new_ndims = array_ops.shape(new_shape)
    expanded_new_shape = array_ops.where(  # Assumes exactly one `-1`.
        implicit_dim, array_ops.fill(new_ndims, size_implicit_dim), new_shape)
    validations = [] if not validate else [
        check_ops.assert_rank(
            original_shape, 1, message="Original shape must be a vector."),
        check_ops.assert_rank(
            new_shape, 1, message="New shape must be a vector."),
        check_ops.assert_less_equal(
            math_ops.count_nonzero(implicit_dim, dtype=dtypes.int32),
            1,
            message="At most one dimension can be unknown."),
        check_ops.assert_positive(
            expanded_new_shape, message="Shape elements must be >=-1."),
        check_ops.assert_equal(
            math_ops.reduce_prod(expanded_new_shape),
            original_size,
            message="Shape sizes do not match."),
    ]
    return expanded_new_shape, batch_shape_static, validations
コード例 #2
0
 def test_doesnt_raise_when_less_equal_and_broadcastable_shapes(self):
   with self.test_session():
     small = constant_op.constant([1], name="small")
     big = constant_op.constant([3, 1], name="big")
     with ops.control_dependencies([check_ops.assert_less_equal(small, big)]):
       out = array_ops.identity(small)
     out.eval()
コード例 #3
0
 def test_doesnt_raise_when_equal(self):
   with self.test_session():
     small = constant_op.constant([1, 2], name="small")
     with ops.control_dependencies(
         [check_ops.assert_less_equal(small, small)]):
       out = array_ops.identity(small)
     out.eval()
コード例 #4
0
 def test_doesnt_raise_when_both_empty(self):
   larry = constant_op.constant([])
   curly = constant_op.constant([])
   with ops.control_dependencies(
       [check_ops.assert_less_equal(larry, curly)]):
     out = array_ops.identity(larry)
   self.evaluate(out)
コード例 #5
0
 def test_raises_when_greater(self):
   small = constant_op.constant([1, 2], name="small")
   big = constant_op.constant([3, 4], name="big")
   with self.assertRaisesOpError("fail"):
     with ops.control_dependencies(
         [check_ops.assert_less_equal(
             big, small, message="fail")]):
       out = array_ops.identity(small)
     self.evaluate(out)
コード例 #6
0
ファイル: weibull.py プロジェクト: AbhinavJain13/tensorflow
 def _maybe_assert_valid_y(self, y):
   if not self.validate_args:
     return y
   is_positive = check_ops.assert_non_negative(
       y, message="Inverse transformation input must be greater than 0.")
   less_than_one = check_ops.assert_less_equal(
       y, constant_op.constant(1., y.dtype),
       message="Inverse transformation input must be less than or equal to 1.")
   return control_flow_ops.with_dependencies([is_positive, less_than_one], y)
コード例 #7
0
 def test_raises_when_less_equal_but_non_broadcastable_shapes(self):
   with self.test_session():
     small = constant_op.constant([1, 1, 1], name="small")
     big = constant_op.constant([3, 1], name="big")
     with self.assertRaisesRegexp(ValueError, "must be"):
       with ops.control_dependencies(
           [check_ops.assert_less_equal(small, big)]):
         out = array_ops.identity(small)
       out.eval()
コード例 #8
0
 def check_soundness(ff, fp):
   (sufficient_n1,
    sufficient_n2) = st.min_num_samples_for_dkwm_mean_two_sample_test(
        numbers, 0., 1., 0., 1.,
        false_fail_rate=ff, false_pass_rate=fp)
   d_fn = st.min_discrepancy_of_true_means_detectable_by_dkwm_two_sample
   detectable_d = d_fn(
       sufficient_n1, 0., 1., sufficient_n2, 0., 1.,
       false_fail_rate=ff, false_pass_rate=fp)
   return check_ops.assert_less_equal(detectable_d, numbers)
コード例 #9
0
ファイル: bernoulli.py プロジェクト: LUTAN/tensorflow
 def _maybe_assert_valid_sample(self, event, check_integer=True):
   if not self.validate_args:
     return event
   event = distribution_util.embed_check_nonnegative_discrete(
       event, check_integer=check_integer)
   return control_flow_ops.with_dependencies([
       check_ops.assert_less_equal(
           event, array_ops.ones_like(event),
           message="event is not less than or equal to 1."),
   ], event)
コード例 #10
0
ファイル: reshape.py プロジェクト: Ajaycs99/tensorflow
  def _maybe_check_valid_shape(self, shape, validate_args):
    """Check that a shape Tensor is int-type and otherwise sane."""
    if not shape.dtype.is_integer:
      raise TypeError("{} dtype ({}) should be `int`-like.".format(
          shape, shape.dtype.name))

    assertions = []

    ndims = array_ops.rank(shape)
    ndims_ = tensor_util.constant_value(ndims)
    if ndims_ is not None and ndims_ > 1:
      raise ValueError("`{}` rank ({}) should be <= 1.".format(
          shape, ndims_))
    elif validate_args:
      assertions.append(check_ops.assert_less_equal(
          ndims, 1, message="`{}` rank should be <= 1.".format(shape)))

    shape_ = tensor_util.constant_value_as_shape(shape)
    if shape_.is_fully_defined():
      es = np.int32(shape_.as_list())
      if sum(es == -1) > 1:
        raise ValueError(
            "`{}` must have at most one `-1` (given {})"
            .format(shape, es))
      if np.any(es < -1):
        raise ValueError(
            "`{}` elements must be either positive integers or `-1`"
            "(given {})."
            .format(shape, es))
    elif validate_args:
      assertions.extend([
          check_ops.assert_less_equal(
              math_ops.reduce_sum(
                  math_ops.cast(math_ops.equal(shape, -1), dtypes.int32)),
              1,
              message="`{}` elements must have at most one `-1`."
              .format(shape)),
          check_ops.assert_greater_equal(
              shape, -1,
              message="`{}` elements must be either positive integers or `-1`."
              .format(shape)),
      ])
    return assertions
コード例 #11
0
ファイル: binomial.py プロジェクト: Jackiefan/tensorflow
 def _maybe_assert_valid_sample(self, counts):
   """Check counts for proper shape, values, then return tensor version."""
   if not self.validate_args:
     return counts
   counts = distribution_util.embed_check_nonnegative_integer_form(counts)
   return control_flow_ops.with_dependencies([
       check_ops.assert_less_equal(
           counts, self.total_count,
           message="counts are not less than or equal to n."),
   ], counts)
コード例 #12
0
ファイル: kumaraswamy.py プロジェクト: AndrewTwinz/tensorflow
 def _maybe_assert_valid(self, x):
   if not self.validate_args:
     return x
   return control_flow_ops.with_dependencies([
       check_ops.assert_non_negative(
           x,
           message="sample must be non-negative"),
       check_ops.assert_less_equal(
           x, array_ops.ones([], self.concentration0.dtype),
           message="sample must be no larger than `1`."),
   ], x)
コード例 #13
0
ファイル: binomial.py プロジェクト: ivankreso/tensorflow
 def _check_counts(self, counts):
   counts = ops.convert_to_tensor(counts, name="counts_before_deps")
   if not self.validate_args:
     return counts
   return control_flow_ops.with_dependencies([
       check_ops.assert_non_negative(
           counts, message="counts has negative components."),
       check_ops.assert_less_equal(
           counts, self._n, message="counts are not less than or equal to n."),
       distribution_util.assert_integer_form(
           counts, message="counts have non-integer components.")], counts)
コード例 #14
0
 def test_dkwm_design_mean_one_sample_soundness(self):
   numbers = [1e-5, 1e-2, 1.1e-1, 0.9, 1., 1.02, 2., 10., 1e2, 1e5, 1e10]
   rates = [1e-6, 1e-3, 1e-2, 1.1e-1, 0.2, 0.5, 0.7, 1.]
   with self.test_session() as sess:
     for ff in rates:
       for fp in rates:
         sufficient_n = st.min_num_samples_for_dkwm_mean_test(
             numbers, 0., 1., false_fail_rate=ff, false_pass_rate=fp)
         detectable_d = st.min_discrepancy_of_true_means_detectable_by_dkwm(
             sufficient_n, 0., 1., false_fail_rate=ff, false_pass_rate=fp)
         sess.run(check_ops.assert_less_equal(detectable_d, numbers))
コード例 #15
0
def get_logits_and_prob(
    logits=None, p=None,
    multidimensional=False, validate_args=False, name="GetLogitsAndProb"):
  """Converts logits to probabilities and vice-versa, and returns both.

  Args:
    logits: Numeric `Tensor` representing log-odds.
    p: Numeric `Tensor` representing probabilities.
    multidimensional: Given `p` a [N1, N2, ... k] dimensional tensor,
      whether the last dimension represents the probability between k classes.
      This will additionally assert that the values in the last dimension
      sum to one. If `False`, will instead assert that each value is in
      `[0, 1]`.
    validate_args: `Boolean`, default `False`.  Whether to assert `0 <= p <= 1`
      if multidimensional is `False`, otherwise that the last dimension of `p`
      sums to one.
    name: A name for this operation (optional).

  Returns:
    Tuple with `logits` and `p`. If `p` has an entry that is `0` or `1`, then
    the corresponding entry in the returned logits will be `-Inf` and `Inf`
    respectively.

  Raises:
    ValueError: if neither `p` nor `logits` were passed in, or both were.
  """
  with ops.name_scope(name, values=[p, logits]):
    if p is None and logits is None:
      raise ValueError("Must pass p or logits.")
    elif p is not None and logits is not None:
      raise ValueError("Must pass either p or logits, not both.")
    elif p is None:
      logits = array_ops.identity(logits, name="logits")
      with ops.name_scope("p"):
        p = math_ops.sigmoid(logits)
    elif logits is None:
      with ops.name_scope("p"):
        p = array_ops.identity(p)
        if validate_args:
          one = constant_op.constant(1., p.dtype)
          dependencies = [check_ops.assert_non_negative(p)]
          if multidimensional:
            dependencies += [assert_close(
                math_ops.reduce_sum(p, reduction_indices=[-1]),
                one, message="p does not sum to 1.")]
          else:
            dependencies += [check_ops.assert_less_equal(
                p, one, message="p has components greater than 1.")]
          p = control_flow_ops.with_dependencies(dependencies, p)
      with ops.name_scope("logits"):
        logits = math_ops.log(p) - math_ops.log(1. - p)
    return (logits, p)
コード例 #16
0
 def test_raises_when_less_equal_but_non_broadcastable_shapes(self):
   small = constant_op.constant([3, 1], name="small")
   big = constant_op.constant([1, 1, 1], name="big")
   # The exception in eager and non-eager mode is different because
   # eager mode relies on shape check done as part of the C++ op, while
   # graph mode does shape checks when creating the `Operation` instance.
   with self.assertRaisesRegexp(
       (errors.InvalidArgumentError, ValueError),
       (r"Incompatible shapes: \[2\] vs. \[3\]|"
        r"Dimensions must be equal, but are 2 and 3")):
     with ops.control_dependencies(
         [check_ops.assert_less_equal(small, big)]):
       out = array_ops.identity(small)
     self.evaluate(out)
コード例 #17
0
    def _check_shape(self, shape):
        """Check that the init arg `shape` defines a valid operator."""
        shape = ops.convert_to_tensor(shape, name="shape")
        if not self._verify_pd:
            return shape

        # Further checks are equivalent to verification that this is positive
        # definite.  Why?  Because the further checks simply check that this is a
        # square matrix, and combining the fact that this is square (and thus maps
        # a vector space R^k onto itself), with the behavior of .matmul(), this must
        # be the identity operator.
        rank = array_ops.size(shape)
        assert_matrix = check_ops.assert_less_equal(2, rank)
        with ops.control_dependencies([assert_matrix]):
            last_dim = array_ops.gather(shape, rank - 1)
            second_to_last_dim = array_ops.gather(shape, rank - 2)
            assert_square = check_ops.assert_equal(last_dim, second_to_last_dim)
            return control_flow_ops.with_dependencies([assert_matrix, assert_square], shape)
コード例 #18
0
def _maximum_mean(samples, envelope, high, name=None):
  """Returns a stochastic upper bound on the mean of a scalar distribution.

  The idea is that if the true CDF is within an `eps`-envelope of the
  empirical CDF of the samples, and the support is bounded above, then
  the mean is bounded above as well.  In symbols,

  ```none
  sup_x(|F_n(x) - F(x)|) < eps
  ```

  The 0th dimension of `samples` is interpreted as independent and
  identically distributed samples.  The remaining dimensions are
  broadcast together with `envelope` and `high`, and operated on
  separately.

  Args:
    samples: Floating-point tensor of samples from the distribution(s)
      of interest.  Entries are assumed IID across the 0th dimension.
      The other dimensions must broadcast with `envelope` and `high`.
    envelope: Floating-point tensor of sizes of admissible CDF
      envelopes (i.e., the `eps` above).
    high: Floating-point tensor of upper bounds on the distributions'
      supports.
    name: A name for this operation (optional).

  Returns:
    bound: Floating-point tensor of upper bounds on the true means.

  Raises:
    InvalidArgumentError: If some `sample` is found to be larger than
      the corresponding `high`.
  """
  with ops.name_scope(name, "maximum_mean", [samples, envelope, high]):
    samples = ops.convert_to_tensor(samples, name="samples")
    envelope = ops.convert_to_tensor(envelope, name="envelope")
    high = ops.convert_to_tensor(high, name="high")

    xmax = math_ops.reduce_max(samples, axis=[-1])
    msg = "Given sample maximum value exceeds expectations"
    check_op = check_ops.assert_less_equal(xmax, high, message=msg)
    with ops.control_dependencies([check_op]):
      return array_ops.identity(_do_maximum_mean(samples, envelope, high))
コード例 #19
0
ファイル: independent.py プロジェクト: Crazyonxh/tensorflow
 def _make_runtime_assertions(
     self, distribution, reduce_batch_ndims, validate_args):
   assertions = []
   static_reduce_batch_ndims = tensor_util.constant_value(reduce_batch_ndims)
   batch_ndims = distribution.batch_shape.ndims
   if batch_ndims is not None and static_reduce_batch_ndims is not None:
     if static_reduce_batch_ndims > batch_ndims:
       raise ValueError("reduce_batch_ndims({}) cannot exceed "
                        "distribution.batch_ndims({})".format(
                            static_reduce_batch_ndims, batch_ndims))
   elif validate_args:
     batch_shape = distribution.batch_shape_tensor()
     batch_ndims = (
         batch_shape.shape[0].value
         if batch_shape.shape.with_rank_at_least(1)[0].value is not None
         else array_ops.shape(batch_shape)[0])
     assertions.append(check_ops.assert_less_equal(
         reduce_batch_ndims, batch_ndims,
         message="reduce_batch_ndims cannot exceed distribution.batch_ndims"))
   return assertions
コード例 #20
0
  def _init_clusters_random(self):
    """Does random initialization of clusters.

    Returns:
      Tensor of randomly initialized clusters.
    """
    num_data = math_ops.add_n([array_ops.shape(inp)[0] for inp in self._inputs])
    # Note that for mini-batch k-means, we should ensure that the batch size of
    # data used during initialization is sufficiently large to avoid duplicated
    # clusters.
    with ops.control_dependencies(
        [check_ops.assert_less_equal(self._num_clusters, num_data)]):
      indices = random_ops.random_uniform(
          array_ops.reshape(self._num_clusters, [-1]),
          minval=0,
          maxval=math_ops.cast(num_data, dtypes.int64),
          seed=self._random_seed,
          dtype=dtypes.int64)
      clusters_init = embedding_lookup(
          self._inputs, indices, partition_strategy='div')
      return clusters_init
コード例 #21
0
ファイル: gmm_ops.py プロジェクト: AndreasGocht/tensorflow
def _init_clusters_random(data, num_clusters, random_seed):
  """Does random initialization of clusters.

  Args:
    data: a list of Tensors with a matrix of data, each row is an example.
    num_clusters: an integer with the number of clusters.
    random_seed: Seed for PRNG used to initialize seeds.

  Returns:
    A Tensor with num_clusters random rows of data.
  """
  assert isinstance(data, list)
  num_data = math_ops.add_n([array_ops.shape(inp)[0] for inp in data])
  with ops.control_dependencies(
      [check_ops.assert_less_equal(num_clusters, num_data)]):
    indices = random_ops.random_uniform(
        [num_clusters],
        minval=0,
        maxval=math_ops.cast(num_data, dtypes.int64),
        seed=random_seed,
        dtype=dtypes.int64)
  indices %= math_ops.cast(num_data, dtypes.int64)
  clusters_init = embedding_lookup(data, indices, partition_strategy='div')
  return clusters_init
コード例 #22
0
ファイル: util.py プロジェクト: 1000sprites/tensorflow
def embed_check_integer_casting_closed(
    x,
    target_dtype,
    assert_nonnegative=True,
    name="embed_check_casting_closed"):
  """Ensures integers remain unaffected despite casting to/from int/float types.

  Example integer-types: `uint8`, `int32`, `bool`.
  Example floating-types: `float32`, `float64`.

  The largest possible integer representable by an IEEE754 floating-point is
  `2**(1 + mantissa_bits)` yet the largest possible integer as an int-type is
  `2**(bits - 1) - 1`. This function ensures that a `Tensor` purporting to have
  integer-form values can be cast to some other type without loss of precision.

  The smallest representable integer is the negative of the largest
  representable integer, except for types: `uint8`, `uint16`, `bool`. For these
  types, the smallest representable integer is `0`.

  Args:
    x: `Tensor` representing integer-form values.
    target_dtype: TF `dtype` under which `x` should have identical values.
    assert_nonnegative: `bool` indicating `x` should contain nonnegative values.
    name: A name for this operation (optional).

  Returns:
    x: Input `Tensor` with appropriate assertions embedded.

  Raises:
    TypeError: if `x` is neither integer- nor floating-type.
    TypeError: if `target_dtype` is neither integer- nor floating-type.
    TypeError: if neither `x` nor `target_dtype` are integer-type.
  """

  with ops.name_scope(name, values=[x]):
    x = ops.convert_to_tensor(x, name="x")
    if (not _is_integer_like_by_dtype(x.dtype)
        and not x.dtype.is_floating):
      raise TypeError("{}.dtype must be floating- or "
                      "integer-type.".format(x.dtype.name))
    if (not _is_integer_like_by_dtype(target_dtype)
        and not target_dtype.is_floating):
      raise TypeError("target_dtype ({}) must be floating- or "
                      "integer-type.".format(target_dtype.name))
    if (not _is_integer_like_by_dtype(x.dtype)
        and not _is_integer_like_by_dtype(target_dtype)):
      raise TypeError("At least one of {}.dtype ({}) and target_dtype ({}) "
                      "must be integer-type.".format(
                          x.op.name, x.dtype.name, target_dtype.name))

    assertions = []
    if assert_nonnegative:
      assertions += [
          check_ops.assert_non_negative(
              x, message="Elements must be non-negative."),
      ]

    if x.dtype.is_floating:
      # Being here means _is_integer_like_by_dtype(target_dtype) = True.
      # Since this check implies the magnitude check below, we need only it.
      assertions += [
          assert_integer_form(
              x, int_dtype=target_dtype,
              message="Elements must be {}-equivalent.".format(
                  target_dtype.name)),
      ]
    else:
      if (_largest_integer_by_dtype(x.dtype)
          > _largest_integer_by_dtype(target_dtype)):
        # Cast may lose integer precision.
        assertions += [
            check_ops.assert_less_equal(
                x, _largest_integer_by_dtype(target_dtype),
                message=("Elements cannot exceed {}.".format(
                    _largest_integer_by_dtype(target_dtype)))),
        ]
      if (not assert_nonnegative and
          (_smallest_integer_by_dtype(x.dtype)
           < _smallest_integer_by_dtype(target_dtype))):
        assertions += [
            check_ops.assert_greater_equal(
                x, _smallest_integer_by_dtype(target_dtype),
                message=("Elements cannot be smaller than {}.".format(
                    _smallest_integer_by_dtype(target_dtype)))),
        ]

    if not assertions:
      return x
    return control_flow_ops.with_dependencies(assertions, x)
コード例 #23
0
def _confusion_matrix_at_thresholds(labels,
                                    predictions,
                                    thresholds,
                                    weights=None):
    with ops.control_dependencies([
            check_ops.assert_greater_equal(
                predictions,
                math_ops.cast(0.0, dtype=predictions.dtype),
                message='predictions must be in [0, 1]'),
            check_ops.assert_less_equal(
                predictions,
                math_ops.cast(1.0, dtype=predictions.dtype),
                message='predictions must be in [0, 1]')
    ]):
        predictions, labels, weights = _remove_squeezable_dimensions(
            predictions=math_ops.to_float(predictions),
            labels=math_ops.cast(labels, dtype=dtypes.bool),
            weights=weights)

    num_thresholds = len(thresholds)

    # Reshape predictions and labels.
    predictions_2d = array_ops.reshape(predictions, [-1, 1])
    labels_2d = array_ops.reshape(math_ops.cast(labels, dtype=dtypes.bool),
                                  [1, -1])

    # Use static shape if known.
    num_predictions = predictions_2d.get_shape().as_list()[0]

    # Otherwise use dynamic shape.
    if num_predictions is None:
        num_predictions = array_ops.shape(predictions_2d)[0]
    thresh_tiled = array_ops.tile(
        array_ops.expand_dims(array_ops.constant(thresholds), [1]),
        array_ops.stack([1, num_predictions]))

    # Tile the predictions after threshold them across different thresholds.
    pred_is_pos = math_ops.greater(
        array_ops.tile(array_ops.transpose(predictions_2d),
                       [num_thresholds, 1]), thresh_tiled)
    pred_is_neg = math_ops.logical_not(pred_is_pos)
    label_is_pos = array_ops.tile(labels_2d, [num_thresholds, 1])
    label_is_neg = math_ops.logical_not(label_is_pos)

    if weights is not None:
        weights = weights_broadcast_ops.broadcast_weights(
            math_ops.to_float(weights), predictions)
        weights_tiled = array_ops.tile(array_ops.reshape(weights, [1, -1]),
                                       [num_thresholds, 1])
        thresh_tiled.get_shape().assert_is_compatible_with(
            weights_tiled.get_shape())
    else:
        weights_tiled = None

    values = {}

    # tp
    is_true_positive = math_ops.to_float(
        math_ops.logical_and(label_is_pos, pred_is_pos))
    if weights_tiled is not None:
        is_true_positive *= weights_tiled
    values['tp'] = math_ops.reduce_sum(is_true_positive, 1)

    # fn
    is_false_negative = math_ops.to_float(
        math_ops.logical_and(label_is_pos, pred_is_neg))
    if weights_tiled is not None:
        is_false_negative *= weights_tiled
    values['fn'] = math_ops.reduce_sum(is_false_negative, 1)

    # tn
    is_true_negative = math_ops.to_float(
        math_ops.logical_and(label_is_neg, pred_is_neg))
    if weights_tiled is not None:
        is_true_negative *= weights_tiled
    values['tn'] = math_ops.reduce_sum(is_true_negative, 1)

    # fp
    is_false_positive = math_ops.to_float(
        math_ops.logical_and(label_is_neg, pred_is_pos))
    if weights_tiled is not None:
        is_false_positive *= weights_tiled
    values['fp'] = math_ops.reduce_sum(is_false_positive, 1)

    return values
コード例 #24
0
  def __init__(self,
               learning_rate,
               preconditioner_decay_rate=0.95,
               num_pseudo_batches=1,
               burnin=25,
               diagonal_bias=1e-8,
               name=None,
               variable_scope=None):
    default_name = 'SGLDOptimizer'
    with ops.name_scope(name, default_name, [
        learning_rate, preconditioner_decay_rate, num_pseudo_batches, burnin,
        diagonal_bias
    ]):
      if variable_scope is None:
        var_scope_name = ops.get_default_graph().unique_name(
            name or default_name)
        with varscope_ops.variable_scope(var_scope_name) as scope:
          self._variable_scope = scope
      else:
        self._variable_scope = variable_scope

      self._preconditioner_decay_rate = ops.convert_to_tensor(
          preconditioner_decay_rate, name='preconditioner_decay_rate')
      self._num_pseudo_batches = ops.convert_to_tensor(
          num_pseudo_batches, name='num_pseudo_batches')
      self._burnin = ops.convert_to_tensor(burnin, name='burnin')
      self._diagonal_bias = ops.convert_to_tensor(
          diagonal_bias, name='diagonal_bias')
      self._learning_rate = ops.convert_to_tensor(
          learning_rate, name='learning_rate')

      with varscope_ops.variable_scope(self._variable_scope):
        self._counter = varscope_ops.get_variable(
            'counter', initializer=0, trainable=False)

      self._preconditioner_decay_rate = control_flow_ops.with_dependencies([
          check_ops.assert_non_negative(
              self._preconditioner_decay_rate,
              message='`preconditioner_decay_rate` must be non-negative'),
          check_ops.assert_less_equal(
              self._preconditioner_decay_rate,
              1.,
              message='`preconditioner_decay_rate` must be at most 1.'),
      ], self._preconditioner_decay_rate)

      self._num_pseudo_batches = control_flow_ops.with_dependencies([
          check_ops.assert_greater(
              self._num_pseudo_batches,
              0,
              message='`num_pseudo_batches` must be greater than zero')
      ], self._num_pseudo_batches)

      self._burnin = control_flow_ops.with_dependencies([
          check_ops.assert_non_negative(
              self._burnin, message='`burnin` must be non-negative'),
          check_ops.assert_integer(
              self._burnin, message='`burnin` must be an integer')
      ], self._burnin)

      self._diagonal_bias = control_flow_ops.with_dependencies([
          check_ops.assert_non_negative(
              self._diagonal_bias,
              message='`diagonal_bias` must be non-negative')
      ], self._diagonal_bias)

      super(SGLDOptimizer, self).__init__(use_locking=False,
                                          name=name or default_name)
コード例 #25
0
def get_logits_and_probs(logits=None,
                         probs=None,
                         multidimensional=False,
                         validate_args=False,
                         name="get_logits_and_probs"):
  """Converts logit to probabilities (or vice-versa), and returns both.

  Args:
    logits: Numeric `Tensor` representing log-odds.
    probs: Numeric `Tensor` representing probabilities.
    multidimensional: `Boolean`, default `False`.
      If `True`, represents whether the last dimension of `logits` or `probs`,
      a `[N1, N2, ... k]` dimensional tensor, representing the
      logit or probability of `shape[-1]` classes.
    validate_args: `Boolean`, default `False`.  When `True`, either assert `0 <=
      probs <= 1` (if not `multidimensional`) or that the last dimension of
      `probs` sums to one.
    name: A name for this operation (optional).

  Returns:
    logits, probs: Tuple of `Tensor`s. If `probs` has an entry that is `0` or
      `1`, then the corresponding entry in the returned logit will be `-Inf` and
      `Inf` respectively.

  Raises:
    ValueError: if neither `probs` nor `logits` were passed in, or both were.
  """
  with ops.name_scope(name, values=[probs, logits]):
    if (probs is None) == (logits is None):
      raise ValueError("Must pass probs or logits, but not both.")

    if probs is None:
      logits = ops.convert_to_tensor(logits, name="logits")
      if multidimensional:
        return logits, nn.softmax(logits, name="probs")
      return logits, math_ops.sigmoid(logits, name="probs")

    probs = ops.convert_to_tensor(probs, name="probs")
    if validate_args:
      with ops.name_scope("validate_probs"):
        one = constant_op.constant(1., probs.dtype)
        dependencies = [check_ops.assert_non_negative(probs)]
        if multidimensional:
          dependencies += [assert_close(math_ops.reduce_sum(probs, -1), one,
                                        message="probs does not sum to 1.")]
        else:
          dependencies += [check_ops.assert_less_equal(
              probs, one, message="probs has components greater than 1.")]
        probs = control_flow_ops.with_dependencies(dependencies, probs)

    with ops.name_scope("logits"):
      if multidimensional:
        # Here we don't compute the multidimensional case, in a manner
        # consistent with respect to the unidimensional case. We do so
        # following the TF convention. Typically, you might expect to see
        # logits = log(probs) - log(gather(probs, pivot)). A side-effect of
        # being consistent with the TF approach is that the unidimensional case
        # implicitly handles the second dimension but the multidimensional case
        # explicitly keeps the pivot dimension.
        return math_ops.log(probs), probs
      return math_ops.log(probs) - math_ops.log1p(-1. * probs), probs
コード例 #26
0
ファイル: sampling_ops.py プロジェクト: zhaoyu611/tensorflow
def rejection_sample(tensors, accept_prob_fn, batch_size, queue_threads=1,
                     enqueue_many=False, prebatch_capacity=16,
                     prebatch_threads=1, runtime_checks=False, name=None):
  """Stochastically creates batches by rejection sampling.

  Each list of non-batched tensors is evaluated by `accept_prob_fn`, to produce
  a scalar tensor between 0 and 1. This tensor corresponds to the probability of
  being accepted. When `batch_size` tensor groups have been accepted, the batch
  queue will return a mini-batch.

  Args:
    tensors: List of tensors for data. All tensors are either one item or a
        batch, according to enqueue_many.
    accept_prob_fn: A python lambda that takes a non-batch tensor from each
        item in `tensors`, and produces a scalar tensor.
    batch_size: Size of batch to be returned.
    queue_threads: The number of threads for the queue that will hold the final
      batch.
    enqueue_many: Bool. If true, interpret input tensors as having a batch
        dimension.
    prebatch_capacity: Capacity for the large queue that is used to convert
      batched tensors to single examples.
    prebatch_threads: Number of threads for the large queue that is used to
      convert batched tensors to single examples.
    runtime_checks: Bool. If true, insert runtime checks on the output of
        `accept_prob_fn`. Using `True` might have a performance impact.
    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 a zero initial probability class has a nonzero target
        probability.
  Returns:
    A list of tensors of the same length as `tensors`, with batch dimension
    `batch_size`.

  Example:
    # Get tensor for a single data and label example.
    data, label = data_provider.Get(['data', 'label'])

    # Get stratified batch according to data tensor.
    accept_prob_fn = lambda x: (tf.tanh(x[0]) + 1) / 2
    data_batch = tf.contrib.training.rejection_sample(
        [data, label], accept_prob_fn, 16)

    # Run batch through network.
    ...
  """
  with variable_scope.variable_scope(name, 'rejection_sample', tensors):
    tensor_list = ops.convert_n_to_tensor_or_indexed_slices(tensors)
    # Reduce the case of a batched example to that of a batch of a single
    # example by taking a batch of size one.
    if enqueue_many:
      # Validate that batch dimension of the input is consistent.
      tensor_list = _verify_data_inputs(tensor_list)

      # Make a single queue to hold input examples. Reshape output so examples
      # don't have singleton batch dimension.
      batched = input_ops.batch(tensor_list,
                                batch_size=1,
                                num_threads=prebatch_threads,
                                capacity=prebatch_capacity,
                                enqueue_many=True)
      tensor_list = [array_ops.squeeze(x, [0]) for x in batched]

    # Set up a queue containing batches that have the distribution.
    cur_prob = accept_prob_fn(tensor_list)
    if runtime_checks:
      cur_prob = array_ops.identity(control_flow_ops.with_dependencies(
          [check_ops.assert_less_equal(0.0, cur_prob),
           check_ops.assert_less_equal(cur_prob, 1.0)],
          cur_prob), name='prob_with_checks')
    keep_input = random_ops.random_uniform([]) < cur_prob
    return _conditional_batch(
        tensor_list, keep_input, batch_size, num_threads=queue_threads)
コード例 #27
0
 def check_soundness(ff, fp):
     sufficient_n = st.min_num_samples_for_dkwm_mean_test(
         numbers, 0., 1., false_fail_rate=ff, false_pass_rate=fp)
     detectable_d = st.min_discrepancy_of_true_means_detectable_by_dkwm(
         sufficient_n, 0., 1., false_fail_rate=ff, false_pass_rate=fp)
     return check_ops.assert_less_equal(detectable_d, numbers)
コード例 #28
0
def update_confusion_matrix_variables(variables_to_update,
                                      y_true,
                                      y_pred,
                                      thresholds,
                                      top_k=None,
                                      class_id=None,
                                      sample_weight=None):
  """Returns op to update the given confusion matrix variables.

  For every pair of values in y_true and y_pred:

  true_positive: y_true == True and y_pred > thresholds
  false_negatives: y_true == True and y_pred <= thresholds
  true_negatives: y_true == False and y_pred <= thresholds
  false_positive: y_true == False and y_pred > thresholds

  The results will be weighted and added together. When multiple thresholds are
  provided, we will repeat the same for every threshold.

  For estimation of these metrics over a stream of data, the function creates an
  `update_op` operation that updates the given variables.

  If `sample_weight` is `None`, weights default to 1.
  Use weights of 0 to mask values.

  Args:
    variables_to_update: Dictionary with 'tp', 'fn', 'tn', 'fp' as valid keys
      and corresponding variables to update as values.
    y_true: A `Tensor` whose shape matches `y_pred`. Will be cast to `bool`.
    y_pred: A floating point `Tensor` of arbitrary shape and whose values are in
      the range `[0, 1]`.
    thresholds: A float value or a python list or tuple of float thresholds in
      `[0, 1]`, or NEG_INF (used when top_k is set).
    top_k: Optional int, indicates that the positive labels should be limited to
      the top k predictions.
    class_id: Optional int, limits the prediction and labels to the class
      specified by this argument.
    sample_weight: Optional `Tensor` whose rank is either 0, or the same rank as
      `y_true`, and must be broadcastable to `y_true` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `y_true` dimension).

  Returns:
    Update op.

  Raises:
    ValueError: If `y_pred` and `y_true` have mismatched shapes, or if
      `sample_weight` is not `None` and its shape doesn't match `y_pred`, or if
      `variables_to_update` contains invalid keys.
  """
  if variables_to_update is None:
    return
  y_true = ops.convert_to_tensor(y_true)
  y_pred = ops.convert_to_tensor(y_pred)
  y_pred.shape.assert_is_compatible_with(y_true.shape)

  if not any(
      key for key in variables_to_update if key in list(ConfusionMatrix)):
    raise ValueError(
        'Please provide at least one valid confusion matrix '
        'variable to update. Valid variable key options are: "{}". '
        'Received: "{}"'.format(
            list(ConfusionMatrix), variables_to_update.keys()))

  invalid_keys = [
      key for key in variables_to_update if key not in list(ConfusionMatrix)
  ]
  if invalid_keys:
    raise ValueError(
        'Invalid keys: {}. Valid variable key options are: "{}"'.format(
            invalid_keys, list(ConfusionMatrix)))

  with ops.control_dependencies([
      check_ops.assert_greater_equal(
          y_pred,
          math_ops.cast(0.0, dtype=y_pred.dtype),
          message='predictions must be >= 0'),
      check_ops.assert_less_equal(
          y_pred,
          math_ops.cast(1.0, dtype=y_pred.dtype),
          message='predictions must be <= 1')
  ]):
    y_pred, y_true, sample_weight = squeeze_or_expand_dimensions(
        math_ops.cast(y_pred, dtype=dtypes.float32),
        math_ops.cast(y_true, dtype=dtypes.bool), sample_weight)

  if top_k is not None:
    y_pred = _filter_top_k(y_pred, top_k)
  if class_id is not None:
    y_true = y_true[..., class_id]
    y_pred = y_pred[..., class_id]

  thresholds = to_list(thresholds)
  num_thresholds = len(thresholds)
  num_predictions = array_ops.size(y_pred)

  # Reshape predictions and labels.
  predictions_2d = array_ops.reshape(y_pred, [1, -1])
  labels_2d = array_ops.reshape(
      math_ops.cast(y_true, dtype=dtypes.bool), [1, -1])

  # Tile the thresholds for every prediction.
  thresh_tiled = array_ops.tile(
      array_ops.expand_dims(array_ops.constant(thresholds), 1),
      array_ops.stack([1, num_predictions]))

  # Tile the predictions for every threshold.
  preds_tiled = array_ops.tile(predictions_2d, [num_thresholds, 1])

  # Compare predictions and threshold.
  pred_is_pos = math_ops.greater(preds_tiled, thresh_tiled)

  # Tile labels by number of thresholds
  label_is_pos = array_ops.tile(labels_2d, [num_thresholds, 1])

  if sample_weight is not None:
    weights = weights_broadcast_ops.broadcast_weights(
        math_ops.cast(sample_weight, dtype=dtypes.float32), y_pred)
    weights_tiled = array_ops.tile(
        array_ops.reshape(weights, [1, -1]), [num_thresholds, 1])
  else:
    weights_tiled = None

  update_ops = []

  def weighted_assign_add(label, pred, weights, var):
    label_and_pred = math_ops.cast(
        math_ops.logical_and(label, pred), dtype=dtypes.float32)
    if weights is not None:
      label_and_pred *= weights
    return state_ops.assign_add(var, math_ops.reduce_sum(label_and_pred, 1))

  loop_vars = {
      ConfusionMatrix.TRUE_POSITIVES: (label_is_pos, pred_is_pos),
  }
  update_tn = ConfusionMatrix.TRUE_NEGATIVES in variables_to_update
  update_fp = ConfusionMatrix.FALSE_POSITIVES in variables_to_update
  update_fn = ConfusionMatrix.FALSE_NEGATIVES in variables_to_update

  if update_fn or update_tn:
    pred_is_neg = math_ops.logical_not(pred_is_pos)
    loop_vars[ConfusionMatrix.FALSE_NEGATIVES] = (label_is_pos, pred_is_neg)

  if update_fp or update_tn:
    label_is_neg = math_ops.logical_not(label_is_pos)
    loop_vars[ConfusionMatrix.FALSE_POSITIVES] = (label_is_neg, pred_is_pos)
    if update_tn:
      loop_vars[ConfusionMatrix.TRUE_NEGATIVES] = (label_is_neg, pred_is_neg)

  for matrix_cond, (label, pred) in loop_vars.items():
    if matrix_cond in variables_to_update:
      update_ops.append(
          weighted_assign_add(label, pred, weights_tiled,
                              variables_to_update[matrix_cond]))
  return control_flow_ops.group(update_ops)
コード例 #29
0
def get_logits_and_prob(
    logits=None, p=None,
    multidimensional=False, validate_args=False, name="GetLogitsAndProb"):
  """Converts logits to probabilities and vice-versa, and returns both.

  Args:
    logits: Numeric `Output` representing log-odds.
    p: Numeric `Output` representing probabilities.
    multidimensional: `Boolean`, default `False`.
      If `True`, represents whether the last dimension of `logits` or `p`,
      a [N1, N2, ... k] dimensional tensor, represent the
      logits / probability between k classes. For `p`, this will
      additionally assert that the values in the last dimension sum to one.

      If `False`, this will instead assert that each value of `p` is in
      `[0, 1]`, and will do nothing to `logits`.
    validate_args: `Boolean`, default `False`.  Whether to assert `0 <= p <= 1`
      if multidimensional is `False`, otherwise that the last dimension of `p`
      sums to one.
    name: A name for this operation (optional).

  Returns:
    Tuple with `logits` and `p`. If `p` has an entry that is `0` or `1`, then
    the corresponding entry in the returned logits will be `-Inf` and `Inf`
    respectively.

  Raises:
    ValueError: if neither `p` nor `logits` were passed in, or both were.
  """
  with ops.name_scope(name, values=[p, logits]):
    if p is None and logits is None:
      raise ValueError("Must pass p or logits.")
    elif p is not None and logits is not None:
      raise ValueError("Must pass either p or logits, not both.")
    elif p is None:
      logits = array_ops.identity(logits, name="logits")
      with ops.name_scope("p"):
        if multidimensional:
          p = nn.softmax(logits)
        else:
          p = math_ops.sigmoid(logits)
    elif logits is None:
      with ops.name_scope("p"):
        p = array_ops.identity(p)
        if validate_args:
          one = constant_op.constant(1., p.dtype)
          dependencies = [check_ops.assert_non_negative(p)]
          if multidimensional:
            dependencies += [assert_close(
                math_ops.reduce_sum(p, reduction_indices=[-1]),
                one, message="p does not sum to 1.")]
          else:
            dependencies += [check_ops.assert_less_equal(
                p, one, message="p has components greater than 1.")]
          p = control_flow_ops.with_dependencies(dependencies, p)
      with ops.name_scope("logits"):
        if multidimensional:
          # Here we don't compute the multidimensional case, in a manner
          # consistent with respect to the unidimensional case. We do so
          # following the TF convention. Typically, you might expect to see
          # logits = log(p) - log(gather(p, pivot)). A side-effect of being
          # consistent with the TF approach is that the unidimensional case
          # implicitly handles the second dimension but the multidimensional
          # case explicitly keeps the pivot dimension.
          logits = math_ops.log(p)
        else:
          logits = math_ops.log(p) - math_ops.log(1. - p)
    return (logits, p)
コード例 #30
0
    def _process_input_helper(self,
                              update_row_factors,
                              sp_input=None,
                              transpose_input=False,
                              row_weights=None):
        """Creates the graph for processing a sparse slice of input.

    Args:
      update_row_factors: if True, update or project the row_factors, else
        update or project the column factors.
      sp_input: Please refer to comments for update_row_factors,
        update_col_factors, project_row_factors, and project_col_factors for
        restrictions.
      transpose_input: If True, the input is logically transposed and then the
        corresponding rows/columns of the transposed input are updated.
      row_weights: If not None, this is the row/column weights to be used for
        the update or projection. If None, use the corresponding weights from
        the model. Note that the feature (column/row) weights will be
        determined by the model. When not None, it can either be a scalar or
        a rank-1 tensor with the same number of elements as the number of rows
        of columns to be updated/projected.

    Returns:
      A tuple consisting of the following three elements:
      new_values: New values for the row/column factors.
      update_op: An op that assigns the newly computed values to the row/column
        factors.
      loss: A tensor (scalar) that contains the normalized minibatch loss,
        corresponding to sp_input.
    """
        assert isinstance(sp_input, sparse_tensor.SparseTensor)

        if update_row_factors:
            left = self._row_factors
            right_factors = self._col_factors_cache
            row_wt = self._row_wt_cache
            col_wt = self._col_wt_cache
            total_rows = self._input_rows
            sharding_func = WALSModel._get_sharding_func(
                self._input_rows, self._num_row_shards)
            gramian = self._col_gramian_cache
        else:
            left = self._col_factors
            right_factors = self._row_factors_cache
            row_wt = self._col_wt_cache
            col_wt = self._row_wt_cache
            total_rows = self._input_cols
            sharding_func = WALSModel._get_sharding_func(
                self._input_cols, self._num_col_shards)
            gramian = self._row_gramian_cache
            transpose_input = not transpose_input

        # Note that the row indices of sp_input are based on the original full input
        # Here we reindex the rows and give them contiguous ids starting at 0.
        # We use tf.unique to achieve this reindexing. Note that this is done so
        # that the downstream kernel can assume that the input is "dense" along the
        # row dimension.
        row_ids, col_ids = array_ops.split(value=sp_input.indices,
                                           num_or_size_splits=2,
                                           axis=1)
        update_row_indices, all_row_ids = array_ops.unique(row_ids[:, 0])
        update_col_indices, all_col_ids = array_ops.unique(col_ids[:, 0])
        col_ids = array_ops.expand_dims(
            math_ops.cast(all_col_ids, dtypes.int64), 1)
        row_ids = array_ops.expand_dims(
            math_ops.cast(all_row_ids, dtypes.int64), 1)

        if transpose_input:
            update_indices = update_col_indices
            row_shape = [
                math_ops.cast(
                    array_ops.shape(update_row_indices)[0], dtypes.int64)
            ]
            gather_indices = update_row_indices
        else:
            update_indices = update_row_indices
            row_shape = [
                math_ops.cast(
                    array_ops.shape(update_col_indices)[0], dtypes.int64)
            ]
            gather_indices = update_col_indices

        num_rows = math_ops.cast(
            array_ops.shape(update_indices)[0], dtypes.int64)
        col_shape = [num_rows]
        right = embedding_ops.embedding_lookup(right_factors,
                                               gather_indices,
                                               partition_strategy="div")
        new_sp_indices = array_ops.concat([row_ids, col_ids], 1)
        new_sp_shape = (array_ops.concat([row_shape, col_shape], 0)
                        if transpose_input else array_ops.concat(
                            [col_shape, row_shape], 0))
        new_sp_input = sparse_tensor.SparseTensor(indices=new_sp_indices,
                                                  values=sp_input.values,
                                                  dense_shape=new_sp_shape)

        # Compute lhs and rhs of the normal equations
        total_lhs = (self._unobserved_weight * gramian)
        if self._regularization_matrix is not None:
            total_lhs += self._regularization_matrix
        if self._row_weights is None:
            # Special case of ALS. Use a much simpler update rule.
            total_rhs = (self._unobserved_weight *
                         sparse_ops.sparse_tensor_dense_matmul(
                             new_sp_input, right, adjoint_a=transpose_input))
            # TODO(rmlarsen): handle transposing in tf.matrix_solve instead of
            # transposing explicitly.
            # TODO(rmlarsen): multi-thread tf.matrix_solve.
            new_left_values = array_ops.transpose(
                linalg_ops.matrix_solve(total_lhs,
                                        array_ops.transpose(total_rhs)))
        else:
            if row_weights is None:
                # TODO(yifanchen): Add special handling for single shard without using
                # embedding_lookup and perform benchmarks for those cases. Same for
                # col_weights lookup below.
                row_weights_slice = embedding_ops.embedding_lookup(
                    row_wt, update_indices, partition_strategy="div")
            else:
                num_indices = array_ops.shape(update_indices)[0]
                with ops.control_dependencies([
                        check_ops.assert_less_equal(
                            array_ops.rank(row_weights), 1)
                ]):
                    row_weights_slice = control_flow_ops.cond(
                        math_ops.equal(array_ops.rank(row_weights), 0), lambda:
                        (array_ops.ones([num_indices]) * row_weights),
                        lambda: math_ops.cast(row_weights, dtypes.float32))

            col_weights = embedding_ops.embedding_lookup(
                col_wt, gather_indices, partition_strategy="div")
            partial_lhs, total_rhs = (
                gen_factorization_ops.wals_compute_partial_lhs_and_rhs(
                    right,
                    col_weights,
                    self._unobserved_weight,
                    row_weights_slice,
                    new_sp_input.indices,
                    new_sp_input.values,
                    num_rows,
                    transpose_input,
                    name="wals_compute_partial_lhs_rhs"))
            total_lhs = array_ops.expand_dims(total_lhs, 0) + partial_lhs
            total_rhs = array_ops.expand_dims(total_rhs, -1)
            new_left_values = array_ops.squeeze(
                linalg_ops.matrix_solve(total_lhs, total_rhs), [2])

        update_op_name = "row_update" if update_row_factors else "col_update"
        update_op = self.scatter_update(left,
                                        update_indices,
                                        new_left_values,
                                        sharding_func,
                                        name=update_op_name)

        # Create the loss subgraph
        loss_sp_input = (sparse_ops.sparse_transpose(new_sp_input)
                         if transpose_input else new_sp_input)
        # sp_approx is the low rank estimate of the input matrix, formed by
        # computing the product <u_i, v_j> for (i, j) in loss_sp_input.indices.
        sp_approx_vals = gen_factorization_ops.masked_matmul(
            new_left_values,
            right,
            loss_sp_input.indices,
            transpose_a=False,
            transpose_b=True)
        sp_approx = sparse_tensor.SparseTensor(loss_sp_input.indices,
                                               sp_approx_vals,
                                               loss_sp_input.dense_shape)
        sp_approx_sq = math_ops.square(sp_approx)
        sp_residual = sparse_ops.sparse_add(loss_sp_input, sp_approx * (-1))
        sp_residual_sq = math_ops.square(sp_residual)
        row_wt_mat = (constant_op.constant(0.) if self._row_weights is None
                      else array_ops.expand_dims(row_weights_slice, 1))
        col_wt_mat = (constant_op.constant(0.) if self._col_weights is None
                      else array_ops.expand_dims(col_weights, 0))
        # We return the normalized loss
        partial_row_gramian = math_ops.matmul(new_left_values,
                                              new_left_values,
                                              transpose_a=True)
        normalization_factor = total_rows / math_ops.cast(
            num_rows, dtypes.float32)
        loss = (self._unobserved_weight *
                (sparse_ops.sparse_reduce_sum(sp_residual_sq) -
                 sparse_ops.sparse_reduce_sum(sp_approx_sq) + math_ops.trace(
                     math_ops.matmul(partial_row_gramian, gramian))) +
                sparse_ops.sparse_reduce_sum(
                    row_wt_mat *
                    (sp_residual_sq * col_wt_mat))) * normalization_factor
        if self._regularization is not None:
            loss += self._regularization * (
                math_ops.trace(partial_row_gramian) * normalization_factor +
                math_ops.trace(gramian))
        return (new_left_values, update_op, loss)
コード例 #31
0
def percentile(x,
               q,
               axis=None,
               interpolation=None,
               keep_dims=False,
               validate_args=False,
               name=None):
    """Compute the `q`-th percentile of `x`.

  Given a vector `x`, the `q`-th percentile of `x` is the value `q / 100` of the
  way from the minimum to the maximum in a sorted copy of `x`.

  The values and distances of the two nearest neighbors as well as the
  `interpolation` parameter will determine the percentile if the normalized
  ranking does not match the location of `q` exactly.

  This function is the same as the median if `q = 50`, the same as the minimum
  if `q = 0` and the same as the maximum if `q = 100`.


  ```python
  # Get 30th percentile with default ('nearest') interpolation.
  x = [1., 2., 3., 4.]
  percentile(x, q=30.)
  ==> 2.0

  # Get 30th percentile with 'lower' interpolation
  x = [1., 2., 3., 4.]
  percentile(x, q=30., interpolation='lower')
  ==> 1.0

  # Get 100th percentile (maximum).  By default, this is computed over every dim
  x = [[1., 2.]
       [3., 4.]]
  percentile(x, q=100.)
  ==> 4.0

  # Treat the leading dim as indexing samples, and find the 100th quantile (max)
  # over all such samples.
  x = [[1., 2.]
       [3., 4.]]
  percentile(x, q=100., axis=[0])
  ==> [3., 4.]
  ```

  Compare to `numpy.percentile`.

  Args:
    x:  Floating point `N-D` `Tensor` with `N > 0`.  If `axis` is not `None`,
      `x` must have statically known number of dimensions.
    q:  Scalar `Tensor` in `[0, 100]`. The percentile.
    axis:  Optional `0-D` or `1-D` integer `Tensor` with constant values.
      The axis that hold independent samples over which to return the desired
      percentile.  If `None` (the default), treat every dimension as a sample
      dimension, returning a scalar.
    interpolation : {"lower", "higher", "nearest"}.  Default: "nearest"
      This optional parameter specifies the interpolation method to
      use when the desired quantile lies between two data points `i < j`:
        * lower: `i`.
        * higher: `j`.
        * nearest: `i` or `j`, whichever is nearest.
    keep_dims:  Python `bool`. If `True`, the last dimension is kept with size 1
      If `False`, the last dimension is removed from the output shape.
    validate_args:  Whether to add runtime checks of argument validity.
      If False, and arguments are incorrect, correct behavior is not guaranteed.
    name:  A Python string name to give this `Op`.  Default is "percentile"

  Returns:
    A `(N - len(axis))` dimensional `Tensor` of same dtype as `x`, or, if
      `axis` is `None`, a scalar.

  Raises:
    ValueError:  If argument 'interpolation' is not an allowed type.
  """
    name = name or "percentile"
    allowed_interpolations = {"lower", "higher", "nearest"}

    if interpolation is None:
        interpolation = "nearest"
    else:
        if interpolation not in allowed_interpolations:
            raise ValueError(
                "Argument 'interpolation' must be in %s.  Found %s" %
                (allowed_interpolations, interpolation))

    with ops.name_scope(name, [x, q]):
        x = ops.convert_to_tensor(x, name="x")
        q = math_ops.to_float(q, name="q")
        _get_static_ndims(q, expect_ndims=0)

        if validate_args:
            q = control_flow_ops.with_dependencies([
                check_ops.assert_rank(q, 0),
                check_ops.assert_greater_equal(q, 0.),
                check_ops.assert_less_equal(q, 100.)
            ], q)

        if axis is None:
            y = array_ops.reshape(x, [-1])
        else:
            axis = ops.convert_to_tensor(axis, name="axis")
            check_ops.assert_integer(axis)
            axis_ndims = _get_static_ndims(axis,
                                           expect_static=True,
                                           expect_ndims_no_more_than=1)
            axis_const = tensor_util.constant_value(axis)
            if axis_const is None:
                raise ValueError(
                    "Expected argument 'axis' to be statically available.  Found: %s"
                    % axis)
            axis = axis_const
            if axis_ndims == 0:
                axis = [axis]
            axis = [int(a) for a in axis]
            x_ndims = _get_static_ndims(x,
                                        expect_static=True,
                                        expect_ndims_at_least=1)
            axis = _make_static_axis_non_negative(axis, x_ndims)
            y = _move_dims_to_flat_end(x, axis, x_ndims)

        frac_at_q_or_above = 1. - q / 100.
        d = math_ops.to_float(array_ops.shape(y)[-1])

        if interpolation == "lower":
            index = math_ops.ceil((d - 1) * frac_at_q_or_above)
        elif interpolation == "higher":
            index = math_ops.floor((d - 1) * frac_at_q_or_above)
        elif interpolation == "nearest":
            index = math_ops.round((d - 1) * frac_at_q_or_above)

        # Sort everything, not just the top 'k' entries, which allows multiple calls
        # to sort only once (under the hood) and use CSE.
        sorted_y = _sort_tensor(y)

        # result.shape = B
        result = sorted_y[..., math_ops.to_int32(index)]
        result.set_shape(y.get_shape()[:-1])

        if keep_dims:
            if axis is None:
                # ones_vec = [1, 1,..., 1], total length = len(S) + len(B).
                ones_vec = array_ops.ones(shape=[_get_best_effort_ndims(x)],
                                          dtype=dtypes.int32)
                result *= array_ops.ones(ones_vec, dtype=x.dtype)
            else:
                result = _insert_back_keep_dims(result, axis)

        return result
コード例 #32
0
def assert_true_mean_in_interval_by_dkwm(
    samples, low, high, expected_low, expected_high,
    false_fail_rate=1e-6, name=None):
  """Asserts the mean of the given distribution is in the given interval.

  More precisely, fails if there is enough evidence (using the
  [Dvoretzky-Kiefer-Wolfowitz-Massart inequality]
  (https://en.wikipedia.org/wiki/CDF-based_nonparametric_confidence_interval))
  that the mean of the distribution from which the given samples are
  drawn is _outside_ the given interval with statistical significance
  `false_fail_rate` or stronger, otherwise passes.  If you also want
  to check that you are gathering enough evidence that a pass is not
  spurious, see `min_num_samples_for_dkwm_mean_test` and
  `min_discrepancy_of_true_means_detectable_by_dkwm`.

  Note that `false_fail_rate` is a total false failure rate for all
  the assertions in the batch.  As such, if the batch is nontrivial,
  the assertion will insist on stronger evidence to fail any one member.

  Args:
    samples: Floating-point `Tensor` of samples from the distribution(s)
      of interest.  Entries are assumed IID across the 0th dimension.
      The other dimensions must broadcast with `low` and `high`.
      The support is bounded: `low <= samples <= high`.
    low: Floating-point `Tensor` of lower bounds on the distributions'
      supports.
    high: Floating-point `Tensor` of upper bounds on the distributions'
      supports.
    expected_low: Floating-point `Tensor` of lower bounds on the
      expected true means.
    expected_high: Floating-point `Tensor` of upper bounds on the
      expected true means.
    false_fail_rate: *Scalar* floating-point `Tensor` admissible total
      rate of mistakes.
    name: A name for this operation (optional).

  Returns:
    check: Op that raises `InvalidArgumentError` if any expected mean
      interval does not overlap with the corresponding confidence
      interval.
  """
  with ops.name_scope(
      name, "assert_true_mean_in_interval_by_dkwm",
      [samples, low, high, expected_low, expected_high, false_fail_rate]):
    samples = ops.convert_to_tensor(samples, name="samples")
    low = ops.convert_to_tensor(low, name="low")
    high = ops.convert_to_tensor(high, name="high")
    expected_low = ops.convert_to_tensor(expected_low, name="expected_low")
    expected_high = ops.convert_to_tensor(expected_high, name="expected_high")
    false_fail_rate = ops.convert_to_tensor(
        false_fail_rate, name="false_fail_rate")
    samples = _check_shape_dominates(
        samples, [low, high, expected_low, expected_high])
    min_mean, max_mean = true_mean_confidence_interval_by_dkwm(
        samples, low, high, false_fail_rate)
    # Assert that the interval [min_mean, max_mean] intersects the
    # interval [expected_low, expected_high].  This is true if
    #   max_mean >= expected_low and min_mean <= expected_high.
    # By DeMorgan's law, that's also equivalent to
    #   not (max_mean < expected_low or min_mean > expected_high),
    # which is a way of saying the two intervals are not disjoint.
    check_confidence_interval_can_intersect = check_ops.assert_greater_equal(
        max_mean, expected_low, message="Confidence interval does not "
        "intersect: true mean smaller than expected")
    with ops.control_dependencies([check_confidence_interval_can_intersect]):
      return check_ops.assert_less_equal(
          min_mean, expected_high, message="Confidence interval does not "
          "intersect: true mean greater than expected")
コード例 #33
0
ファイル: util.py プロジェクト: lengjia/RRL
def embed_check_categorical_event_shape(
        categorical_param, name="embed_check_categorical_event_shape"):
    """Embeds checks that categorical distributions don't have too many classes.

  A categorical-type distribution is one which, e.g., returns the class label
  rather than a one-hot encoding.  E.g., `Categorical(probs)`.

  Since distributions output samples in the same dtype as the parameters, we
  must ensure that casting doesn't lose precision. That is, the
  `parameter.dtype` implies a maximum number of classes. However, since shape is
  `int32` and categorical variables are presumed to be indexes into a `Tensor`,
  we must also ensure that the number of classes is no larger than the largest
  possible `int32` index, i.e., `2**31-1`.

  In other words the number of classes, `K`, must satisfy the following
  condition:

  ```python
  K <= min(
      int(2**31 - 1),  # Largest float as an index.
      {
          dtypes.float16: int(2**11),   # Largest int as a float16.
          dtypes.float32: int(2**24),
          dtypes.float64: int(2**53),
      }.get(categorical_param.dtype.base_dtype, 0))
  ```

  Args:
    categorical_param: Floating-point `Tensor` representing parameters of
      distribution over categories. The rightmost shape is presumed to be the
      number of categories.
    name: A name for this operation (optional).

  Returns:
    categorical_param: Input `Tensor` with appropriate assertions embedded.

  Raises:
    TypeError: if `categorical_param` has an unknown `dtype`.
    ValueError: if we can statically identify `categorical_param` as being too
      large (for being closed under int32/float casting).
  """
    with ops.name_scope(name, values=[categorical_param]):
        x = ops.convert_to_tensor(categorical_param, name="categorical_param")
        # The size must not exceed both of:
        # - The largest possible int32 (since categorical values are presumed to be
        #   indexes into a Tensor).
        # - The largest possible integer exactly representable under the given
        #   floating-point dtype (since we need to cast to/from).
        #
        # The chosen floating-point thresholds are 2**(1 + mantissa_bits).
        # For more details, see:
        # https://en.wikipedia.org/wiki/Floating-point_arithmetic#Internal_representation
        x_dtype = x.dtype.base_dtype
        max_event_size = (_largest_integer_by_dtype(x_dtype)
                          if x_dtype.is_floating else 0)
        if max_event_size is 0:
            raise TypeError("Unable to validate size of unrecognized dtype "
                            "({}).".format(x_dtype.name))
        try:
            x_shape_static = x.get_shape().with_rank_at_least(1)
        except ValueError:
            raise ValueError("A categorical-distribution parameter must have "
                             "at least 1 dimension.")
        if x_shape_static[-1].value is not None:
            event_size = x_shape_static[-1].value
            if event_size < 2:
                raise ValueError(
                    "A categorical-distribution parameter must have at "
                    "least 2 events.")
            if event_size > max_event_size:
                raise ValueError(
                    "Number of classes exceeds `dtype` precision, i.e., "
                    "{} implies shape ({}) cannot exceed {}.".format(
                        x_dtype.name, event_size, max_event_size))
            return x
        else:
            event_size = array_ops.shape(x, name="x_shape")[-1]
            return control_flow_ops.with_dependencies([
                check_ops.assert_rank_at_least(
                    x,
                    1,
                    message=("A categorical-distribution parameter must have "
                             "at least 1 dimension.")),
                check_ops.assert_greater_equal(
                    array_ops.shape(x)[-1],
                    2,
                    message=(
                        "A categorical-distribution parameter must have at "
                        "least 2 events.")),
                check_ops.assert_less_equal(
                    event_size,
                    max_event_size,
                    message="Number of classes exceeds `dtype` precision, "
                    "i.e., {} dtype cannot exceed {} shape.".format(
                        x_dtype.name, max_event_size)),
            ], x)
コード例 #34
0
def _interpolate_bilinear(grid,
                          query_points,
                          name='interpolate_bilinear',
                          indexing='ij'):
  """Similar to Matlab's interp2 function.
  Finds values for query points on a grid using bilinear interpolation.
  Args:
    grid: a 4-D float `Tensor` of shape `[batch, height, width, channels]`.
    query_points: a 3-D float `Tensor` of N points with shape `[batch, N, 2]`.
    name: a name for the operation (optional).
    indexing: whether the query points are specified as row and column (ij),
      or Cartesian coordinates (xy).
  Returns:
    values: a 3-D `Tensor` with shape `[batch, N, channels]`
  Raises:
    ValueError: if the indexing mode is invalid, or if the shape of the inputs
      invalid.
  """
  if indexing != 'ij' and indexing != 'xy':
    raise ValueError('Indexing mode must be \'ij\' or \'xy\'')

  with ops.name_scope(name):
    grid = ops.convert_to_tensor(grid)
    query_points = ops.convert_to_tensor(query_points)
    shape = grid.get_shape().as_list()
    if len(shape) != 4:
      msg = 'Grid must be 4 dimensional. Received size: '
      raise ValueError(msg + str(grid.get_shape()))

    batch_size, height, width, channels = (array_ops.shape(grid)[0],
                                           array_ops.shape(grid)[1],
                                           array_ops.shape(grid)[2],
                                           array_ops.shape(grid)[3])

    shape = [batch_size, height, width, channels]
    query_type = query_points.dtype
    grid_type = grid.dtype

    with ops.control_dependencies([
        check_ops.assert_equal(
            len(query_points.get_shape()),
            3,
            message='Query points must be 3 dimensional.'),
        check_ops.assert_equal(
            array_ops.shape(query_points)[2],
            2,
            message='Query points must be size 2 in dim 2.')
    ]):
      num_queries = array_ops.shape(query_points)[1]

    with ops.control_dependencies([
        check_ops.assert_greater_equal(
            height, 2, message='Grid height must be at least 2.'),
        check_ops.assert_greater_equal(
            width, 2, message='Grid width must be at least 2.')
    ]):
      alphas = []
      floors = []
      ceils = []
      index_order = [0, 1] if indexing == 'ij' else [1, 0]
      unstacked_query_points = array_ops.unstack(query_points, axis=2)

    for dim in index_order:
      with ops.name_scope('dim-' + str(dim)):
        queries = unstacked_query_points[dim]

        size_in_indexing_dimension = shape[dim + 1]

        # max_floor is size_in_indexing_dimension - 2 so that max_floor + 1
        # is still a valid index into the grid.
        max_floor = math_ops.cast(size_in_indexing_dimension - 2, query_type)
        min_floor = constant_op.constant(0.0, dtype=query_type)
        floor = math_ops.minimum(
            math_ops.maximum(min_floor, math_ops.floor(queries)), max_floor)
        int_floor = math_ops.cast(floor, dtypes.int32)
        floors.append(int_floor)
        ceil = int_floor + 1
        ceils.append(ceil)

        # alpha has the same type as the grid, as we will directly use alpha
        # when taking linear combinations of pixel values from the image.
        alpha = math_ops.cast(queries - floor, grid_type)
        min_alpha = constant_op.constant(0.0, dtype=grid_type)
        max_alpha = constant_op.constant(1.0, dtype=grid_type)
        alpha = math_ops.minimum(math_ops.maximum(min_alpha, alpha), max_alpha)

        # Expand alpha to [b, n, 1] so we can use broadcasting
        # (since the alpha values don't depend on the channel).
        alpha = array_ops.expand_dims(alpha, 2)
        alphas.append(alpha)

    with ops.control_dependencies([
        check_ops.assert_less_equal(
            math_ops.cast(batch_size * height * width, dtype=dtypes.float32),
            np.iinfo(np.int32).max / 8,
            message="""The image size or batch size is sufficiently large
                       that the linearized addresses used by array_ops.gather
                       may exceed the int32 limit.""")
    ]):
      flattened_grid = array_ops.reshape(
          grid, [batch_size * height * width, channels])
      batch_offsets = array_ops.reshape(
          math_ops.range(batch_size) * height * width, [batch_size, 1])

    # This wraps array_ops.gather. We reshape the image data such that the
    # batch, y, and x coordinates are pulled into the first dimension.
    # Then we gather. Finally, we reshape the output back. It's possible this
    # code would be made simpler by using array_ops.gather_nd.
    def gather(y_coords, x_coords, name):
      with ops.name_scope('gather-' + name):
        linear_coordinates = batch_offsets + y_coords * width + x_coords
        gathered_values = array_ops.gather(flattened_grid, linear_coordinates)
        return array_ops.reshape(gathered_values,
                                 [batch_size, num_queries, channels])

    # grab the pixel values in the 4 corners around each query point
    top_left = gather(floors[0], floors[1], 'top_left')
    top_right = gather(floors[0], ceils[1], 'top_right')
    bottom_left = gather(ceils[0], floors[1], 'bottom_left')
    bottom_right = gather(ceils[0], ceils[1], 'bottom_right')

    # now, do the actual interpolation
    with ops.name_scope('interpolate'):
      interp_top = alphas[1] * (top_right - top_left) + top_left
      interp_bottom = alphas[1] * (bottom_right - bottom_left) + bottom_left
      interp = alphas[0] * (interp_bottom - interp_top) + interp_top

    return interp
コード例 #35
0
def create_feature_bitmask(tensor, dtype=dtypes.int32, name=None):
    """Packs the innermost dimension of a boolean tensor into integer values.

  `result[i1...iN]` is the integer formed by interpreting the booleans
  `tensor[i1...iN, 0:num_bits]` as individual bits, with big-endian order.
  E.g., if `tensor[i1...iN, 0:num_bits] = [True, False, False, True, False]`,
  then `result[i1...iN] = 0b10010 = 18`.  The return tensor is of type `dtype`,
  if specified; if `dtype` is not set, `int32` will be used.

  If `num_bits` is too large to fit in `dtype`, then an exception is raised
  when this op is called (if `num_bits` is statically known) or when it is
  evaluated (if `num_bits` is not statically known).

  Args:
    tensor: `<bool>[D1...DN, num_bits]` The boolean tensor whose innermost
      dimension should be packed to form integer values.
    dtype: The datatype to output for this op (optional).
    name: The name for this op (optional).

  Returns:
    `<dtype> [D1...DN]`
      An integer tensor formed by interpreting the innermost dimension of
      `tensor` as individual bits.

  Raises:
    ValueError: If the data to be packed is too large for the chosen data
      type.
    ValueError: If the data to be packed is not boolean.
    InvalidArgumentError: If the input tensor is a list, or the dtype is not a
      supported integer type.

  Examples:
    ```python
    >>> assert create_feature_bitmask([True, False, False, True]) == 0b1001
    >>> create_feature_bitmask([[True, False], [False, True], [True, True]])
    [0b10, 0b01, 0b11]
    ```
  """
    with ops.name_scope(name, 'CreateFeatureBitmask', [tensor]):
        if (isinstance(tensor, (list, tuple)) and tensor
                and isinstance(tensor[0], ops.Tensor)):
            raise errors.InvalidArgumentError(
                None, None,
                'CreateFeatureBitmask does not support lists of tensors. Consider '
                'using tf.stack(list,-1) to create a single tensor before invoking '
                'this op.')

        tensor = ops.convert_to_tensor(tensor, dtypes.bool, 'tensor')

        if dtype not in _max_bits.keys():
            raise errors.InvalidArgumentError(
                None, None, 'dtype must be one of: [%s], was %s' %
                (sorted(_max_bits.items(), key=lambda kv: kv[1]), dtype.name))

        integer_data = math_ops.cast(tensor, dtype=dtype)
        shape = tensor.shape
        if shape.ndims is not None and shape.dims[-1].value is not None:
            num_bits = shape.dims[-1].value
            if num_bits > 63:
                raise ValueError(
                    'data.shape[-1] must be less than 64, is %d.' % num_bits)
            elif num_bits > _max_bits[dtype]:
                raise ValueError(
                    'data.shape[-1] is too large for %s (was %d, cannot exceed %d); '
                    'consider switching condense_boolean_tensor to a larger '
                    'dtype.' % (dtype.name, num_bits, _max_bits[dtype]))
            bit_masks = constant_op.constant(
                [2**pos for pos in range(num_bits - 1, -1, -1)], dtype)
        else:
            bit_masks = constant_op.constant(
                [2**pos for pos in range(_max_bits[dtype] - 1, -1, -1)], dtype)
            num_bits = array_ops.shape(tensor)[-1]
            with ops.control_dependencies([
                    check_ops.assert_less_equal(
                        num_bits,
                        _max_bits[dtype],
                        message=
                        'data.shape[-1] is too large for %s (cannot exceed %s)'
                        % (dtype.name, _max_bits[dtype]))
            ]):
                # The second slice ("[:num_bits]") is a no-op unless num_bits==0.
                bit_masks = bit_masks[-num_bits:][:num_bits]
        return math_ops.reduce_sum(integer_data * bit_masks, axis=-1)
コード例 #36
0
ファイル: metrics_utils.py プロジェクト: zhiqiuchn/tensorflow
def update_confusion_matrix_variables(variables_to_update,
                                      y_true,
                                      y_pred,
                                      thresholds,
                                      top_k=None,
                                      class_id=None,
                                      sample_weight=None,
                                      multi_label=False,
                                      label_weights=None):
    """Returns op to update the given confusion matrix variables.

  For every pair of values in y_true and y_pred:

  true_positive: y_true == True and y_pred > thresholds
  false_negatives: y_true == True and y_pred <= thresholds
  true_negatives: y_true == False and y_pred <= thresholds
  false_positive: y_true == False and y_pred > thresholds

  The results will be weighted and added together. When multiple thresholds are
  provided, we will repeat the same for every threshold.

  For estimation of these metrics over a stream of data, the function creates an
  `update_op` operation that updates the given variables.

  If `sample_weight` is `None`, weights default to 1.
  Use weights of 0 to mask values.

  Args:
    variables_to_update: Dictionary with 'tp', 'fn', 'tn', 'fp' as valid keys
      and corresponding variables to update as values.
    y_true: A `Tensor` whose shape matches `y_pred`. Will be cast to `bool`.
    y_pred: A floating point `Tensor` of arbitrary shape and whose values are in
      the range `[0, 1]`.
    thresholds: A float value, float tensor, python list, or tuple of float
      thresholds in `[0, 1]`, or NEG_INF (used when top_k is set).
    top_k: Optional int, indicates that the positive labels should be limited to
      the top k predictions.
    class_id: Optional int, limits the prediction and labels to the class
      specified by this argument.
    sample_weight: Optional `Tensor` whose rank is either 0, or the same rank as
      `y_true`, and must be broadcastable to `y_true` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `y_true` dimension).
    multi_label: Optional boolean indicating whether multidimensional
      prediction/labels should be treated as multilabel responses, or flattened
      into a single label. When True, the valus of `variables_to_update` must
      have a second dimension equal to the number of labels in y_true and
      y_pred, and those tensors must not be RaggedTensors.
    label_weights: (optional) tensor of non-negative weights for multilabel
      data. The weights are applied when calculating TP, FP, FN, and TN without
      explicit multilabel handling (i.e. when the data is to be flattened).

  Returns:
    Update op.

  Raises:
    ValueError: If `y_pred` and `y_true` have mismatched shapes, or if
      `sample_weight` is not `None` and its shape doesn't match `y_pred`, or if
      `variables_to_update` contains invalid keys.
  """
    if multi_label and label_weights is not None:
        raise ValueError(
            '`label_weights` for multilabel data should be handled '
            'outside of `update_confusion_matrix_variables` when '
            '`multi_label` is True.')
    if variables_to_update is None:
        return
    if not any(key
               for key in variables_to_update if key in list(ConfusionMatrix)):
        raise ValueError(
            'Please provide at least one valid confusion matrix '
            'variable to update. Valid variable key options are: "{}". '
            'Received: "{}"'.format(list(ConfusionMatrix),
                                    variables_to_update.keys()))

    variable_dtype = list(variables_to_update.values())[0].dtype

    y_true = math_ops.cast(y_true, dtype=variable_dtype)
    y_pred = math_ops.cast(y_pred, dtype=variable_dtype)
    thresholds = ops.convert_to_tensor_v2_with_dispatch(thresholds,
                                                        dtype=variable_dtype)
    num_thresholds = thresholds.shape[0]
    if multi_label:
        one_thresh = math_ops.equal(math_ops.cast(1, dtype=dtypes.int32),
                                    array_ops.rank(thresholds),
                                    name='one_set_of_thresholds_cond')
    else:
        [y_pred, y_true
         ], _ = ragged_assert_compatible_and_get_flat_values([y_pred, y_true],
                                                             sample_weight)
        one_thresh = math_ops.cast(True, dtype=dtypes.bool)

    invalid_keys = [
        key for key in variables_to_update if key not in list(ConfusionMatrix)
    ]
    if invalid_keys:
        raise ValueError(
            'Invalid keys: {}. Valid variable key options are: "{}"'.format(
                invalid_keys, list(ConfusionMatrix)))

    with ops.control_dependencies([
            check_ops.assert_greater_equal(y_pred,
                                           math_ops.cast(0.0,
                                                         dtype=y_pred.dtype),
                                           message='predictions must be >= 0'),
            check_ops.assert_less_equal(y_pred,
                                        math_ops.cast(1.0, dtype=y_pred.dtype),
                                        message='predictions must be <= 1')
    ]):
        if sample_weight is None:
            y_pred, y_true = losses_utils.squeeze_or_expand_dimensions(
                y_pred, y_true)
        else:
            sample_weight = math_ops.cast(sample_weight, dtype=variable_dtype)
            y_pred, y_true, sample_weight = (
                losses_utils.squeeze_or_expand_dimensions(
                    y_pred, y_true, sample_weight=sample_weight))
    y_pred.shape.assert_is_compatible_with(y_true.shape)

    if top_k is not None:
        y_pred = _filter_top_k(y_pred, top_k)
    if class_id is not None:
        y_true = y_true[..., class_id]
        y_pred = y_pred[..., class_id]

    pred_shape = array_ops.shape(y_pred)
    num_predictions = pred_shape[0]
    if y_pred.shape.ndims == 1:
        num_labels = 1
    else:
        num_labels = gen_math_ops.Prod(input=pred_shape[1:], axis=0)
    thresh_label_tile = control_flow_ops.cond(
        one_thresh, lambda: num_labels,
        lambda: math_ops.cast(1, dtype=dtypes.int32))

    # Reshape predictions and labels, adding a dim for thresholding.
    if multi_label:
        predictions_extra_dim = array_ops.expand_dims(y_pred, 0)
        labels_extra_dim = array_ops.expand_dims(
            math_ops.cast(y_true, dtype=dtypes.bool), 0)
    else:
        # Flatten predictions and labels when not multilabel.
        predictions_extra_dim = array_ops.reshape(y_pred, [1, -1])
        labels_extra_dim = array_ops.reshape(
            math_ops.cast(y_true, dtype=dtypes.bool), [1, -1])

    # Tile the thresholds for every prediction.
    if multi_label:
        thresh_pretile_shape = [num_thresholds, 1, -1]
        thresh_tiles = [1, num_predictions, thresh_label_tile]
        data_tiles = [num_thresholds, 1, 1]
    else:
        thresh_pretile_shape = [num_thresholds, -1]
        thresh_tiles = [1, num_predictions * num_labels]
        data_tiles = [num_thresholds, 1]

    thresh_tiled = array_ops.tile(
        array_ops.reshape(thresholds, thresh_pretile_shape),
        array_ops.stack(thresh_tiles))

    # Tile the predictions for every threshold.
    preds_tiled = array_ops.tile(predictions_extra_dim, data_tiles)

    # Compare predictions and threshold.
    pred_is_pos = math_ops.greater(preds_tiled, thresh_tiled)

    # Tile labels by number of thresholds
    label_is_pos = array_ops.tile(labels_extra_dim, data_tiles)

    if sample_weight is not None:
        sample_weight = weights_broadcast_ops.broadcast_weights(
            math_ops.cast(sample_weight, dtype=variable_dtype), y_pred)
        weights_tiled = array_ops.tile(
            array_ops.reshape(sample_weight, thresh_tiles), data_tiles)
    else:
        weights_tiled = None

    if label_weights is not None and not multi_label:
        label_weights = array_ops.expand_dims(label_weights, 0)
        label_weights = weights_broadcast_ops.broadcast_weights(
            label_weights, y_pred)
        label_weights_tiled = array_ops.tile(
            array_ops.reshape(label_weights, thresh_tiles), data_tiles)
        if weights_tiled is None:
            weights_tiled = label_weights_tiled
        else:
            weights_tiled = math_ops.multiply(weights_tiled,
                                              label_weights_tiled)

    update_ops = []

    def weighted_assign_add(label, pred, weights, var):
        label_and_pred = math_ops.cast(math_ops.logical_and(label, pred),
                                       dtype=var.dtype)
        if weights is not None:
            label_and_pred *= math_ops.cast(weights, dtype=var.dtype)
        return var.assign_add(math_ops.reduce_sum(label_and_pred, 1))

    loop_vars = {
        ConfusionMatrix.TRUE_POSITIVES: (label_is_pos, pred_is_pos),
    }
    update_tn = ConfusionMatrix.TRUE_NEGATIVES in variables_to_update
    update_fp = ConfusionMatrix.FALSE_POSITIVES in variables_to_update
    update_fn = ConfusionMatrix.FALSE_NEGATIVES in variables_to_update

    if update_fn or update_tn:
        pred_is_neg = math_ops.logical_not(pred_is_pos)
        loop_vars[ConfusionMatrix.FALSE_NEGATIVES] = (label_is_pos,
                                                      pred_is_neg)

    if update_fp or update_tn:
        label_is_neg = math_ops.logical_not(label_is_pos)
        loop_vars[ConfusionMatrix.FALSE_POSITIVES] = (label_is_neg,
                                                      pred_is_pos)
        if update_tn:
            loop_vars[ConfusionMatrix.TRUE_NEGATIVES] = (label_is_neg,
                                                         pred_is_neg)

    for matrix_cond, (label, pred) in loop_vars.items():

        if matrix_cond in variables_to_update:
            update_ops.append(
                weighted_assign_add(label, pred, weights_tiled,
                                    variables_to_update[matrix_cond]))

    return control_flow_ops.group(update_ops)
コード例 #37
0
ファイル: wishart.py プロジェクト: Jordan1237/tensorflow
  def __init__(self,
               df,
               scale_operator,
               cholesky_input_output_matrices=False,
               validate_args=False,
               allow_nan_stats=True,
               name=None):
    """Construct Wishart distributions.

    Args:
      df: `float` or `double` tensor, the degrees of freedom of the
        distribution(s). `df` must be greater than or equal to `k`.
      scale_operator: `float` or `double` instance of `LinearOperator`.
      cholesky_input_output_matrices: Python `bool`. Any function which whose
        input or output is a matrix assumes the input is Cholesky and returns a
        Cholesky factored matrix. Example `log_prob` input takes a Cholesky and
        `sample_n` returns a Cholesky when
        `cholesky_input_output_matrices=True`.
      validate_args: Python `bool`, default `False`. When `True` distribution
        parameters are checked for validity despite possibly degrading runtime
        performance. When `False` invalid inputs may silently render incorrect
        outputs.
      allow_nan_stats: Python `bool`, default `True`. When `True`, statistics
        (e.g., mean, mode, variance) use the value "`NaN`" to indicate the
        result is undefined. When `False`, an exception is raised if one or
        more of the statistic's batch members are undefined.
      name: Python `str` name prefixed to Ops created by this class.

    Raises:
      TypeError: if scale is not floating-type
      TypeError: if scale.dtype != df.dtype
      ValueError: if df < k, where scale operator event shape is
        `(k, k)`
    """
    parameters = dict(locals())
    self._cholesky_input_output_matrices = cholesky_input_output_matrices
    with ops.name_scope(name) as name:
      with ops.name_scope("init", values=[df, scale_operator]):
        if not scale_operator.dtype.is_floating:
          raise TypeError(
              "scale_operator.dtype=%s is not a floating-point type" %
              scale_operator.dtype)
        if not scale_operator.is_square:
          print(scale_operator.to_dense().eval())
          raise ValueError("scale_operator must be square.")

        self._scale_operator = scale_operator
        self._df = ops.convert_to_tensor(
            df,
            dtype=scale_operator.dtype,
            name="df")
        contrib_tensor_util.assert_same_float_dtype(
            (self._df, self._scale_operator))
        if (self._scale_operator.shape.ndims is None or
            self._scale_operator.shape[-1].value is None):
          self._dimension = math_ops.cast(
              self._scale_operator.domain_dimension_tensor(),
              dtype=self._scale_operator.dtype, name="dimension")
        else:
          self._dimension = ops.convert_to_tensor(
              self._scale_operator.shape[-1].value,
              dtype=self._scale_operator.dtype, name="dimension")
        df_val = tensor_util.constant_value(self._df)
        dim_val = tensor_util.constant_value(self._dimension)
        if df_val is not None and dim_val is not None:
          df_val = np.asarray(df_val)
          if not df_val.shape:
            df_val = [df_val]
          if any(df_val < dim_val):
            raise ValueError(
                "Degrees of freedom (df = %s) cannot be less than "
                "dimension of scale matrix (scale.dimension = %s)"
                % (df_val, dim_val))
        elif validate_args:
          assertions = check_ops.assert_less_equal(
              self._dimension, self._df,
              message=("Degrees of freedom (df = %s) cannot be "
                       "less than dimension of scale matrix "
                       "(scale.dimension = %s)" %
                       (self._dimension, self._df)))
          self._df = control_flow_ops.with_dependencies(
              [assertions], self._df)
    super(_WishartLinearOperator, self).__init__(
        dtype=self._scale_operator.dtype,
        validate_args=validate_args,
        allow_nan_stats=allow_nan_stats,
        reparameterization_type=distribution.FULLY_REPARAMETERIZED,
        parameters=parameters,
        graph_parents=([self._df, self._dimension] +
                       self._scale_operator.graph_parents),
        name=name)
コード例 #38
0
    def __init__(self,
                 df,
                 scale_operator,
                 cholesky_input_output_matrices=False,
                 validate_args=False,
                 allow_nan_stats=True,
                 name=None):
        """Construct Wishart distributions.

    Args:
      df: `float` or `double` tensor, the degrees of freedom of the
        distribution(s). `df` must be greater than or equal to `k`.
      scale_operator: `float` or `double` instance of `LinearOperator`.
      cholesky_input_output_matrices: Python `bool`. Any function which whose
        input or output is a matrix assumes the input is Cholesky and returns a
        Cholesky factored matrix. Example `log_prob` input takes a Cholesky and
        `sample_n` returns a Cholesky when
        `cholesky_input_output_matrices=True`.
      validate_args: Python `bool`, default `False`. When `True` distribution
        parameters are checked for validity despite possibly degrading runtime
        performance. When `False` invalid inputs may silently render incorrect
        outputs.
      allow_nan_stats: Python `bool`, default `True`. When `True`, statistics
        (e.g., mean, mode, variance) use the value "`NaN`" to indicate the
        result is undefined. When `False`, an exception is raised if one or
        more of the statistic's batch members are undefined.
      name: Python `str` name prefixed to Ops created by this class.

    Raises:
      TypeError: if scale is not floating-type
      TypeError: if scale.dtype != df.dtype
      ValueError: if df < k, where scale operator event shape is
        `(k, k)`
    """
        parameters = distribution_util.parent_frame_arguments()
        self._cholesky_input_output_matrices = cholesky_input_output_matrices
        with ops.name_scope(name) as name:
            with ops.name_scope("init", values=[df, scale_operator]):
                if not scale_operator.dtype.is_floating:
                    raise TypeError(
                        "scale_operator.dtype=%s is not a floating-point type"
                        % scale_operator.dtype)
                if not scale_operator.is_square:
                    print(scale_operator.to_dense().eval())
                    raise ValueError("scale_operator must be square.")

                self._scale_operator = scale_operator
                self._df = ops.convert_to_tensor(df,
                                                 dtype=scale_operator.dtype,
                                                 name="df")
                contrib_tensor_util.assert_same_float_dtype(
                    (self._df, self._scale_operator))
                if (self._scale_operator.shape.ndims is None
                        or self._scale_operator.shape[-1].value is None):
                    self._dimension = math_ops.cast(
                        self._scale_operator.domain_dimension_tensor(),
                        dtype=self._scale_operator.dtype,
                        name="dimension")
                else:
                    self._dimension = ops.convert_to_tensor(
                        self._scale_operator.shape[-1].value,
                        dtype=self._scale_operator.dtype,
                        name="dimension")
                df_val = tensor_util.constant_value(self._df)
                dim_val = tensor_util.constant_value(self._dimension)
                if df_val is not None and dim_val is not None:
                    df_val = np.asarray(df_val)
                    if not df_val.shape:
                        df_val = [df_val]
                    if any(df_val < dim_val):
                        raise ValueError(
                            "Degrees of freedom (df = %s) cannot be less than "
                            "dimension of scale matrix (scale.dimension = %s)"
                            % (df_val, dim_val))
                elif validate_args:
                    assertions = check_ops.assert_less_equal(
                        self._dimension,
                        self._df,
                        message=("Degrees of freedom (df = %s) cannot be "
                                 "less than dimension of scale matrix "
                                 "(scale.dimension = %s)" %
                                 (self._dimension, self._df)))
                    self._df = control_flow_ops.with_dependencies([assertions],
                                                                  self._df)
        super(_WishartLinearOperator, self).__init__(
            dtype=self._scale_operator.dtype,
            validate_args=validate_args,
            allow_nan_stats=allow_nan_stats,
            reparameterization_type=distribution.FULLY_REPARAMETERIZED,
            parameters=parameters,
            graph_parents=([self._df, self._dimension] +
                           self._scale_operator.graph_parents),
            name=name)
コード例 #39
0
    def __init__(self,
                 batch_size,
                 total_num_examples,
                 max_learning_rate=1.0,
                 preconditioner_decay_rate=0.95,
                 burnin=25,
                 burnin_max_learning_rate=1e-6,
                 use_single_learning_rate=False,
                 name=None,
                 variable_scope=None):
        default_name = 'VariationalSGDOptimizer'
        with ops.name_scope(name, default_name, [
                max_learning_rate, preconditioner_decay_rate, batch_size,
                burnin, burnin_max_learning_rate
        ]):
            if variable_scope is None:
                var_scope_name = ops.get_default_graph().unique_name(
                    name or default_name)
                with varscope_ops.variable_scope(var_scope_name) as scope:
                    self._variable_scope = scope
            else:
                self._variable_scope = variable_scope

            self._preconditioner_decay_rate = ops.convert_to_tensor(
                preconditioner_decay_rate, name='preconditioner_decay_rate')
            self._batch_size = ops.convert_to_tensor(batch_size,
                                                     name='batch_size')
            self._total_num_examples = ops.convert_to_tensor(
                total_num_examples, name='total_num_examples')
            self._burnin = ops.convert_to_tensor(burnin, name='burnin')
            self._burnin_max_learning_rate = ops.convert_to_tensor(
                burnin_max_learning_rate, name='burnin_max_learning_rate')
            self._max_learning_rate = ops.convert_to_tensor(
                max_learning_rate, name='max_learning_rate')
            self._use_single_learning_rate = use_single_learning_rate

            with varscope_ops.variable_scope(self._variable_scope):
                self._counter = varscope_ops.get_variable('counter',
                                                          initializer=0,
                                                          trainable=False)

            self._preconditioner_decay_rate = control_flow_ops.with_dependencies([
                check_ops.assert_non_negative(
                    self._preconditioner_decay_rate,
                    message='`preconditioner_decay_rate` must be non-negative'
                ),
                check_ops.assert_less_equal(
                    self._preconditioner_decay_rate,
                    1.,
                    message='`preconditioner_decay_rate` must be at most 1.'),
            ], self._preconditioner_decay_rate)

            self._batch_size = control_flow_ops.with_dependencies([
                check_ops.assert_greater(
                    self._batch_size,
                    0,
                    message='`batch_size` must be greater than zero')
            ], self._batch_size)

            self._total_num_examples = control_flow_ops.with_dependencies([
                check_ops.assert_greater(
                    self._total_num_examples,
                    0,
                    message='`total_num_examples` must be greater than zero')
            ], self._total_num_examples)

            self._burnin = control_flow_ops.with_dependencies([
                check_ops.assert_non_negative(
                    self._burnin, message='`burnin` must be non-negative'),
                check_ops.assert_integer(self._burnin,
                                         message='`burnin` must be an integer')
            ], self._burnin)

            self._burnin_max_learning_rate = control_flow_ops.with_dependencies([
                check_ops.assert_non_negative(
                    self._burnin_max_learning_rate,
                    message='`burnin_max_learning_rate` must be non-negative')
            ], self._burnin_max_learning_rate)

            self._max_learning_rate = control_flow_ops.with_dependencies([
                check_ops.assert_non_negative(
                    self._max_learning_rate,
                    message='`max_learning_rate` must be non-negative')
            ], self._max_learning_rate)

            super(VariationalSGDOptimizer, self).__init__(use_locking=False,
                                                          name=name
                                                          or default_name)
コード例 #40
0
def get_logits_and_probs(logits=None,
                         probs=None,
                         multidimensional=False,
                         validate_args=False,
                         name="get_logits_and_probs"):
    """Converts logit to probabilities (or vice-versa), and returns both.

  Args:
    logits: Floating-point `Tensor` representing log-odds.
    probs: Floating-point `Tensor` representing probabilities.
    multidimensional: Python `bool`, default `False`.
      If `True`, represents whether the last dimension of `logits` or `probs`,
      a `[N1, N2, ...  k]` dimensional tensor, representing the
      logit or probability of `shape[-1]` classes.
    validate_args: Python `bool`, default `False`. When `True`, either assert
      `0 <= probs <= 1` (if not `multidimensional`) or that the last dimension
      of `probs` sums to one.
    name: A name for this operation (optional).

  Returns:
    logits, probs: Tuple of `Tensor`s. If `probs` has an entry that is `0` or
      `1`, then the corresponding entry in the returned logit will be `-Inf` and
      `Inf` respectively.

  Raises:
    ValueError: if neither `probs` nor `logits` were passed in, or both were.
  """
    with ops.name_scope(name, values=[probs, logits]):
        if (probs is None) == (logits is None):
            raise ValueError("Must pass probs or logits, but not both.")

        if probs is None:
            logits = ops.convert_to_tensor(logits, name="logits")
            if multidimensional:
                return logits, nn.softmax(logits, name="probs")
            return logits, math_ops.sigmoid(logits, name="probs")

        probs = ops.convert_to_tensor(probs, name="probs")
        if validate_args:
            with ops.name_scope("validate_probs"):
                one = constant_op.constant(1., probs.dtype)
                dependencies = [check_ops.assert_non_negative(probs)]
                if multidimensional:
                    dependencies += [
                        assert_close(math_ops.reduce_sum(probs, -1),
                                     one,
                                     message="probs does not sum to 1.")
                    ]
                else:
                    dependencies += [
                        check_ops.assert_less_equal(
                            probs,
                            one,
                            message="probs has components greater than 1.")
                    ]
                probs = control_flow_ops.with_dependencies(dependencies, probs)

        with ops.name_scope("logits"):
            if multidimensional:
                # Here we don't compute the multidimensional case, in a manner
                # consistent with respect to the unidimensional case. We do so
                # following the TF convention. Typically, you might expect to see
                # logits = log(probs) - log(probs[pivot]). A side-effect of
                # being consistent with the TF approach is that the unidimensional case
                # implicitly handles the second dimension but the multidimensional case
                # explicitly keeps the pivot dimension.
                return math_ops.log(probs), probs
            return math_ops.log(probs) - math_ops.log1p(-1. * probs), probs
コード例 #41
0
def assert_true_mean_equal_by_dkwm_two_sample(
    samples1, low1, high1, samples2, low2, high2,
    false_fail_rate=1e-6, name=None):
  """Asserts the means of the given distributions are equal.

  More precisely, fails if there is enough evidence (using the
  [Dvoretzky-Kiefer-Wolfowitz-Massart inequality]
  (https://en.wikipedia.org/wiki/CDF-based_nonparametric_confidence_interval))
  that the means of the distributions from which the given samples are
  drawn are _not_ equal with statistical significance `false_fail_rate`
  or stronger, otherwise passes.  If you also want to check that you
  are gathering enough evidence that a pass is not spurious, see
  `min_num_samples_for_dkwm_mean_two_sample_test` and
  `min_discrepancy_of_true_means_detectable_by_dkwm_two_sample`.

  Note that `false_fail_rate` is a total false failure rate for all
  the assertions in the batch.  As such, if the batch is nontrivial,
  the assertion will insist on stronger evidence to fail any one member.

  Args:
    samples1: Floating-point tensor of samples from the
      distribution(s) A.  Entries are assumed IID across the 0th
      dimension.  The other dimensions must broadcast with `low1`,
      `high1`, `low2`, and `high2`.
    low1: Floating-point tensor of lower bounds on the supports of the
      distributions A.
    high1: Floating-point tensor of upper bounds on the supports of
      the distributions A.
    samples2: Floating-point tensor of samples from the
      distribution(s) B.  Entries are assumed IID across the 0th
      dimension.  The other dimensions must broadcast with `low1`,
      `high1`, `low2`, and `high2`.
    low2: Floating-point tensor of lower bounds on the supports of the
      distributions B.
    high2: Floating-point tensor of upper bounds on the supports of
      the distributions B.
    false_fail_rate: *Scalar* admissible total rate of mistakes.
    name: A name for this operation (optional).

  Returns:
    check: Op that raises `InvalidArgumentError` if any pair of confidence
      intervals true for corresponding true means do not overlap.
  """
  with ops.name_scope(
      name, "assert_true_mean_equal_by_dkwm_two_sample",
      [samples1, low1, high1, samples2, low2, high2, false_fail_rate]):
    samples1 = ops.convert_to_tensor(samples1, name="samples1")
    low1 = ops.convert_to_tensor(low1, name="low1")
    high1 = ops.convert_to_tensor(high1, name="high1")
    samples2 = ops.convert_to_tensor(samples2, name="samples2")
    low2 = ops.convert_to_tensor(low2, name="low2")
    high2 = ops.convert_to_tensor(high2, name="high2")
    false_fail_rate = ops.convert_to_tensor(
        false_fail_rate, name="false_fail_rate")
    samples1 = _check_shape_dominates(samples1, [low1, high1])
    samples2 = _check_shape_dominates(samples2, [low2, high2])
    compatible_samples = check_ops.assert_equal(
        array_ops.shape(samples1)[1:], array_ops.shape(samples2)[1:])
    with ops.control_dependencies([compatible_samples]):
      # Could in principle play games with cleverly allocating
      # significance instead of the even split below.  It may be possible
      # to get tighter intervals, in order to obtain a higher power test.
      # Any allocation strategy that depends only on the support bounds
      # and sample counts should be valid; however, because the intervals
      # scale as O(-log(false_fail_rate)), there doesn't seem to be much
      # room to win.
      min_mean_1, max_mean_1 = true_mean_confidence_interval_by_dkwm(
          samples1, low1, high1, false_fail_rate / 2.)
      min_mean_2, max_mean_2 = true_mean_confidence_interval_by_dkwm(
          samples2, low2, high2, false_fail_rate / 2.)
      # I want to assert
      #   not (max_mean_1 < min_mean_2 or min_mean_1 > max_mean_2),
      # but I think I only have and-combination of asserts, so use DeMorgan.
      clause1_op = check_ops.assert_greater_equal(max_mean_1, min_mean_2)
      with ops.control_dependencies([clause1_op]):
        return check_ops.assert_less_equal(min_mean_1, max_mean_2)
コード例 #42
0
ファイル: wishart.py プロジェクト: sanketg10/tensorflow
  def __init__(self,
               df,
               scale_operator_pd,
               cholesky_input_output_matrices=False,
               validate_args=False,
               allow_nan_stats=True,
               name=None):
    """Construct Wishart distributions.

    Args:
      df: `float` or `double` tensor, the degrees of freedom of the
        distribution(s). `df` must be greater than or equal to `k`.
      scale_operator_pd: `float` or `double` instance of `OperatorPDBase`.
      cholesky_input_output_matrices: `Boolean`. Any function which whose input
        or output is a matrix assumes the input is Cholesky and returns a
        Cholesky factored matrix. Example`log_pdf` input takes a Cholesky and
        `sample_n` returns a Cholesky when
        `cholesky_input_output_matrices=True`.
      validate_args: `Boolean`, default `False`.  Whether to validate input with
        asserts. If `validate_args` is `False`, and the inputs are invalid,
        correct behavior is not guaranteed.
      allow_nan_stats: `Boolean`, default `True`. If `False`, raise an
        exception if a statistic (e.g., mean, mode) is undefined for any batch
        member. If True, batch members with valid parameters leading to
        undefined statistics will return `NaN` for this statistic.
      name: The name to give Ops created by the initializer.

    Raises:
      TypeError: if scale is not floating-type
      TypeError: if scale.dtype != df.dtype
      ValueError: if df < k, where scale operator event shape is `(k, k)`
    """
    parameters = locals()
    parameters.pop("self")
    self._cholesky_input_output_matrices = cholesky_input_output_matrices
    with ops.name_scope(name) as ns:
      with ops.name_scope("init", values=[df, scale_operator_pd]):
        if not scale_operator_pd.dtype.is_floating:
          raise TypeError(
              "scale_operator_pd.dtype=%s is not a floating-point type" %
              scale_operator_pd.dtype)
        self._scale_operator_pd = scale_operator_pd
        self._df = ops.convert_to_tensor(
            df, dtype=scale_operator_pd.dtype, name="df")
        contrib_tensor_util.assert_same_float_dtype(
            (self._df, self._scale_operator_pd))
        if (self._scale_operator_pd.get_shape().ndims is None or
            self._scale_operator_pd.get_shape()[-1].value is None):
          self._dimension = math_ops.cast(
              self._scale_operator_pd.vector_space_dimension(),
              dtype=self._scale_operator_pd.dtype, name="dimension")
        else:
          self._dimension = ops.convert_to_tensor(
              self._scale_operator_pd.get_shape()[-1].value,
              dtype=self._scale_operator_pd.dtype, name="dimension")
        df_val = tensor_util.constant_value(self._df)
        dim_val = tensor_util.constant_value(self._dimension)
        if df_val is not None and dim_val is not None:
          df_val = np.asarray(df_val)
          if not df_val.shape: df_val = (df_val,)
          if any(df_val < dim_val):
            raise ValueError(
                "Degrees of freedom (df = %s) cannot be less than dimension of "
                "scale matrix (scale.dimension = %s)"
                % (df_val, dim_val))
        elif validate_args:
          assertions = check_ops.assert_less_equal(
              self._dimension, self._df,
              message=("Degrees of freedom (df = %s) cannot be less than "
                       "dimension of scale matrix (scale.dimension = %s)" %
                       (self._dimension, self._df)))
          self._df = control_flow_ops.with_dependencies([assertions], self._df)
    super(_WishartOperatorPD, self).__init__(
        dtype=self._scale_operator_pd.dtype,
        validate_args=validate_args,
        allow_nan_stats=allow_nan_stats,
        is_continuous=True,
        is_reparameterized=True,
        parameters=parameters,
        graph_parents=([self._df, self._dimension] +
                       self._scale_operator_pd.inputs),
        name=ns)
コード例 #43
0
def get_logits_and_prob(logits=None,
                        p=None,
                        multidimensional=False,
                        validate_args=False,
                        name="GetLogitsAndProb"):
    """Converts logits to probabilities and vice-versa, and returns both.

  Args:
    logits: Numeric `Tensor` representing log-odds.
    p: Numeric `Tensor` representing probabilities.
    multidimensional: Given `p` a [N1, N2, ... k] dimensional tensor,
      whether the last dimension represents the probability between k classes.
      This will additionally assert that the values in the last dimension
      sum to one. If `False`, will instead assert that each value is in
      `[0, 1]`.
    validate_args: `Boolean`, default `False`.  Whether to assert `0 <= p <= 1`
      if multidimensional is `False`, otherwise that the last dimension of `p`
      sums to one.
    name: A name for this operation (optional).

  Returns:
    Tuple with `logits` and `p`. If `p` has an entry that is `0` or `1`, then
    the corresponding entry in the returned logits will be `-Inf` and `Inf`
    respectively.

  Raises:
    ValueError: if neither `p` nor `logits` were passed in, or both were.
  """
    with ops.name_scope(name, values=[p, logits]):
        if p is None and logits is None:
            raise ValueError("Must pass p or logits.")
        elif p is not None and logits is not None:
            raise ValueError("Must pass either p or logits, not both.")
        elif p is None:
            logits = array_ops.identity(logits, name="logits")
            with ops.name_scope("p"):
                p = math_ops.sigmoid(logits)
        elif logits is None:
            with ops.name_scope("p"):
                p = array_ops.identity(p)
                if validate_args:
                    one = constant_op.constant(1., p.dtype)
                    dependencies = [check_ops.assert_non_negative(p)]
                    if multidimensional:
                        dependencies += [
                            assert_close(math_ops.reduce_sum(
                                p, reduction_indices=[-1]),
                                         one,
                                         message="p does not sum to 1.")
                        ]
                    else:
                        dependencies += [
                            check_ops.assert_less_equal(
                                p,
                                one,
                                message="p has components greater than 1.")
                        ]
                    p = control_flow_ops.with_dependencies(dependencies, p)
            with ops.name_scope("logits"):
                logits = math_ops.log(p) - math_ops.log(1. - p)
        return (logits, p)
コード例 #44
0
ファイル: wishart.py プロジェクト: ivankreso/tensorflow
  def __init__(self,
               df,
               scale_operator_pd,
               cholesky_input_output_matrices=False,
               validate_args=False,
               allow_nan_stats=True,
               name=None):
    """Construct Wishart distributions.

    Args:
      df: `float` or `double` tensor, the degrees of freedom of the
        distribution(s). `df` must be greater than or equal to `k`.
      scale_operator_pd: `float` or `double` instance of `OperatorPDBase`.
      cholesky_input_output_matrices: `Boolean`. Any function which whose input
        or output is a matrix assumes the input is Cholesky and returns a
        Cholesky factored matrix. Example`log_pdf` input takes a Cholesky and
        `sample_n` returns a Cholesky when
        `cholesky_input_output_matrices=True`.
      validate_args: `Boolean`, default `False`.  Whether to validate input with
        asserts. If `validate_args` is `False`, and the inputs are invalid,
        correct behavior is not guaranteed.
      allow_nan_stats: `Boolean`, default `True`. If `False`, raise an
        exception if a statistic (e.g., mean, mode) is undefined for any batch
        member. If True, batch members with valid parameters leading to
        undefined statistics will return `NaN` for this statistic.
      name: The name to give Ops created by the initializer.

    Raises:
      TypeError: if scale is not floating-type
      TypeError: if scale.dtype != df.dtype
      ValueError: if df < k, where scale operator event shape is `(k, k)`
    """
    parameters = locals()
    parameters.pop("self")
    self._cholesky_input_output_matrices = cholesky_input_output_matrices
    with ops.name_scope(name) as ns:
      with ops.name_scope("init", values=[df, scale_operator_pd]):
        if not scale_operator_pd.dtype.is_floating:
          raise TypeError(
              "scale_operator_pd.dtype=%s is not a floating-point type" %
              scale_operator_pd.dtype)
        self._scale_operator_pd = scale_operator_pd
        self._df = ops.convert_to_tensor(
            df, dtype=scale_operator_pd.dtype, name="df")
        contrib_tensor_util.assert_same_float_dtype(
            (self._df, self._scale_operator_pd))
        if (self._scale_operator_pd.get_shape().ndims is None or
            self._scale_operator_pd.get_shape()[-1].value is None):
          self._dimension = math_ops.cast(
              self._scale_operator_pd.vector_space_dimension(),
              dtype=self._scale_operator_pd.dtype, name="dimension")
        else:
          self._dimension = ops.convert_to_tensor(
              self._scale_operator_pd.get_shape()[-1].value,
              dtype=self._scale_operator_pd.dtype, name="dimension")
        df_val = tensor_util.constant_value(self._df)
        dim_val = tensor_util.constant_value(self._dimension)
        if df_val is not None and dim_val is not None:
          df_val = np.asarray(df_val)
          if not df_val.shape: df_val = (df_val,)
          if any(df_val < dim_val):
            raise ValueError(
                "Degrees of freedom (df = %s) cannot be less than dimension of "
                "scale matrix (scale.dimension = %s)"
                % (df_val, dim_val))
        elif validate_args:
          assertions = check_ops.assert_less_equal(
              self._dimension, self._df,
              message=("Degrees of freedom (df = %s) cannot be less than "
                       "dimension of scale matrix (scale.dimension = %s)" %
                       (self._dimension, self._df)))
          self._df = control_flow_ops.with_dependencies([assertions], self._df)
    super(_WishartOperatorPD, self).__init__(
        dtype=self._scale_operator_pd.dtype,
        validate_args=validate_args,
        allow_nan_stats=allow_nan_stats,
        is_continuous=True,
        reparameterization_type=distribution.FULLY_REPARAMETERIZED,
        parameters=parameters,
        graph_parents=([self._df, self._dimension] +
                       self._scale_operator_pd.inputs),
        name=ns)
コード例 #45
0
ファイル: util.py プロジェクト: 1000sprites/tensorflow
def embed_check_categorical_event_shape(
    categorical_param,
    name="embed_check_categorical_event_shape"):
  """Embeds checks that categorical distributions don't have too many classes.

  A categorical-type distribution is one which, e.g., returns the class label
  rather than a one-hot encoding.  E.g., `Categorical(probs)`.

  Since distributions output samples in the same dtype as the parameters, we
  must ensure that casting doesn't lose precision. That is, the
  `parameter.dtype` implies a maximum number of classes. However, since shape is
  `int32` and categorical variables are presumed to be indexes into a `Tensor`,
  we must also ensure that the number of classes is no larger than the largest
  possible `int32` index, i.e., `2**31-1`.

  In other words the number of classes, `K`, must satisfy the following
  condition:

  ```python
  K <= min(
      int(2**31 - 1),  # Largest float as an index.
      {
          dtypes.float16: int(2**11),   # Largest int as a float16.
          dtypes.float32: int(2**24),
          dtypes.float64: int(2**53),
      }.get(categorical_param.dtype.base_dtype, 0))
  ```

  Args:
    categorical_param: Floating-point `Tensor` representing parameters of
      distribution over categories. The rightmost shape is presumed to be the
      number of categories.
    name: A name for this operation (optional).

  Returns:
    categorical_param: Input `Tensor` with appropriate assertions embedded.

  Raises:
    TypeError: if `categorical_param` has an unknown `dtype`.
    ValueError: if we can statically identify `categorical_param` as being too
      large (for being closed under int32/float casting).
  """
  with ops.name_scope(name, values=[categorical_param]):
    x = ops.convert_to_tensor(categorical_param, name="categorical_param")
    # The size must not exceed both of:
    # - The largest possible int32 (since categorical values are presumed to be
    #   indexes into a Tensor).
    # - The largest possible integer exactly representable under the given
    #   floating-point dtype (since we need to cast to/from).
    #
    # The chosen floating-point thresholds are 2**(1 + mantissa_bits).
    # For more details, see:
    # https://en.wikipedia.org/wiki/Floating-point_arithmetic#Internal_representation
    x_dtype = x.dtype.base_dtype
    max_event_size = (_largest_integer_by_dtype(x_dtype)
                      if x_dtype.is_floating else 0)
    if max_event_size is 0:
      raise TypeError("Unable to validate size of unrecognized dtype "
                      "({}).".format(x_dtype.name))
    try:
      x_shape_static = x.get_shape().with_rank_at_least(1)
    except ValueError:
      raise ValueError("A categorical-distribution parameter must have "
                       "at least 1 dimension.")
    if x_shape_static[-1].value is not None:
      event_size = x_shape_static[-1].value
      if event_size < 2:
        raise ValueError("A categorical-distribution parameter must have at "
                         "least 2 events.")
      if event_size > max_event_size:
        raise ValueError(
            "Number of classes exceeds `dtype` precision, i.e., "
            "{} implies shape ({}) cannot exceed {}.".format(
                x_dtype.name, event_size, max_event_size))
      return x
    else:
      event_size = array_ops.shape(x, name="x_shape")[-1]
      return control_flow_ops.with_dependencies([
          check_ops.assert_rank_at_least(
              x, 1, message=("A categorical-distribution parameter must have "
                             "at least 1 dimension.")),
          check_ops.assert_greater_equal(
              array_ops.shape(x)[-1], 2,
              message=("A categorical-distribution parameter must have at "
                       "least 2 events.")),
          check_ops.assert_less_equal(
              event_size, max_event_size,
              message="Number of classes exceeds `dtype` precision, "
                      "i.e., {} dtype cannot exceed {} shape.".format(
                          x_dtype.name, max_event_size)),
      ], x)
コード例 #46
0
def percentile(x,
               q,
               axis=None,
               interpolation=None,
               keep_dims=False,
               validate_args=False,
               name=None):
  """Compute the `q`-th percentile of `x`.

  Given a vector `x`, the `q`-th percentile of `x` is the value `q / 100` of the
  way from the minimum to the maximum in a sorted copy of `x`.

  The values and distances of the two nearest neighbors as well as the
  `interpolation` parameter will determine the percentile if the normalized
  ranking does not match the location of `q` exactly.

  This function is the same as the median if `q = 50`, the same as the minimum
  if `q = 0` and the same as the maximum if `q = 100`.


  ```python
  # Get 30th percentile with default ('nearest') interpolation.
  x = [1., 2., 3., 4.]
  percentile(x, q=30.)
  ==> 2.0

  # Get 30th percentile with 'lower' interpolation
  x = [1., 2., 3., 4.]
  percentile(x, q=30., interpolation='lower')
  ==> 1.0

  # Get 100th percentile (maximum).  By default, this is computed over every dim
  x = [[1., 2.]
       [3., 4.]]
  percentile(x, q=100.)
  ==> 4.0

  # Treat the leading dim as indexing samples, and find the 100th quantile (max)
  # over all such samples.
  x = [[1., 2.]
       [3., 4.]]
  percentile(x, q=100., axis=[0])
  ==> [3., 4.]
  ```

  Compare to `numpy.percentile`.

  Args:
    x:  Floating point `N-D` `Tensor` with `N > 0`.  If `axis` is not `None`,
      `x` must have statically known number of dimensions.
    q:  Scalar `Tensor` in `[0, 100]`. The percentile.
    axis:  Optional `0-D` or `1-D` integer `Tensor` with constant values.
      The axis that hold independent samples over which to return the desired
      percentile.  If `None` (the default), treat every dimension as a sample
      dimension, returning a scalar.
    interpolation : {"lower", "higher", "nearest"}.  Default: "nearest"
      This optional parameter specifies the interpolation method to
      use when the desired quantile lies between two data points `i < j`:
        * lower: `i`.
        * higher: `j`.
        * nearest: `i` or `j`, whichever is nearest.
    keep_dims:  Python `bool`. If `True`, the last dimension is kept with size 1
      If `False`, the last dimension is removed from the output shape.
    validate_args:  Whether to add runtime checks of argument validity.
      If False, and arguments are incorrect, correct behavior is not guaranteed.
    name:  A Python string name to give this `Op`.  Default is "percentile"

  Returns:
    A `(N - len(axis))` dimensional `Tensor` of same dtype as `x`, or, if
      `axis` is `None`, a scalar.

  Raises:
    ValueError:  If argument 'interpolation' is not an allowed type.
  """
  name = name or "percentile"
  allowed_interpolations = {"lower", "higher", "nearest"}

  if interpolation is None:
    interpolation = "nearest"
  else:
    if interpolation not in allowed_interpolations:
      raise ValueError("Argument 'interpolation' must be in %s.  Found %s" %
                       (allowed_interpolations, interpolation))

  with ops.name_scope(name, [x, q]):
    x = ops.convert_to_tensor(x, name="x")
    # Double is needed here and below, else we get the wrong index if the array
    # is huge along axis.
    q = math_ops.to_double(q, name="q")
    _get_static_ndims(q, expect_ndims=0)

    if validate_args:
      q = control_flow_ops.with_dependencies([
          check_ops.assert_rank(q, 0),
          check_ops.assert_greater_equal(q, math_ops.to_double(0.)),
          check_ops.assert_less_equal(q, math_ops.to_double(100.))
      ], q)

    if axis is None:
      y = array_ops.reshape(x, [-1])
    else:
      axis = ops.convert_to_tensor(axis, name="axis")
      check_ops.assert_integer(axis)
      axis_ndims = _get_static_ndims(
          axis, expect_static=True, expect_ndims_no_more_than=1)
      axis_const = tensor_util.constant_value(axis)
      if axis_const is None:
        raise ValueError(
            "Expected argument 'axis' to be statically available.  Found: %s" %
            axis)
      axis = axis_const
      if axis_ndims == 0:
        axis = [axis]
      axis = [int(a) for a in axis]
      x_ndims = _get_static_ndims(
          x, expect_static=True, expect_ndims_at_least=1)
      axis = _make_static_axis_non_negative(axis, x_ndims)
      y = _move_dims_to_flat_end(x, axis, x_ndims)

    frac_at_q_or_above = 1. - q / 100.
    d = math_ops.to_double(array_ops.shape(y)[-1])

    if interpolation == "lower":
      index = math_ops.ceil((d - 1) * frac_at_q_or_above)
    elif interpolation == "higher":
      index = math_ops.floor((d - 1) * frac_at_q_or_above)
    elif interpolation == "nearest":
      index = math_ops.round((d - 1) * frac_at_q_or_above)

    # If d is gigantic, then we would have d == d - 1, even in double... So
    # let's use max/min to avoid out of bounds errors.
    d = array_ops.shape(y)[-1]
    # d - 1 will be distinct from d in int32.
    index = clip_ops.clip_by_value(math_ops.to_int32(index), 0, d - 1)

    # Sort everything, not just the top 'k' entries, which allows multiple calls
    # to sort only once (under the hood) and use CSE.
    sorted_y = _sort_tensor(y)

    # result.shape = B
    result = sorted_y[..., index]
    result.set_shape(y.get_shape()[:-1])

    if keep_dims:
      if axis is None:
        # ones_vec = [1, 1,..., 1], total length = len(S) + len(B).
        ones_vec = array_ops.ones(
            shape=[_get_best_effort_ndims(x)], dtype=dtypes.int32)
        result *= array_ops.ones(ones_vec, dtype=x.dtype)
      else:
        result = _insert_back_keep_dims(result, axis)

    return result
コード例 #47
0
ファイル: util.py プロジェクト: lengjia/RRL
def embed_check_integer_casting_closed(x,
                                       target_dtype,
                                       assert_nonnegative=True,
                                       name="embed_check_casting_closed"):
    """Ensures integers remain unaffected despite casting to/from int/float types.

  Example integer-types: `uint8`, `int32`, `bool`.
  Example floating-types: `float32`, `float64`.

  The largest possible integer representable by an IEEE754 floating-point is
  `2**(1 + mantissa_bits)` yet the largest possible integer as an int-type is
  `2**(bits - 1) - 1`. This function ensures that a `Tensor` purporting to have
  integer-form values can be cast to some other type without loss of precision.

  The smallest representable integer is the negative of the largest
  representable integer, except for types: `uint8`, `uint16`, `bool`. For these
  types, the smallest representable integer is `0`.

  Args:
    x: `Tensor` representing integer-form values.
    target_dtype: TF `dtype` under which `x` should have identical values.
    assert_nonnegative: `bool` indicating `x` should contain nonnegative values.
    name: A name for this operation (optional).

  Returns:
    x: Input `Tensor` with appropriate assertions embedded.

  Raises:
    TypeError: if `x` is neither integer- nor floating-type.
    TypeError: if `target_dtype` is neither integer- nor floating-type.
    TypeError: if neither `x` nor `target_dtype` are integer-type.
  """

    with ops.name_scope(name, values=[x]):
        x = ops.convert_to_tensor(x, name="x")
        if (not _is_integer_like_by_dtype(x.dtype)
                and not x.dtype.is_floating):
            raise TypeError("{}.dtype must be floating- or "
                            "integer-type.".format(x.dtype.name))
        if (not _is_integer_like_by_dtype(target_dtype)
                and not target_dtype.is_floating):
            raise TypeError("target_dtype ({}) must be floating- or "
                            "integer-type.".format(target_dtype.name))
        if (not _is_integer_like_by_dtype(x.dtype)
                and not _is_integer_like_by_dtype(target_dtype)):
            raise TypeError(
                "At least one of {}.dtype ({}) and target_dtype ({}) "
                "must be integer-type.".format(x.op.name, x.dtype.name,
                                               target_dtype.name))

        assertions = []
        if assert_nonnegative:
            assertions += [
                check_ops.assert_non_negative(
                    x, message="Elements must be non-negative."),
            ]

        if x.dtype.is_floating:
            # Being here means _is_integer_like_by_dtype(target_dtype) = True.
            # Since this check implies the magnitude check below, we need only it.
            assertions += [
                assert_integer_form(
                    x,
                    int_dtype=target_dtype,
                    message="Elements must be {}-equivalent.".format(
                        target_dtype.name)),
            ]
        else:
            if (_largest_integer_by_dtype(x.dtype) >
                    _largest_integer_by_dtype(target_dtype)):
                # Cast may lose integer precision.
                assertions += [
                    check_ops.assert_less_equal(
                        x,
                        _largest_integer_by_dtype(target_dtype),
                        message=("Elements cannot exceed {}.".format(
                            _largest_integer_by_dtype(target_dtype)))),
                ]
            if (not assert_nonnegative and (_smallest_integer_by_dtype(
                    x.dtype) < _smallest_integer_by_dtype(target_dtype))):
                assertions += [
                    check_ops.assert_greater_equal(
                        x,
                        _smallest_integer_by_dtype(target_dtype),
                        message=("Elements cannot be smaller than {}.".format(
                            _smallest_integer_by_dtype(target_dtype)))),
                ]

        if not assertions:
            return x
        return control_flow_ops.with_dependencies(assertions, x)
コード例 #48
0
    def update_state(self, y_true, y_pred, sample_weight=None):
        # Cast inputs
        y_pred = tf.convert_to_tensor(y_pred)
        y_true = tf.cast(y_true, dtype=y_pred.dtype)

        # Transform inputs
        [y_pred, y_true
         ], _ = metrics_utils.ragged_assert_compatible_and_get_flat_values(
             [y_pred, y_true], sample_weight)

        # Check input values and adjust shapes
        with ops.control_dependencies([
                check_ops.assert_greater_equal(
                    y_pred,
                    tf.cast(0.0, dtype=y_pred.dtype),
                    message='predictions must be >= 0'),
                check_ops.assert_less_equal(y_pred,
                                            tf.cast(1.0, dtype=y_pred.dtype),
                                            message='predictions must be <= 1')
        ]):

            if sample_weight is None:
                y_pred, y_true = tf_losses_utils.squeeze_or_expand_dimensions(
                    y_pred, y_true)
            else:
                y_pred, y_true, sample_weight = (
                    tf_losses_utils.squeeze_or_expand_dimensions(
                        y_pred, y_true, sample_weight=sample_weight))

        # Check shape compatibility
        y_pred.shape.assert_is_compatible_with(y_true.shape)

        # Get prediction shape
        pred_shape = tf.shape(y_pred)
        num_predictions = pred_shape[0]

        # Get lables (decode one-hot)
        y_pred_labels = K.flatten(tf.argmax(y_pred, axis=-1))
        y_true_labels = K.flatten(tf.argmax(y_true, axis=-1))

        # Set sample weights
        if sample_weight is not None:
            sample_weight = weights_broadcast_ops.broadcast_weights(
                tf.cast(sample_weight, dtype=y_pred.dtype), y_pred)
            weights_tiled = tf.gather(
                K.flatten(sample_weight),
                tf.range(start=0,
                         limit=num_predictions * self.num_classes,
                         delta=self.num_classes,
                         dtype=tf.int64))
        else:
            weights_tiled = None

        def _weighted_assign_add(label, pred, weights, var):

            return var.assign_add(
                tf.math.confusion_matrix(labels=label,
                                         predictions=pred,
                                         num_classes=self.num_classes,
                                         weights=weights,
                                         dtype=self.dtype))

        # Set return value
        update_ops = []

        # Update confusion matrix
        update_ops.append(
            _weighted_assign_add(y_true_labels, y_pred_labels, weights_tiled,
                                 self.confusion_matrix))

        return tf.group(update_ops)
コード例 #49
0
    def update_state(self, y_true, y_pred, sample_weight=None):
        # Cast inputs
        y_pred = tf.convert_to_tensor(y_pred)
        y_true = tf.cast(y_true, dtype=y_pred.dtype)

        # Transform inputs
        [y_pred, y_true
         ], _ = metrics_utils.ragged_assert_compatible_and_get_flat_values(
             [y_pred, y_true], sample_weight)

        # Get threshold properties
        if isinstance(self.thresholds, list):
            num_thresholds = len(self.thresholds)
        else:
            num_thresholds = len(list(self.thresholds))

        # Check input values and adjust shapes
        with ops.control_dependencies([
                check_ops.assert_greater_equal(
                    y_pred,
                    tf.cast(0.0, dtype=y_pred.dtype),
                    message='predictions must be >= 0'),
                check_ops.assert_less_equal(y_pred,
                                            tf.cast(1.0, dtype=y_pred.dtype),
                                            message='predictions must be <= 1')
        ]):

            if sample_weight is None:
                y_pred, y_true = tf_losses_utils.squeeze_or_expand_dimensions(
                    y_pred, y_true)
            else:
                y_pred, y_true, sample_weight = (
                    tf_losses_utils.squeeze_or_expand_dimensions(
                        y_pred, y_true, sample_weight=sample_weight))

        # Check shape compatibility
        y_pred.shape.assert_is_compatible_with(y_true.shape)

        # Check if num_classes corresponds to y_pred
        if self.average != 'micro':
            tf.debugging.assert_shapes(
                shapes=[(y_pred, (..., self.num_classes))],
                data=y_pred,
                summarize=10,
                message='num_classes must correspond to the prediction')

        # Filter top k
        if self.top_k is not None:
            y_pred = metrics_utils._filter_top_k(y_pred, self.top_k)

        # Select class id
        if self.class_id is not None:
            y_true = y_true[..., self.class_id]
            y_pred = y_pred[..., self.class_id]

        # Get prediction shape
        pred_shape = tf.shape(y_pred)
        num_predictions = pred_shape[0]

        # Set label shapes
        if y_pred.shape.ndims == 1:
            num_labels = 1
        else:
            num_labels = K.prod(pred_shape[1:], axis=0)

        # Flatten predicitons and labels
        predictions_extra_dim = tf.reshape(y_pred, [1, -1])
        labels_extra_dim = tf.reshape(tf.cast(y_true, dtype=tf.bool), [1, -1])

        # Tile the thresholds for every prediction
        thresh_pretile_shape = [num_thresholds, -1]
        thresh_tiles = [1, num_predictions * num_labels]
        data_tiles = [num_thresholds, 1]

        thresh_tiled = tf.tile(
            tf.reshape(tf.constant(self.thresholds, dtype=y_pred.dtype),
                       thresh_pretile_shape), tf.stack(thresh_tiles))

        # Tile the predictions for every threshold
        preds_tiled = tf.tile(predictions_extra_dim, data_tiles)

        # Compare predictions and threshold
        pred_is_pos = tf.greater(preds_tiled, thresh_tiled)

        # Tile labels by number of thresholds
        label_is_pos = tf.tile(labels_extra_dim, data_tiles)

        # Set sample weights
        if sample_weight is not None:
            sample_weight = weights_broadcast_ops.broadcast_weights(
                tf.cast(sample_weight, dtype=y_pred.dtype), y_pred)
            weights_tiled = tf.tile(tf.reshape(sample_weight, thresh_tiles),
                                    data_tiles)
        else:
            weights_tiled = None

        def _weighted_assign_add(label, pred, weights, var):
            label_and_pred = tf.cast(tf.logical_and(label, pred),
                                     dtype=y_pred.dtype)

            if weights is not None:
                label_and_pred *= weights

            if self.average != 'micro':
                label_and_pred = tf.reshape(label_and_pred,
                                            shape=[-1, self.num_classes])

            return var.assign_add(tf.reduce_sum(label_and_pred, self.axis))

        # Set return value
        update_ops = []

        # Update true positives
        update_ops.append(
            _weighted_assign_add(label_is_pos, pred_is_pos, weights_tiled,
                                 self.true_positives))

        # Update false negatives
        pred_is_neg = tf.logical_not(pred_is_pos)
        update_ops.append(
            _weighted_assign_add(label_is_pos, pred_is_neg, weights_tiled,
                                 self.false_negatives))

        # Update false positives
        label_is_neg = tf.logical_not(label_is_pos)
        update_ops.append(
            _weighted_assign_add(label_is_neg, pred_is_pos, weights_tiled,
                                 self.false_positives))

        return tf.group(update_ops)
コード例 #50
0
def assert_true_mean_equal_by_dkwm_two_sample(samples1,
                                              low1,
                                              high1,
                                              samples2,
                                              low2,
                                              high2,
                                              false_fail_rate=1e-6,
                                              name=None):
    """Asserts the means of the given distributions are equal.

  More precisely, fails if there is enough evidence (using the
  [Dvoretzky-Kiefer-Wolfowitz-Massart inequality]
  (https://en.wikipedia.org/wiki/CDF-based_nonparametric_confidence_interval))
  that the means of the distributions from which the given samples are
  drawn are _not_ equal with statistical significance `false_fail_rate`
  or stronger, otherwise passes.  If you also want to check that you
  are gathering enough evidence that a pass is not spurious, see
  `min_num_samples_for_dkwm_mean_two_sample_test` and
  `min_discrepancy_of_true_means_detectable_by_dkwm_two_sample`.

  Note that `false_fail_rate` is a total false failure rate for all
  the assertions in the batch.  As such, if the batch is nontrivial,
  the assertion will insist on stronger evidence to fail any one member.

  Args:
    samples1: Floating-point tensor of samples from the
      distribution(s) A.  Entries are assumed IID across the 0th
      dimension.  The other dimensions must broadcast with `low1`,
      `high1`, `low2`, and `high2`.
    low1: Floating-point tensor of lower bounds on the supports of the
      distributions A.
    high1: Floating-point tensor of upper bounds on the supports of
      the distributions A.
    samples2: Floating-point tensor of samples from the
      distribution(s) B.  Entries are assumed IID across the 0th
      dimension.  The other dimensions must broadcast with `low1`,
      `high1`, `low2`, and `high2`.
    low2: Floating-point tensor of lower bounds on the supports of the
      distributions B.
    high2: Floating-point tensor of upper bounds on the supports of
      the distributions B.
    false_fail_rate: *Scalar* admissible total rate of mistakes.
    name: A name for this operation (optional).

  Returns:
    check: Op that raises `InvalidArgumentError` if any pair of confidence
      intervals true for corresponding true means do not overlap.
  """
    with ops.name_scope(
            name, "assert_true_mean_equal_by_dkwm_two_sample",
        [samples1, low1, high1, samples2, low2, high2, false_fail_rate]):
        samples1 = ops.convert_to_tensor(samples1, name="samples1")
        low1 = ops.convert_to_tensor(low1, name="low1")
        high1 = ops.convert_to_tensor(high1, name="high1")
        samples2 = ops.convert_to_tensor(samples2, name="samples2")
        low2 = ops.convert_to_tensor(low2, name="low2")
        high2 = ops.convert_to_tensor(high2, name="high2")
        false_fail_rate = ops.convert_to_tensor(false_fail_rate,
                                                name="false_fail_rate")
        samples1 = _check_shape_dominates(samples1, [low1, high1])
        samples2 = _check_shape_dominates(samples2, [low2, high2])
        compatible_samples = check_ops.assert_equal(
            array_ops.shape(samples1)[1:],
            array_ops.shape(samples2)[1:])
        with ops.control_dependencies([compatible_samples]):
            # Could in principle play games with cleverly allocating
            # significance instead of the even split below.  It may be possible
            # to get tighter intervals, in order to obtain a higher power test.
            # Any allocation strategy that depends only on the support bounds
            # and sample counts should be valid; however, because the intervals
            # scale as O(-log(false_fail_rate)), there doesn't seem to be much
            # room to win.
            min_mean_1, max_mean_1 = true_mean_confidence_interval_by_dkwm(
                samples1, low1, high1, false_fail_rate / 2.)
            min_mean_2, max_mean_2 = true_mean_confidence_interval_by_dkwm(
                samples2, low2, high2, false_fail_rate / 2.)
            # I want to assert
            #   not (max_mean_1 < min_mean_2 or min_mean_1 > max_mean_2),
            # but I think I only have and-combination of asserts, so use DeMorgan.
            check_confidence_intervals_can_intersect = check_ops.assert_greater_equal(
                max_mean_1,
                min_mean_2,
                message="Confidence intervals do not "
                "intersect: samples1 has a smaller mean than samples2")
            with ops.control_dependencies(
                [check_confidence_intervals_can_intersect]):
                return check_ops.assert_less_equal(
                    min_mean_1,
                    max_mean_2,
                    message="Confidence intervals do not "
                    "intersect: samples2 has a smaller mean than samples1")
def _interpolate_nearest3D(grid,
                          query_points,
                          name='interpolate_nearest3D',
                          indexing='ij'):
  """
  3D nearest-neighbor interpolation based on tensorflow's _interpolate_bilinear
  Author:
    Junyu Chen
  Email:
    [email protected]
  """
  if indexing != 'ij' and indexing != 'xy':
    raise ValueError('Indexing mode must be \'ij\' or \'xy\'')

  with ops.name_scope(name):
    grid = ops.convert_to_tensor(grid)
    query_points = ops.convert_to_tensor(query_points)
    shape = grid.get_shape().as_list()
    if len(shape) != 5:
      msg = 'Grid must be 5 dimensional. Received size: '
      raise ValueError(msg + str(grid.get_shape()))

    batch_size, height, width, length, channels = (array_ops.shape(grid)[0],
                                                array_ops.shape(grid)[1],
                                                array_ops.shape(grid)[2],
                                                array_ops.shape(grid)[3],
                                                array_ops.shape(grid)[4])

    shape = [batch_size, length, height, width, channels]
    query_type = query_points.dtype
    grid_type = grid.dtype

    with ops.control_dependencies([
        check_ops.assert_equal(
            len(query_points.get_shape()),
            3,
            message='Query points must be 3 dimensional.'),
        check_ops.assert_equal(
            array_ops.shape(query_points)[2],
            3,
            message='Query points must be size 2 in dim 2.')
    ]):
      num_queries = array_ops.shape(query_points)[1]

    with ops.control_dependencies([
        check_ops.assert_greater_equal(
            height, 2, message='Grid height must be at least 2.'),
        check_ops.assert_greater_equal(
            width, 2, message='Grid width must be at least 2.')
    ]):
      alphas = []
      floors = []
      ceils = []
      index_order = [0, 1, 2] if indexing == 'ij' else [2, 1, 0]

      unstacked_query_points = array_ops.unstack(query_points, axis=2)
    for dim in index_order:
      with ops.name_scope('dim-' + str(dim)):
        queries = unstacked_query_points[dim]

        size_in_indexing_dimension = shape[dim + 1]

        # max_floor is size_in_indexing_dimension - 2 so that max_floor + 1
        # is still a valid index into the grid.
        max_floor = math_ops.cast(size_in_indexing_dimension - 2, query_type)
        min_floor = constant_op.constant(0.0, dtype=query_type)
        floor = math_ops.minimum(
            math_ops.maximum(min_floor, math_ops.floor(queries)), max_floor)
        int_floor = math_ops.cast(floor, dtypes.int32)
        floors.append(int_floor)
        ceil = int_floor + 1
        ceils.append(ceil)

        # alpha has the same type as the grid, as we will directly use alpha
        # when taking linear combinations of pixel values from the image.
        alpha = math_ops.cast(queries - floor, grid_type)
        min_alpha = constant_op.constant(0.0, dtype=grid_type)
        max_alpha = constant_op.constant(1.0, dtype=grid_type)
        alpha = math_ops.minimum(math_ops.maximum(min_alpha, alpha), max_alpha)

        # Expand alpha to [b, n, 1] so we can use broadcasting
        # (since the alpha values don't depend on the channel).
        alpha = array_ops.expand_dims(alpha, 2)
        alphas.append(alpha)

    with ops.control_dependencies([
        check_ops.assert_less_equal(
            math_ops.cast(batch_size * height * width * length, dtype=dtypes.float32),
            np.iinfo(np.int32).max / 8,
            message="""The image size or batch size is sufficiently large
                       that the linearized addresses used by array_ops.gather
                       may exceed the int32 limit.""")
    ]):
      flattened_grid = array_ops.reshape(
          grid, [batch_size * height * width * length, channels])
      batch_offsets = array_ops.reshape(
          math_ops.range(batch_size) * height * width * length, [batch_size, 1])

    # This wraps array_ops.gather. We reshape the image data such that the
    # batch, y, and x coordinates are pulled into the first dimension.
    # Then we gather. Finally, we reshape the output back. It's possible this
    # code would be made simpler by using array_ops.gather_nd.
    def gather(z_coords, x_coords, y_coords, name):
      with ops.name_scope('gather-' + name):
        linear_coordinates = batch_offsets + (y_coords*width+z_coords)*length + x_coords
        gathered_values = array_ops.gather(flattened_grid, linear_coordinates)
        return array_ops.reshape(gathered_values, [batch_size, num_queries, channels])

    # grab the pixel values in the 8 corners around each query point
    btop_left = gather(floors[2], floors[0], floors[1], 'btop_left')
    btop_right = gather(floors[2], floors[0], ceils[1], 'btop_right')
    bbottom_left = gather(floors[2], ceils[0], floors[1], 'bbottom_left')
    bbottom_right = gather(floors[2], ceils[0], ceils[1], 'bbottom_right')

    ttop_left = gather(ceils[2], floors[0], floors[1], 'ttop_left')
    ttop_right = gather(ceils[2], floors[0], ceils[1], 'ttop_right')
    tbottom_left = gather(ceils[2], ceils[0], floors[1], 'tbottom_left')
    tbottom_right = gather(ceils[2], ceils[0], ceils[1], 'tbottom_right')

    # now, do the actual interpolation
    #alphas = [0.1,0.1,0.1]

    with ops.name_scope('interpolate'):
      interp_top = K.round(alphas[1]) * (btop_right - btop_left) + btop_left
      interp_bottom = K.round(alphas[1]) * (bbottom_right - bbottom_left) + bbottom_left
      interp1 = K.round(alphas[0]) * (interp_bottom - interp_top) + interp_top

      interp_top = K.round(alphas[1]) * (ttop_right - ttop_left) + ttop_left
      interp_bottom = K.round(alphas[1]) * (tbottom_right - tbottom_left) + tbottom_left
      interp2 = K.round(alphas[0]) * (interp_bottom - interp_top) + interp_top

      interp = K.round(alphas[2]) * (interp2 - interp1) + interp1
    return interp