コード例 #1
0
 def testDeprecatedArgumentLookup(self):
   good_value = 3
   self.assertEqual(deprecation.deprecated_argument_lookup(
       "val_new", good_value, "val_old", None), good_value)
   self.assertEqual(deprecation.deprecated_argument_lookup(
       "val_new", None, "val_old", good_value), good_value)
   with self.assertRaisesRegexp(ValueError,
                                "Cannot specify both 'val_old' and 'val_new'"):
     self.assertEqual(deprecation.deprecated_argument_lookup(
         "val_new", good_value, "val_old", good_value), good_value)
コード例 #2
0
    def entr_pool(self,
                  value,
                  ksize,
                  strides,
                  padding,
                  data_format='NHWC',
                  name=None,
                  input=None):
        with ops.name_scope(name, "EntrPool", [value]) as name:
            value = deprecation.deprecated_argument_lookup(
                "input", input, "value", value)

            if data_format is None:
                data_format = "NHWC"
            channel_index = 1 if data_format.startswith("NC") else 3

            ksize = _get_sequence(ksize, 2, channel_index, "ksize")
            strides = _get_sequence(strides, 2, channel_index, "strides")
            paddings = op_pad(padding, value, ksize, strides)

            _, out_h, out_w, _ = self.built_output_shape

            return self.op_entr_pool(value,
                                     ksize=ksize,
                                     strides=strides,
                                     paddings=paddings,
                                     batch_size=self.built_input_shape[0],
                                     out_h=out_h,
                                     out_w=out_w,
                                     mode='high',
                                     data_format=data_format,
                                     name=name)
コード例 #3
0
def string_to_number_v1(string_tensor=None,
                        out_type=dtypes.float32,
                        name=None,
                        input=None):
    string_tensor = deprecation.deprecated_argument_lookup(
        "input", input, "string_tensor", string_tensor)
    return gen_parsing_ops.string_to_number(string_tensor, out_type, name)
コード例 #4
0
def strings_split_v1(input=None, sep=None, maxsplit=-1,  # pylint: disable=redefined-builtin
                     result_type="SparseTensor", source=None, name=None):
  """Split elements of `input` based on `sep`.

  Let N be the size of `input` (typically N will be the batch size). Split each
  element of `input` based on `sep` and return a `SparseTensor` or
  `RaggedTensor` containing the split tokens. Empty tokens are ignored.

  Examples:

  ```python
  >>> tf.strings.split(['hello world', 'a b c'])
  tf.SparseTensor(indices=[[0, 0], [0, 1], [1, 0], [1, 1], [1, 2]],
                  values=['hello', 'world', 'a', 'b', 'c']
                  dense_shape=[2, 3])

  >>> tf.strings.split(['hello world', 'a b c'], result_type="RaggedTensor")
  <tf.RaggedTensor [['hello', 'world'], ['a', 'b', 'c']]>
  ```

  If `sep` is given, consecutive delimiters are not grouped together and are
  deemed to delimit empty strings. For example, `input` of `"1<>2<><>3"` and
  `sep` of `"<>"` returns `["1", "2", "", "3"]`. If `sep` is None or an empty
  string, consecutive whitespace are regarded as a single separator, and the
  result will contain no empty strings at the start or end if the string has
  leading or trailing whitespace.

  Note that the above mentioned behavior matches python's str.split.

  Args:
    input: `1-D` string `Tensor`, the strings to split.
    sep: `0-D` string `Tensor`, the delimiter character.
    maxsplit: An `int`. If `maxsplit > 0`, limit of the split of the result.
    result_type: The tensor type for the result: one of `"RaggedTensor"` or
      `"SparseTensor"`.
    source: alias for "input" argument.
    name: A name for the operation (optional).

  Raises:
    ValueError: If sep is not a string.

  Returns:
    A `SparseTensor` of rank `2`, the strings split according to the delimiter.
    The first column of the indices corresponds to the row in `source` and the
    second column corresponds to the index of the split component in this row.
  """
  source = deprecation.deprecated_argument_lookup(
      "input", input, "source", source)
  with ops.name_scope(name, "StringSplit", [source]):
    sparse_result = string_ops.string_split_v2(
        source, sep=sep, maxsplit=maxsplit)
    if result_type == "SparseTensor":
      return sparse_result
    elif result_type == "RaggedTensor":
      return ragged_tensor.RaggedTensor.from_value_rowids(
          values=sparse_result.values,
          value_rowids=sparse_result.indices[:, 0],
          nrows=sparse_result.dense_shape[0])
    else:
      raise ValueError("result_type must be 'RaggedTensor' or 'SparseTensor'.")
コード例 #5
0
def expand_dims(input, axis=None, name=None, dim=None):  # pylint: disable=redefined-builtin
  """Creates a StructuredTensor with a length 1 axis inserted at index `axis`.

  This is an implementation of tf.expand_dims for StructuredTensor. Note
  that the `axis` must be less than or equal to rank.

  >>> st = StructuredTensor.from_pyval([[{"x": 1}, {"x": 2}], [{"x": 3}]])
  >>> tf.expand_dims(st, 0).to_pyval()
  [[[{'x': 1}, {'x': 2}], [{'x': 3}]]]
  >>> tf.expand_dims(st, 1).to_pyval()
  [[[{'x': 1}, {'x': 2}]], [[{'x': 3}]]]
  >>> tf.expand_dims(st, 2).to_pyval()
  [[[{'x': 1}], [{'x': 2}]], [[{'x': 3}]]]
  >>> tf.expand_dims(st, -1).to_pyval()  # -1 is the same as 2
  [[[{'x': 1}], [{'x': 2}]], [[{'x': 3}]]]

  Args:
    input: the original StructuredTensor.
    axis: the axis to insert the dimension: `-(rank + 1) <= axis <= rank`
    name: the name of the op.
    dim: deprecated: use axis.

  Returns:
    a new structured tensor with larger rank.

  Raises:
    an error if `axis < -(rank + 1)` or `rank < axis`.
  """
  axis = deprecation.deprecated_argument_lookup('axis', axis, 'dim', dim)
  return _expand_dims_impl(input, axis, name=name)
コード例 #6
0
def strings_split_v1(input=None, sep=None, maxsplit=-1,  # pylint: disable=redefined-builtin
                     result_type="SparseTensor", source=None, name=None):
  """Split elements of `input` based on `sep`.

  Let N be the size of `input` (typically N will be the batch size). Split each
  element of `input` based on `sep` and return a `SparseTensor` or
  `RaggedTensor` containing the split tokens. Empty tokens are ignored.

  Examples:

  >>> print(tf.compat.v1.strings.split(['hello world', 'a b c']))
  SparseTensor(indices=tf.Tensor( [[0 0] [0 1] [1 0] [1 1] [1 2]], ...),
               values=tf.Tensor([b'hello' b'world' b'a' b'b' b'c'], ...),
               dense_shape=tf.Tensor([2 3], shape=(2,), dtype=int64))

  >>> print(tf.compat.v1.strings.split(['hello world', 'a b c'],
  ...     result_type="RaggedTensor"))
  <tf.RaggedTensor [[b'hello', b'world'], [b'a', b'b', b'c']]>

  If `sep` is given, consecutive delimiters are not grouped together and are
  deemed to delimit empty strings. For example, `input` of `"1<>2<><>3"` and
  `sep` of `"<>"` returns `["1", "2", "", "3"]`. If `sep` is None or an empty
  string, consecutive whitespace are regarded as a single separator, and the
  result will contain no empty strings at the start or end if the string has
  leading or trailing whitespace.

  Note that the above mentioned behavior matches python's str.split.

  Args:
    input: A string `Tensor` of rank `N`, the strings to split.  If
      `rank(input)` is not known statically, then it is assumed to be `1`.
    sep: `0-D` string `Tensor`, the delimiter character.
    maxsplit: An `int`. If `maxsplit > 0`, limit of the split of the result.
    result_type: The tensor type for the result: one of `"RaggedTensor"` or
      `"SparseTensor"`.
    source: alias for "input" argument.
    name: A name for the operation (optional).

  Raises:
    ValueError: If sep is not a string.

  Returns:
    A `SparseTensor` or `RaggedTensor` of rank `N+1`, the strings split
    according to the delimiter.
  """
  input = deprecation.deprecated_argument_lookup(
      "input", input, "source", source)
  with ops.name_scope(name, "StringSplit", [input]):
    input = ragged_tensor.convert_to_tensor_or_ragged_tensor(
        input, dtype=dtypes.string, name="input")
    if result_type == "SparseTensor" and input.shape.rank == 1:
      return string_ops.string_split_v2(input, sep=sep, maxsplit=maxsplit)

    ragged_result = string_split_v2(input, sep=sep, maxsplit=maxsplit)
    if result_type == "SparseTensor":
      return ragged_result.to_sparse()
    elif result_type == "RaggedTensor":
      return ragged_result
    else:
      raise ValueError("result_type must be 'RaggedTensor' or 'SparseTensor'.")
コード例 #7
0
def cosine_distance(labels,
                    predictions,
                    axis=None,
                    weights=1.0,
                    scope=None,
                    loss_collection=ops.GraphKeys.LOSSES,
                    reduction=Reduction.SUM_BY_NONZERO_WEIGHTS,
                    dim=None):
    """Adds a cosine-distance loss to the training procedure.

  Note that the function assumes that `predictions` and `labels` are already
  unit-normalized.

  Args:
    labels: `Tensor` whose shape matches 'predictions'
    predictions: An arbitrary matrix.
    axis: The dimension along which the cosine distance is computed.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `losses` dimension).
    scope: The scope for the operations performed in computing the loss.
    loss_collection: collection to which this loss will be added.
    reduction: Type of reduction to apply to loss.
    dim: The old (deprecated) name for `axis`.

  Returns:
    Weighted loss float `Tensor`. If `reduction` is `NONE`, this has the same
    shape as `labels`; otherwise, it is scalar.

  Raises:
    ValueError: If `predictions` shape doesn't match `labels` shape, or
      `axis`, `labels`, `predictions` or `weights` is `None`.

  @compatibility(eager)
  The `loss_collection` argument is ignored when executing eagerly. Consider
  holding on to the return value or collecting losses via a `tf.keras.Model`.
  @end_compatibility
  """
    axis = deprecated_argument_lookup("axis", axis, "dim", dim)
    if axis is None:
        raise ValueError("You must specify 'axis'.")
    if labels is None:
        raise ValueError("labels must not be None.")
    if predictions is None:
        raise ValueError("predictions must not be None.")
    with ops.name_scope(scope, "cosine_distance_loss",
                        (predictions, labels, weights)) as scope:
        predictions = math_ops.to_float(predictions)
        labels = math_ops.to_float(labels)
        predictions.get_shape().assert_is_compatible_with(labels.get_shape())

        radial_diffs = math_ops.multiply(predictions, labels)
        losses = 1 - math_ops.reduce_sum(
            radial_diffs, axis=(axis, ), keepdims=True)
        return compute_weighted_loss(losses,
                                     weights,
                                     scope,
                                     loss_collection,
                                     reduction=reduction)
コード例 #8
0
ファイル: numerics.py プロジェクト: aritratony/tensorflow
def verify_tensor_all_finite(t=None, msg=None, name=None, x=None, message=None):
  """Assert that the tensor does not contain any NaN's or Inf's.

  Args:
    t: Tensor to check.
    msg: Message to log on failure.
    name: A name for this operation (optional).
    x: Alias for t.
    message: Alias for msg.

  Returns:
    Same tensor as `t`.
  """
  x = deprecation.deprecated_argument_lookup("x", x, "t", t)
  message = deprecation.deprecated_argument_lookup(
      "message", message, "msg", msg)
  return verify_tensor_all_finite_v2(x, message, name)
コード例 #9
0
def _ragged_squeeze_v1(
        input: ragged_tensor.Ragged,  # pylint: disable=redefined-builtin
        axis=None,
        name=None,
        squeeze_dims=None):
    axis = deprecation.deprecated_argument_lookup('axis', axis, 'squeeze_dims',
                                                  squeeze_dims)
    return squeeze(input, axis, name)
コード例 #10
0
def verify_tensor_all_finite(t=None, msg=None, name=None, x=None, message=None):
  """Assert that the tensor does not contain any NaN's or Inf's.

  Args:
    t: Tensor to check.
    msg: Message to log on failure.
    name: A name for this operation (optional).
    x: Alias for t.
    message: Alias for msg.

  Returns:
    Same tensor as `t`.
  """
  x = deprecation.deprecated_argument_lookup("x", x, "t", t)
  message = deprecation.deprecated_argument_lookup(
      "message", message, "msg", msg)
  return verify_tensor_all_finite_v2(x, message, name)
コード例 #11
0
def string_to_hash_bucket_v1(string_tensor=None,
                             num_buckets=None,
                             name=None,
                             input=None):
    string_tensor = deprecation.deprecated_argument_lookup(
        "input", input, "string_tensor", string_tensor)
    return gen_string_ops.string_to_hash_bucket(string_tensor, num_buckets,
                                                name)
コード例 #12
0
ファイル: string_ops.py プロジェクト: adit-chandra/tensorflow
def string_to_hash_bucket_v1(
    string_tensor=None,
    num_buckets=None,
    name=None,
    input=None):
  string_tensor = deprecation.deprecated_argument_lookup(
      "input", input, "string_tensor", string_tensor)
  return gen_string_ops.string_to_hash_bucket(string_tensor, num_buckets, name)
コード例 #13
0
ファイル: string_ops.py プロジェクト: adit-chandra/tensorflow
def string_to_number_v1(
    string_tensor=None,
    out_type=dtypes.float32,
    name=None,
    input=None):
  string_tensor = deprecation.deprecated_argument_lookup(
      "input", input, "string_tensor", string_tensor)
  return gen_parsing_ops.string_to_number(string_tensor, out_type, name)
コード例 #14
0
ファイル: string_ops.py プロジェクト: wwjiang007/tensorflow
def string_to_hash_bucket_v1(  # pylint: disable=missing-function-docstring
        string_tensor=None,
        num_buckets=None,
        name=None,
        input=None):
    string_tensor = deprecation.deprecated_argument_lookup(
        "input", input, "string_tensor", string_tensor)
    return gen_string_ops.string_to_hash_bucket(string_tensor, num_buckets,
                                                name)
コード例 #15
0
def reduce_join(inputs, axis=None,  # pylint: disable=missing-docstring
                keep_dims=None,
                separator="",
                name=None,
                reduction_indices=None,
                keepdims=None):
  keepdims = deprecation.deprecated_argument_lookup("keepdims", keepdims,
                                                    "keep_dims", keep_dims)
  if keep_dims is None:
    keep_dims = False
  axis = deprecation.deprecated_argument_lookup("axis", axis,
                                                "reduction_indices",
                                                reduction_indices)
  return reduce_join_v2(
      inputs=inputs,
      axis=axis,
      keepdims=keepdims,
      separator=separator,
      name=name)
コード例 #16
0
def string_split(source, sep=None, skip_empty=True, delimiter=None):  # pylint: disable=invalid-name
    """Split elements of `source` based on `delimiter` into a `SparseTensor`.

  Let N be the size of source (typically N will be the batch size). Split each
  element of `source` based on `delimiter` and return a `SparseTensor`
  containing the split tokens. Empty tokens are ignored.

  If `sep` is an empty string, each element of the `source` is split
  into individual strings, each containing one byte. (This includes splitting
  multibyte sequences of UTF-8.) If delimiter contains multiple bytes, it is
  treated as a set of delimiters with each considered a potential split point.

  For example:
  N = 2, source[0] is 'hello world' and source[1] is 'a b c', then the output
  will be

  st.indices = [0, 0;
                0, 1;
                1, 0;
                1, 1;
                1, 2]
  st.shape = [2, 3]
  st.values = ['hello', 'world', 'a', 'b', 'c']

  Args:
    source: `1-D` string `Tensor`, the strings to split.
    sep: `0-D` string `Tensor`, the delimiter character, the string should
      be length 0 or 1. Default is ' '.
    skip_empty: A `bool`. If `True`, skip the empty strings from the result.
    delimiter: deprecated alias for `sep`.

  Raises:
    ValueError: If delimiter is not a string.

  Returns:
    A `SparseTensor` of rank `2`, the strings split according to the delimiter.
    The first column of the indices corresponds to the row in `source` and the
    second column corresponds to the index of the split component in this row.
  """
    delimiter = deprecation.deprecated_argument_lookup("sep", sep, "delimiter",
                                                       delimiter)

    if delimiter is None:
        delimiter = " "
    delimiter = ops.convert_to_tensor(delimiter, dtype=dtypes.string)
    source = ops.convert_to_tensor(source, dtype=dtypes.string)

    indices, values, shape = gen_string_ops.string_split(source,
                                                         delimiter=delimiter,
                                                         skip_empty=skip_empty)
    indices.set_shape([None, 2])
    values.set_shape([None])
    shape.set_shape([2])
    return sparse_tensor.SparseTensor(indices, values, shape)
コード例 #17
0
ファイル: string_ops.py プロジェクト: adit-chandra/tensorflow
def string_split(source, sep=None, skip_empty=True, delimiter=None):  # pylint: disable=invalid-name
  """Split elements of `source` based on `delimiter` into a `SparseTensor`.

  Let N be the size of source (typically N will be the batch size). Split each
  element of `source` based on `delimiter` and return a `SparseTensor`
  containing the split tokens. Empty tokens are ignored.

  If `sep` is an empty string, each element of the `source` is split
  into individual strings, each containing one byte. (This includes splitting
  multibyte sequences of UTF-8.) If delimiter contains multiple bytes, it is
  treated as a set of delimiters with each considered a potential split point.

  For example:
  N = 2, source[0] is 'hello world' and source[1] is 'a b c', then the output
  will be

  st.indices = [0, 0;
                0, 1;
                1, 0;
                1, 1;
                1, 2]
  st.shape = [2, 3]
  st.values = ['hello', 'world', 'a', 'b', 'c']

  Args:
    source: `1-D` string `Tensor`, the strings to split.
    sep: `0-D` string `Tensor`, the delimiter character, the string should
      be length 0 or 1. Default is ' '.
    skip_empty: A `bool`. If `True`, skip the empty strings from the result.
    delimiter: deprecated alias for `sep`.

  Raises:
    ValueError: If delimiter is not a string.

  Returns:
    A `SparseTensor` of rank `2`, the strings split according to the delimiter.
    The first column of the indices corresponds to the row in `source` and the
    second column corresponds to the index of the split component in this row.
  """
  delimiter = deprecation.deprecated_argument_lookup(
      "sep", sep, "delimiter", delimiter)

  if delimiter is None:
    delimiter = " "
  delimiter = ops.convert_to_tensor(delimiter, dtype=dtypes.string)
  source = ops.convert_to_tensor(source, dtype=dtypes.string)

  indices, values, shape = gen_string_ops.string_split(
      source, delimiter=delimiter, skip_empty=skip_empty)
  indices.set_shape([None, 2])
  values.set_shape([None])
  shape.set_shape([2])
  return sparse_tensor.SparseTensor(indices, values, shape)
コード例 #18
0
ファイル: losses_impl.py プロジェクト: bunbutter/tensorflow
def cosine_distance(
    labels, predictions, axis=None, weights=1.0, scope=None,
    loss_collection=ops.GraphKeys.LOSSES,
    reduction=Reduction.SUM_BY_NONZERO_WEIGHTS,
    dim=None):
  """Adds a cosine-distance loss to the training procedure.

  Note that the function assumes that `predictions` and `labels` are already
  unit-normalized.

  Args:
    labels: `Tensor` whose shape matches 'predictions'
    predictions: An arbitrary matrix.
    axis: The dimension along which the cosine distance is computed.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `losses` dimension).
    scope: The scope for the operations performed in computing the loss.
    loss_collection: collection to which this loss will be added.
    reduction: Type of reduction to apply to loss.
    dim: The old (deprecated) name for `axis`.

  Returns:
    Weighted loss float `Tensor`. If `reduction` is `NONE`, this has the same
    shape as `labels`; otherwise, it is scalar.

  Raises:
    ValueError: If `predictions` shape doesn't match `labels` shape, or
      `axis`, `labels`, `predictions` or `weights` is `None`.

  @compatibility(eager)
  The `loss_collection` argument is ignored when executing eagerly. Consider
  holding on to the return value or collecting losses via a `tf.keras.Model`.
  @end_compatibility
  """
  axis = deprecated_argument_lookup("axis", axis, "dim", dim)
  if axis is None:
    raise ValueError("You must specify 'axis'.")
  if labels is None:
    raise ValueError("labels must not be None.")
  if predictions is None:
    raise ValueError("predictions must not be None.")
  with ops.name_scope(scope, "cosine_distance_loss",
                      (predictions, labels, weights)) as scope:
    predictions = math_ops.to_float(predictions)
    labels = math_ops.to_float(labels)
    predictions.get_shape().assert_is_compatible_with(labels.get_shape())

    radial_diffs = math_ops.multiply(predictions, labels)
    losses = 1 - math_ops.reduce_sum(radial_diffs, axis=(axis,), keepdims=True)
    return compute_weighted_loss(
        losses, weights, scope, loss_collection, reduction=reduction)
コード例 #19
0
def SecureSum(input_tensor,
            axis=None,
            keepdims=None,
            name=None,
            reduction_indices=None,
            keep_dims=None):
    keepdims = deprecation.deprecated_argument_lookup("keepdims", keepdims,
                                                      "keep_dims", keep_dims)

    keepdims = False if keepdims is None else keepdims
    axis = math_ops._ReductionDims(input_tensor, axis)

    return _secure_ops.secure_reduce_sum(input_tensor, reduction_indices=axis, name=name, keep_dims=keepdims)
コード例 #20
0
ファイル: string_ops.py プロジェクト: HowieYang0/notmnist-ex
def reduce_join(inputs, axis=None,
                keep_dims=False,
                separator="",
                name=None,
                reduction_indices=None):
  axis = deprecation.deprecated_argument_lookup("axis", axis,
                                                "reduction_indices",
                                                reduction_indices)
  if axis is None:
    raise ValueError("axis must be specified.")
  return gen_string_ops.reduce_join(
      inputs=inputs,
      reduction_indices=axis,
      keep_dims=keep_dims,
      separator=separator,
      name=name)
コード例 #21
0
def dropout(x,
            keep_prob=None,
            noise_shape=None,
            seed=None,
            name=None,
            rate=None):  # pylint: disable=invalid-name
    """Computes dropout.
  For each element of `x`, with probability `rate`, outputs `0`, and otherwise
  scales up the input by `1 / (1-rate)`. The scaling is such that the expected
  sum is unchanged.
  By default, each element is kept or dropped independently.  If `noise_shape`
  is specified, it must be
  [broadcastable](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html)
  to the shape of `x`, and only dimensions with `noise_shape[i] == shape(x)[i]`
  will make independent decisions.  For example, if `shape(x) = [k, l, m, n]`
  and `noise_shape = [k, 1, 1, n]`, each batch and channel component will be
  kept independently and each row and column will be kept or not kept together.
  Args:
    x: A floating point tensor.
    keep_prob: (deprecated) A deprecated alias for `(1-rate)`.
    noise_shape: A 1-D `Tensor` of type `int32`, representing the
      shape for randomly generated keep/drop flags.
    seed: A Python integer. Used to create random seeds. See
      `tf.set_random_seed` for behavior.
    name: A name for this operation (optional).
    rate: A scalar `Tensor` with the same type as `x`. The probability that each
      element of `x` is discarded.
  Returns:
    A Tensor of the same shape of `x`.
  Raises:
    ValueError: If `rate` is not in `[0, 1)` or if `x` is not a floating
      point tensor.
  """
    try:
        keep = 1. - keep_prob if keep_prob is not None else None
    except TypeError:
        raise ValueError("keep_prob must be a floating point number or Tensor "
                         "(got %r)" % keep_prob)

    rate = deprecation.deprecated_argument_lookup("rate", rate, "keep_prob",
                                                  keep)

    if rate is None:
        raise ValueError("You must provide a rate to dropout.")

    return dropout_v2(x, rate, noise_shape=noise_shape, seed=seed, name=name)
コード例 #22
0
def reduce_join(inputs, axis=None,  # pylint: disable=missing-docstring
                keep_dims=False,
                separator="",
                name=None,
                reduction_indices=None,
                keepdims=None):
  keep_dims = deprecation.deprecated_argument_lookup(
      "keepdims", keepdims, "keep_dims", keep_dims)
  inputs_t = ops.convert_to_tensor(inputs)
  reduction_indices = _reduce_join_reduction_dims(
      inputs_t, axis, reduction_indices)
  return gen_string_ops.reduce_join(
      inputs=inputs_t,
      reduction_indices=reduction_indices,
      keep_dims=keep_dims,
      separator=separator,
      name=name)
コード例 #23
0
ファイル: string_ops.py プロジェクト: adit-chandra/tensorflow
def reduce_join(inputs, axis=None,  # pylint: disable=missing-docstring
                keep_dims=False,
                separator="",
                name=None,
                reduction_indices=None,
                keepdims=None):
  keep_dims = deprecation.deprecated_argument_lookup(
      "keepdims", keepdims, "keep_dims", keep_dims)
  inputs_t = ops.convert_to_tensor(inputs)
  reduction_indices = _reduce_join_reduction_dims(
      inputs_t, axis, reduction_indices)
  return gen_string_ops.reduce_join(
      inputs=inputs_t,
      reduction_indices=reduction_indices,
      keep_dims=keep_dims,
      separator=separator,
      name=name)
コード例 #24
0
def cosine_distance(predictions,
                    labels=None,
                    axis=None,
                    weights=1.0,
                    scope=None,
                    dim=None):
  """Adds a cosine-distance loss to the training procedure.

  Note that the function assumes that `predictions` and `labels` are already
  unit-normalized.

  Args:
    predictions: An arbitrary matrix.
    labels: A `Tensor` whose shape matches 'predictions'
    axis: The dimension along which the cosine distance is computed.
    weights: Coefficients for the loss a scalar, a tensor of shape
      [batch_size] or a tensor whose shape matches `predictions`.
    scope: The scope for the operations performed in computing the loss.
    dim: The old (deprecated) name for `axis`.

  Returns:
    A scalar `Tensor` representing the loss value.

  Raises:
    ValueError: If `predictions` shape doesn't match `labels` shape, or
      `weights` is `None`.
  """
  axis = deprecated_argument_lookup(
      "axis", axis, "dim", dim)
  if axis is None:
    raise ValueError("You must specify 'axis'.")
  with ops.name_scope(scope, "cosine_distance_loss",
                      [predictions, labels, weights]) as scope:
    predictions.get_shape().assert_is_compatible_with(labels.get_shape())

    predictions = math_ops.cast(predictions, dtypes.float32)
    labels = math_ops.cast(labels, dtypes.float32)

    radial_diffs = math_ops.multiply(predictions, labels)
    losses = 1 - math_ops.reduce_sum(
        radial_diffs, axis=[
            axis,
        ])
    return compute_weighted_loss(losses, weights, scope=scope)
コード例 #25
0
ファイル: loss_ops.py プロジェクト: ThunderQi/tensorflow
def cosine_distance(predictions,
                    labels=None,
                    axis=None,
                    weights=1.0,
                    scope=None,
                    dim=None):
  """Adds a cosine-distance loss to the training procedure.

  Note that the function assumes that `predictions` and `labels` are already
  unit-normalized.

  Args:
    predictions: An arbitrary matrix.
    labels: A `Tensor` whose shape matches 'predictions'
    axis: The dimension along which the cosine distance is computed.
    weights: Coefficients for the loss a scalar, a tensor of shape
      [batch_size] or a tensor whose shape matches `predictions`.
    scope: The scope for the operations performed in computing the loss.
    dim: The old (deprecated) name for `axis`.

  Returns:
    A scalar `Tensor` representing the loss value.

  Raises:
    ValueError: If `predictions` shape doesn't match `labels` shape, or
      `weights` is `None`.
  """
  axis = deprecated_argument_lookup(
      "axis", axis, "dim", dim)
  if axis is None:
    raise ValueError("You must specify 'axis'.")
  with ops.name_scope(scope, "cosine_distance_loss",
                      [predictions, labels, weights]) as scope:
    predictions.get_shape().assert_is_compatible_with(labels.get_shape())

    predictions = math_ops.to_float(predictions)
    labels = math_ops.to_float(labels)

    radial_diffs = math_ops.multiply(predictions, labels)
    losses = 1 - math_ops.reduce_sum(
        radial_diffs, reduction_indices=[
            axis,
        ])
    return compute_weighted_loss(losses, weights, scope=scope)
コード例 #26
0
ファイル: math_ops.py プロジェクト: yuneskhauli/Diploma
def reduce_mean(input_tensor,
                axis=None,
                keepdims=None,
                name=None,
                reduction_indices=None,
                keep_dims=None):

    keepdims = deprecation.deprecated_argument_lookup("keepdims", keepdims,
                                                      "keep_dims", keep_dims)

    if keepdims is None:
        keepdims = False
    return _may_reduce_to_scalar(
        keepdims, axis, reduction_indices,
        gen_math_ops.mean(input_tensor,
                          _ReductionDims(input_tensor, axis,
                                         reduction_indices),
                          keepdims,
                          name=name))
コード例 #27
0
ファイル: rtt_math_ops.py プロジェクト: zjsunzone/Rosetta
def rtt_mean(
    input_tensor,
    axis=None,
    keepdims=None,
    name=None,
    reduction_indices=None,
    keep_dims=None,
):
    """Computes the mean of elements across dimensions of a tensor."""

    keepdims = deprecation.deprecated_argument_lookup("keepdims", keepdims,
                                                      "keep_dims", keep_dims)
    keepdims = False if keepdims is None else keepdims
    axis = math_ops._ReductionDims(input_tensor, axis)
    input_tensor = rtt_ts.convert_to_rtttensor(input_tensor)
    _result = rtt_ts.rtt_ops.rtt_reduce_mean(input_tensor,
                                             reduction_indices=axis,
                                             name=name,
                                             keep_dims=keepdims)
    return rtt_ts.RttTensor(_result)
コード例 #28
0
ファイル: parsing_ops.py プロジェクト: wangjunbo2000/wangjb
def decode_raw_v1(
        input_bytes=None,
        out_type=None,
        little_endian=True,
        name=None,
        bytes=None  # pylint: disable=redefined-builtin
):
    """Convert raw byte strings into tensors.

  Args:
    input_bytes:
      Each element of the input Tensor is converted to an array of bytes.
    out_type:
      `DType` of the output. Acceptable types are `half`, `float`, `double`,
      `int32`, `uint16`, `uint8`, `int16`, `int8`, `int64`.
    little_endian:
      Whether the `input_bytes` data is in little-endian format. Data will be
      converted into host byte order if necessary.
    name: A name for the operation (optional).
    bytes: Deprecated parameter. Use `input_bytes` instead.

  Returns:
    A `Tensor` object storing the decoded bytes.
  """
    input_bytes = deprecation.deprecated_argument_lookup(
        "input_bytes", input_bytes, "bytes", bytes)

    # out_type is a required positional argument in the original API, and had to
    # be changed to a keyword argument in order to facilitate the transition from
    # the reserved named `bytes` to `input_bytes`. Ensure it's still set.
    if out_type is None:
        raise ValueError(
            "decode_raw_v1() missing 1 positional argument: 'out_type'")

    return gen_parsing_ops.decode_raw(input_bytes,
                                      out_type,
                                      little_endian=little_endian,
                                      name=name)
コード例 #29
0
def asset_or_nothing_price(volatilities,
                           strikes,
                           expiries,
                           spots=None,
                           forwards=None,
                           discount_rates=None,
                           dividend_rates=None,
                           continuous_dividends=None,
                           cost_of_carries=None,
                           discount_factors=None,
                           is_call_options=None,
                           is_normal_volatility=False,
                           dtype=None,
                           name=None):
  """Computes the Black Scholes price for a batch of asset-or-nothing options.

  The asset-or-nothing call (resp. put) pays out one unit of the underlying
  asset if the spot is above (resp. below) the strike at maturity.

  #### Example

  ```python
    # Price a batch of 5 asset_or_nothing call and put options.
    volatilities = np.array([0.0001, 102.0, 2.0, 0.1, 0.4])
    forwards = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
    # Strikes will automatically be broadcasted to shape [5].
    strikes = np.array([3.0])
    # Expiries will be broadcast to shape [5], i.e. each option has strike=3
    # and expiry = 1.
    expiries = 1.0
    computed_prices = tff.black_scholes.asset_or_nothing_price(
        volatilities=volatilities,
        strikes=strikes,
        expiries=expiries,
        forwards=forwards)
  # Expected print output of prices:
  # [0., 2., 2.52403424, 3.99315108, 4.65085383]
  ```

  #### References:

  [1] Hull, John C., Options, Futures and Other Derivatives. Pearson, 2018.
  [2] https://en.wikipedia.org/wiki/Binary_option#Asset-or-nothing_call

  Args:
    volatilities: Real `Tensor` of any shape and dtype. The volatilities to
      expiry of the options to price.
    strikes: A real `Tensor` of the same dtype and compatible shape as
      `volatilities`. The strikes of the options to be priced.
    expiries: A real `Tensor` of same dtype and compatible shape as
      `volatilities`. The expiry of each option.
    spots: A real `Tensor` of any shape that broadcasts to the shape of the
      `volatilities`. The current spot price of the underlying. Either this
      argument or the `forwards` (but not both) must be supplied.
    forwards: A real `Tensor` of any shape that broadcasts to the shape of
      `volatilities`. The forwards to maturity. Either this argument or the
      `spots` must be supplied but both must not be supplied.
    discount_rates: An optional real `Tensor` of same dtype as the
      `volatilities` and of the shape that broadcasts with `volatilities`. If
      not `None`, discount factors are calculated as e^(-rT), where r are the
      discount rates, or risk free rates. At most one of discount_rates and
      discount_factors can be supplied.
      Default value: `None`, equivalent to r = 0 and discount factors = 1 when
        discount_factors also not given.
    dividend_rates: An optional real `Tensor` of same dtype as the
      `volatilities` and of the shape that broadcasts with `volatilities`. If
      not `None`, `cost_of_carries` is calculated as r - q, where r are the
      `discount_rates` and q is `dividend_rates`. Either this or
      `cost_of_carries` can be given.
      Default value: `None`, equivalent to q = 0.
    continuous_dividends: `Tensor` equivalent to `dividend_rates`, to be
      deprecated.
    cost_of_carries: An optional real `Tensor` of same dtype as the
      `volatilities` and of the shape that broadcasts with `volatilities`. Cost
      of storing a physical commodity, the cost of interest paid when long, or
      the opportunity cost, or the cost of paying dividends when short. If not
      `None`, and `spots` is supplied, used to calculate forwards from
      `spots`: F = e^(bT) * S, where F is the forwards price, b is the cost of
        carries, T is expiries and S is the spot price. If `None`, value assumed
        to be equal to the `discount_rate` - `dividend_rates`
      Default value: `None`, equivalent to b = r.
    discount_factors: An optional real `Tensor` of same dtype as the
      `volatilities`. If not `None`, these are the discount factors to expiry
      (i.e. e^(-rT)). Mutually exclusive with discount_rate and cost_of_carry.
      If neither is given, no discounting is applied (i.e. the undiscounted
      option price is returned). If `spots` is supplied and `discount_factors`
      is not `None` then this is also used to compute the forwards to expiry. At
      most one of discount_rates and discount_factors can be supplied.
      Default value: `None`, which maps to e^(-rT) calculated from
        discount_rates.
    is_call_options: A boolean `Tensor` of a shape compatible with
      `volatilities`. Indicates whether the option is a call (if True) or a put
      (if False). If not supplied, call options are assumed.
    is_normal_volatility: An optional Python boolean specifying whether the
      `volatilities` correspond to lognormal Black volatility (if False) or
      normal Black volatility (if True).
      Default value: False, which corresponds to lognormal volatility.
    dtype: Optional `tf.DType`. If supplied, the dtype to be used for conversion
      of any supplied non-`Tensor` arguments to `Tensor`.
      Default value: `None` which maps to the default dtype inferred by
        TensorFlow.
    name: str. The name for the ops created by this function.
      Default value: `None`, which is mapped to the default name
        `asset_or_nothing_price`.

  Returns:
    option_prices: A `Tensor` of the same shape as `forwards`. The Black
    Scholes price of the options.

  Raises:
    ValueError: If both `forwards` and `spots` are supplied or if neither is
      supplied.
    ValueError: If both `discount_rates` and `discount_factors` is supplied.
    ValueError: If both `dividend_rates` and `cost_of_carries` is
      supplied.
  """
  dividend_rates = deprecation.deprecated_argument_lookup(
      'dividend_rates', dividend_rates,
      'continuous_dividends', continuous_dividends)
  if (spots is None) == (forwards is None):
    raise ValueError('Either spots or forwards must be supplied but not both.')
  if (discount_rates is not None) and (discount_factors is not None):
    raise ValueError('At most one of discount_rates and discount_factors may '
                     'be supplied')
  if (dividend_rates is not None) and (cost_of_carries is not None):
    raise ValueError('At most one of dividend_rates and cost_of_carries '
                     'may be supplied')

  with tf.name_scope(name or 'asset_or_nothing_price'):
    strikes = tf.convert_to_tensor(strikes, dtype=dtype, name='strikes')
    dtype = strikes.dtype
    volatilities = tf.convert_to_tensor(
        volatilities, dtype=dtype, name='volatilities')
    expiries = tf.convert_to_tensor(expiries, dtype=dtype, name='expiries')

    if discount_rates is not None:
      discount_rates = tf.convert_to_tensor(
          discount_rates, dtype=dtype, name='discount_rates')
      discount_factors = tf.exp(-discount_rates * expiries)
    elif discount_factors is not None:
      discount_factors = tf.convert_to_tensor(
          discount_factors, dtype=dtype, name='discount_factors')
      discount_rates = -tf.math.log(discount_factors) / expiries
    else:
      discount_rates = tf.convert_to_tensor(
          0.0, dtype=dtype, name='discount_rates')
      discount_factors = tf.convert_to_tensor(
          1.0, dtype=dtype, name='discount_factors')

    if dividend_rates is None:
      dividend_rates = tf.convert_to_tensor(
          0.0, dtype=dtype, name='dividend_rates')

    if cost_of_carries is not None:
      cost_of_carries = tf.convert_to_tensor(
          cost_of_carries, dtype=dtype, name='cost_of_carries')
    else:
      cost_of_carries = discount_rates - dividend_rates

    if forwards is not None:
      forwards = tf.convert_to_tensor(forwards, dtype=dtype, name='forwards')
    else:
      spots = tf.convert_to_tensor(spots, dtype=dtype, name='spots')
      forwards = spots * tf.exp(cost_of_carries * expiries)

    sqrt_var = volatilities * tf.math.sqrt(expiries)

    if not is_normal_volatility:  # lognormal model
      d1 = tf.math.divide_no_nan(tf.math.log(forwards / strikes),
                                 sqrt_var) + sqrt_var / 2
      undiscounted_calls = tf.where(sqrt_var > 0, forwards * _ncdf(d1),
                                    tf.where(forwards > strikes, forwards, 0.))
    else:  # normal model
      d1 = tf.math.divide_no_nan((forwards - strikes), sqrt_var)
      undiscounted_calls = tf.where(
          sqrt_var > 0.0,
          forwards * _ncdf(d1) +
          sqrt_var * tf.math.exp(-0.5 * d1**2) / np.sqrt(2 * np.pi),
          tf.where(forwards > strikes, forwards, 0.))

    if is_call_options is None:
      return discount_factors * undiscounted_calls
    undiscounted_puts = forwards - undiscounted_calls
    predicate = tf.broadcast_to(is_call_options, tf.shape(undiscounted_calls))
    return discount_factors * tf.where(predicate, undiscounted_calls,
                                       undiscounted_puts)
コード例 #30
0
def mpusim_depthwise_conv2d(input,
                                filter,
                                strides,
                                padding,
                                rate=None,
                                name=None,
                                data_format=None,
                                dilations=None,
                                activations_datatype_size_byte=1,
                                weights_datatype_size_byte=1,
                                results_datatype_size_byte=4,
                                systolic_array_height=256,
                                systolic_array_width=256,
                                activation_fifo_depth=8,
                                accumulator_array_height=4096,
                                log_file_output_dir='.',
                                model_name='unnamed'):

    rate = deprecated_argument_lookup("dilations", dilations, "rate", rate)
    
    with ops.name_scope("mpusim_depthwise_conv2d", [input, filter]) as name:
        input = ops.convert_to_tensor(input, name="tensor_in")
        filter = ops.convert_to_tensor(filter, name="filter_in")
        
        if rate is None:
            rate = [1, 1]
            
        channels = input.get_shape().with_rank(4).dims[3]
        
        #print('Depthwise convolution shape: {}'.format(filter.get_shape()))

        def op(input_converted, _, padding):
            
            inputs = tf.split(input_converted, channels, 3)
            kernels = tf.split(filter, channels, 2)
                
            outputs = []
            convolution_count = 0
                
            for input_block, kernel_block in zip(inputs, kernels):
                
                with ops.name_scope("_{}".format(convolution_count)) as name:
                
                    channel_output = mpu_sim_conv2d_lib.mpu_sim_conv2d(input_block,
                                                                        kernel_block,
                                                                        activations_datatype_size_byte,
                                                                        weights_datatype_size_byte,
                                                                        results_datatype_size_byte,
                                                                        systolic_array_height,
                                                                        systolic_array_width,
                                                                        activation_fifo_depth,
                                                                        accumulator_array_height,
                                                                        log_file_output_dir,
                                                                        model_name,
                                                                        strides=strides,
                                                                        padding=padding)
                
                    outputs.append(channel_output)
                
                    convolution_count += 1
            
            return tf.concat(outputs, 3)

        return nn_ops.with_space_to_batch(input=input,
                                            filter_shape=array_ops.shape(filter),
                                            dilation_rate=rate,
                                            padding=padding,
                                            data_format=data_format,
                                            op=op)
コード例 #31
0
def norm(tensor,
         ord='euclidean',
         axis=None,
         keepdims=None,
         name=None,
         keep_dims=None):
  r"""Computes the norm of vectors, matrices, and tensors.

  This function can compute several different vector norms (the 1-norm, the
  Euclidean or 2-norm, the inf-norm, and in general the p-norm for p > 0) and
  matrix norms (Frobenius, 1-norm, and inf-norm).

  Args:
    tensor: `Tensor` of types `float32`, `float64`, `complex64`, `complex128`
    ord: Order of the norm. Supported values are 'fro', 'euclidean',
      `1`, `2`, `np.inf` and any positive real number yielding the corresponding
      p-norm. Default is 'euclidean' which is equivalent to Frobenius norm if
      `tensor` is a matrix and equivalent to 2-norm for vectors.
      Some restrictions apply:
        a) The Frobenius norm `fro` is not defined for vectors,
        b) If axis is a 2-tuple (matrix norm), only 'euclidean', 'fro', `1`,
           `np.inf` are supported.
      See the description of `axis` on how to compute norms for a batch of
      vectors or matrices stored in a tensor.
    axis: If `axis` is `None` (the default), the input is considered a vector
      and a single vector norm is computed over the entire set of values in the
      tensor, i.e. `norm(tensor, ord=ord)` is equivalent to
      `norm(reshape(tensor, [-1]), ord=ord)`.
      If `axis` is a Python integer, the input is considered a batch of vectors,
      and `axis` determines the axis in `tensor` over which to compute vector
      norms.
      If `axis` is a 2-tuple of Python integers it is considered a batch of
      matrices and `axis` determines the axes in `tensor` over which to compute
      a matrix norm.
      Negative indices are supported. Example: If you are passing a tensor that
      can be either a matrix or a batch of matrices at runtime, pass
      `axis=[-2,-1]` instead of `axis=None` to make sure that matrix norms are
      computed.
    keepdims: If True, the axis indicated in `axis` are kept with size 1.
      Otherwise, the dimensions in `axis` are removed from the output shape.
    name: The name of the op.
    keep_dims: Deprecated alias for `keepdims`.

  Returns:
    output: A `Tensor` of the same type as tensor, containing the vector or
      matrix norms. If `keepdims` is True then the rank of output is equal to
      the rank of `tensor`. Otherwise, if `axis` is none the output is a scalar,
      if `axis` is an integer, the rank of `output` is one less than the rank
      of `tensor`, if `axis` is a 2-tuple the rank of `output` is two less
      than the rank of `tensor`.

  Raises:
    ValueError: If `ord` or `axis` is invalid.

  @compatibility(numpy)
  Mostly equivalent to numpy.linalg.norm.
  Not supported: ord <= 0, 2-norm for matrices, nuclear norm.
  Other differences:
    a) If axis is `None`, treats the flattened `tensor` as a vector
     regardless of rank.
    b) Explicitly supports 'euclidean' norm as the default, including for
     higher order tensors.
  @end_compatibility
  """
  keepdims = deprecation.deprecated_argument_lookup('keepdims', keepdims,
                                                    'keep_dims', keep_dims)
  if keepdims is None:
    keepdims = False

  is_matrix_norm = ((isinstance(axis, tuple) or isinstance(axis, list)) and
                    len(axis) == 2)
  if is_matrix_norm:
    axis = tuple(axis)
    if (not isinstance(axis[0], int) or not isinstance(axis[1], int) or
        axis[0] == axis[1]):
      raise ValueError(
          "'axis' must be None, an integer, or a tuple of 2 unique integers")
    # TODO(rmlarsen): Implement matrix 2-norm using tf.svd().
    supported_matrix_norms = ['euclidean', 'fro', 1, np.inf]
    if ord not in supported_matrix_norms:
      raise ValueError("'ord' must be a supported matrix norm in %s, got %s" %
                       (supported_matrix_norms, ord))
  else:
    if not (isinstance(axis, int) or axis is None):
      raise ValueError(
          "'axis' must be None, an integer, or a tuple of 2 unique integers")

    supported_vector_norms = ['euclidean', 1, 2, np.inf]
    if (not np.isreal(ord) or ord <= 0) and ord not in supported_vector_norms:
      raise ValueError("'ord' must be a supported vector norm, got %s" % ord)
    if axis is not None:
      axis = (axis,)

  with ops.name_scope(name, 'norm', [tensor]):
    tensor = ops.convert_to_tensor(tensor)
    if ord in ['fro', 'euclidean', 2, 2.0]:
      # TODO(rmlarsen): Move 2-norm to a separate clause once we support it for
      # matrices.
      result = math_ops.sqrt(
          math_ops.reduce_sum(
              tensor * math_ops.conj(tensor), axis, keepdims=True))
    else:
      result = math_ops.abs(tensor)
      if ord == 1:
        sum_axis = None if axis is None else axis[0]
        result = math_ops.reduce_sum(result, sum_axis, keepdims=True)
        if is_matrix_norm:
          result = math_ops.reduce_max(result, axis[-1], keepdims=True)
      elif ord == np.inf:
        if is_matrix_norm:
          result = math_ops.reduce_sum(result, axis[1], keepdims=True)
        max_axis = None if axis is None else axis[0]
        result = math_ops.reduce_max(result, max_axis, keepdims=True)
      else:
        # General p-norms (positive p only)
        result = math_ops.pow(
            math_ops.reduce_sum(math_ops.pow(result, ord), axis, keepdims=True),
            1.0 / ord)
    if not keepdims:
      result = array_ops.squeeze(result, axis)
    return result
コード例 #32
0
def adesi_whaley(volatilities,
                 strikes,
                 expiries,
                 spots=None,
                 forwards=None,
                 discount_rates=None,
                 dividend_rates=None,
                 continuous_dividends=None,
                 discount_factors=None,
                 is_call_options=None,
                 max_iterations=100,
                 tolerance=1e-8,
                 dtype=None,
                 name=None):
    """Computes American option prices using the Baron-Adesi Whaley approximation.

  #### Example

  ```python
  spots = [80.0, 90.0, 100.0, 110.0, 120.0]
  strikes = [100.0, 100.0, 100.0, 100.0, 100.0]
  volatilities = [0.2, 0.2, 0.2, 0.2, 0.2]
  expiries = 0.25
  dividends = 0.12
  discount_rates = 0.08
  computed_prices = adesi_whaley(
      volatilities=volatilities,
      strikes=strikes,
      expiries=expiries,
      discount_rates=discount_rates,
      dividend_rates=dividends,
      spots=spots,
      dtype=tf.float64)
  # Expected print output of computed prices:
  # [0.03, 0.59, 3.52, 10.31, 20.0]
  ```

  #### References:
  [1] Baron-Adesi, Whaley, Efficient Analytic Approximation of American Option
    Values, The Journal of Finance, Vol XLII, No. 2, June 1987
    https://deriscope.com/docs/Barone_Adesi_Whaley_1987.pdf

  Args:
    volatilities: Real `Tensor` of any shape and dtype. The volatilities to
      expiry of the options to price.
    strikes: A real `Tensor` of the same dtype and compatible shape as
      `volatilities`. The strikes of the options to be priced.
    expiries: A real `Tensor` of same dtype and compatible shape as
      `volatilities`. The expiry of each option. The units should be such that
      `expiry * volatility**2` is dimensionless.
    spots: A real `Tensor` of any shape that broadcasts to the shape of the
      `volatilities`. The current spot price of the underlying. Either this
      argument or the `forwards` (but not both) must be supplied.
    forwards: A real `Tensor` of any shape that broadcasts to the shape of
      `volatilities`. The forwards to maturity. Either this argument or the
      `spots` must be supplied but both must not be supplied.
    discount_rates: An optional real `Tensor` of same dtype as the
      `volatilities`. If not `None`, discount factors are calculated as e^(-rT),
      where r are the discount rates, or risk free rates.
      Default value: `None`, equivalent to r = 0 and discount factors = 1 when
      discount_factors also not given.
    dividend_rates: An optional real `Tensor` of same dtype as the
      `volatilities`. The continuous dividend rate on the underliers. May be
      negative (to indicate costs of holding the underlier).
      Default value: `None`, equivalent to zero dividends.
    continuous_dividends: `Tensor` equivalent to `dividend_rates`, to be
      deprecated.
    discount_factors: An optional real `Tensor` of same dtype as the
      `volatilities`. If not `None`, these are the discount factors to expiry
      (i.e. e^(-rT)). Mutually exclusive with discount_rate.
      If neither is given, no discounting is applied (i.e. the undiscounted
      option price is returned). If `spots` is supplied and `discount_factors`
      is not `None` then this is also used to compute the forwards to expiry.
      At most one of discount_rates and discount_factors can be supplied.
      Default value: `None`, which maps to -log(discount_factors) / expiries
    is_call_options: A boolean `Tensor` of a shape compatible with
      `volatilities`. Indicates whether the option is a call (if True) or a put
      (if False). If not supplied, call options are assumed.
    max_iterations: positive `int`. The maximum number of iterations of Newton's
      root finding method to find the critical spot price above and below which
      the pricing formula is different.
      Default value: 100
    tolerance: Positive scalar `Tensor`. As with max_iterations, used with the
      Newton root finder to find the critical spot price. The root finder will
      judge an element to have converged if `|f(x_n) - a|` is less than
      `tolerance` (where `f` is the target function as defined in [1] and
      `x_n` is the estimated critical value), or if `x_n` becomes `nan`. When an
      element is judged to have converged it will no longer be updated. If all
      elements converge before `max_iterations` is reached then the root finder
      will return early.
      Default value: 1e-8
    dtype: Optional `tf.DType`. If supplied, the dtype to be used for conversion
      of any supplied non-`Tensor` arguments to `Tensor`.
      Default value: None which maps to the default dtype inferred by
       TensorFlow.
    name: str. The name for the ops created by this function.
      Default value: None which is mapped to the default name `adesi_whaley`.

  Returns:
    A 3-tuple containing the following items in order:
       (a) option_prices: A `Tensor` of the same shape as `forwards`. The Black
         Scholes price of the options.
       (b) converged: A boolean `Tensor` of the same shape as `option_prices`
         above. Indicates whether the corresponding adesi-whaley approximation
         has converged to within tolerance.
       (c) failed: A boolean `Tensor` of the same shape as `option_prices`
         above. Indicates whether the corresponding options price is NaN or not
         a finite number. Note that converged being True implies that failed
         will be false. However, it may happen that converged is False but
         failed is not True. This indicates the search did not converge in the
         permitted number of iterations but may converge if the iterations are
         increased.

  Raises:
    ValueError:
      (a) If both `forwards` and `spots` are supplied or if neither is supplied.
  """
    dividend_rates = deprecation.deprecated_argument_lookup(
        'dividend_rates', dividend_rates, 'continuous_dividends',
        continuous_dividends)
    if (spots is None) == (forwards is None):
        raise ValueError(
            'Either spots or forwards must be supplied but not both.')
    if (discount_rates is not None) and (discount_factors is not None):
        raise ValueError(
            'At most one of discount_rates and discount_factors may '
            'be supplied')
    with tf.name_scope(name or 'adesi_whaley'):
        volatilities = tf.convert_to_tensor(volatilities,
                                            dtype=dtype,
                                            name='volatilities')
        dtype = volatilities.dtype  # This dtype should be common for all inputs
        strikes = tf.convert_to_tensor(strikes, dtype=dtype, name='strikes')
        expiries = tf.convert_to_tensor(expiries, dtype=dtype, name='expiries')
        if discount_rates is not None:
            discount_rates = tf.convert_to_tensor(discount_rates,
                                                  dtype=dtype,
                                                  name='discount_rates')
        elif discount_factors is not None:
            discount_factors = tf.convert_to_tensor(discount_factors,
                                                    dtype=dtype,
                                                    name='discount_factors')
            discount_rates = -tf.math.log(discount_factors) / expiries
        else:
            discount_rates = tf.constant(0.0,
                                         dtype=dtype,
                                         name='discount_rates')

        if dividend_rates is not None:
            dividend_rates = tf.convert_to_tensor(dividend_rates,
                                                  dtype=dtype,
                                                  name='dividend_rates')
        else:
            dividend_rates = 0
        # Set forwards and spots
        if forwards is not None:
            spots = tf.convert_to_tensor(
                forwards *
                tf.exp(-(discount_rates - dividend_rates) * expiries),
                dtype=dtype,
                name='spots')
        else:
            spots = tf.convert_to_tensor(spots, dtype=dtype, name='spots')
        if is_call_options is not None:
            is_call_options = tf.convert_to_tensor(is_call_options,
                                                   dtype=tf.bool,
                                                   name='is_call_options')
        else:
            is_call_options = tf.constant(True, name='is_call_options')

        am_prices, converged, failed = _adesi_whaley(
            sigma=volatilities,
            x=strikes,
            t=expiries,
            s=spots,
            r=discount_rates,
            d=dividend_rates,
            is_call_options=is_call_options,
            dtype=dtype,
            max_iterations=max_iterations,
            tolerance=tolerance)

        # For call options where b >= r as per reference [1], only the European
        # option price should be calclated, while for the rest the american price
        # formula should be used. For this reason, the vanilla European price is
        # calculated for all the spot prices, (assuming they are all call options),
        # and a subset of these will be used further down, if any of the date points
        # fit the criteria that they are all call options with b >= r.
        eu_prices = vanilla_prices.option_price(volatilities=volatilities,
                                                strikes=strikes,
                                                expiries=expiries,
                                                spots=spots,
                                                discount_rates=discount_rates,
                                                dividend_rates=dividend_rates,
                                                dtype=dtype,
                                                name=name)
        calculate_eu = is_call_options & (dividend_rates <= 0)
        converged = tf.where(calculate_eu, True, converged)
        failed = tf.where(calculate_eu, False, failed)
        return tf.where(calculate_eu, eu_prices, am_prices), converged, failed
コード例 #33
0
ファイル: ctc_ops.py プロジェクト: adit-chandra/tensorflow
def ctc_loss(labels, inputs=None, sequence_length=None,
             preprocess_collapse_repeated=False,
             ctc_merge_repeated=True,
             ignore_longer_outputs_than_inputs=False, time_major=True,
             logits=None):
  """Computes the CTC (Connectionist Temporal Classification) Loss.

  This op implements the CTC loss as presented in the article:

  [A. Graves, S. Fernandez, F. Gomez, J. Schmidhuber.
  Connectionist Temporal Classification: Labeling Unsegmented Sequence Data
  with Recurrent Neural Networks. ICML 2006, Pittsburgh, USA,
  pp. 369-376.](http://www.cs.toronto.edu/~graves/icml_2006.pdf)

  Input requirements:

  ```
  sequence_length(b) <= time for all b

  max(labels.indices(labels.indices[:, 1] == b, 2))
    <= sequence_length(b) for all b.
  ```

  Notes:

  This class performs the softmax operation for you, so inputs should
  be e.g. linear projections of outputs by an LSTM.

  The `inputs` Tensor's innermost dimension size, `num_classes`, represents
  `num_labels + 1` classes, where num_labels is the number of true labels, and
  the largest value `(num_classes - 1)` is reserved for the blank label.

  For example, for a vocabulary containing 3 labels `[a, b, c]`,
  `num_classes = 4` and the labels indexing is `{a: 0, b: 1, c: 2, blank: 3}`.

  Regarding the arguments `preprocess_collapse_repeated` and
  `ctc_merge_repeated`:

  If `preprocess_collapse_repeated` is True, then a preprocessing step runs
  before loss calculation, wherein repeated labels passed to the loss
  are merged into single labels.  This is useful if the training labels come
  from, e.g., forced alignments and therefore have unnecessary repetitions.

  If `ctc_merge_repeated` is set False, then deep within the CTC calculation,
  repeated non-blank labels will not be merged and are interpreted
  as individual labels.  This is a simplified (non-standard) version of CTC.

  Here is a table of the (roughly) expected first order behavior:

  * `preprocess_collapse_repeated=False`, `ctc_merge_repeated=True`

    Classical CTC behavior: Outputs true repeated classes with blanks in
    between, and can also output repeated classes with no blanks in
    between that need to be collapsed by the decoder.

  * `preprocess_collapse_repeated=True`, `ctc_merge_repeated=False`

    Never learns to output repeated classes, as they are collapsed
    in the input labels before training.

  * `preprocess_collapse_repeated=False`, `ctc_merge_repeated=False`

    Outputs repeated classes with blanks in between, but generally does not
    require the decoder to collapse/merge repeated classes.

  * `preprocess_collapse_repeated=True`, `ctc_merge_repeated=True`

    Untested.  Very likely will not learn to output repeated classes.

  The `ignore_longer_outputs_than_inputs` option allows to specify the behavior
  of the CTCLoss when dealing with sequences that have longer outputs than
  inputs. If true, the CTCLoss will simply return zero gradient for those
  items, otherwise an InvalidArgument error is returned, stopping training.

  Args:
    labels: An `int32` `SparseTensor`.
      `labels.indices[i, :] == [b, t]` means `labels.values[i]` stores
      the id for (batch b, time t).
      `labels.values[i]` must take on values in `[0, num_labels)`.
      See `core/ops/ctc_ops.cc` for more details.
    inputs: 3-D `float` `Tensor`.
      If time_major == False, this will be a `Tensor` shaped:
        `[batch_size, max_time, num_classes]`.
      If time_major == True (default), this will be a `Tensor` shaped:
        `[max_time, batch_size, num_classes]`.
      The logits.
    sequence_length: 1-D `int32` vector, size `[batch_size]`.
      The sequence lengths.
    preprocess_collapse_repeated: Boolean.  Default: False.
      If True, repeated labels are collapsed prior to the CTC calculation.
    ctc_merge_repeated: Boolean.  Default: True.
    ignore_longer_outputs_than_inputs: Boolean. Default: False.
      If True, sequences with longer outputs than inputs will be ignored.
    time_major: The shape format of the `inputs` Tensors.
      If True, these `Tensors` must be shaped `[max_time, batch_size,
      num_classes]`.
      If False, these `Tensors` must be shaped `[batch_size, max_time,
      num_classes]`.
      Using `time_major = True` (default) is a bit more efficient because it
      avoids transposes at the beginning of the ctc_loss calculation.  However,
      most TensorFlow data is batch-major, so by this function also accepts
      inputs in batch-major form.
    logits: Alias for inputs.

  Returns:
    A 1-D `float` `Tensor`, size `[batch]`, containing the negative log
      probabilities.

  Raises:
    TypeError: if labels is not a `SparseTensor`.
  """
  # The second, third, etc output tensors contain the gradients.  We use it in
  # _CTCLossGrad() below.
  if not isinstance(labels, sparse_tensor.SparseTensor):
    raise TypeError("Expected labels (first argument) to be a SparseTensor")

  # For internal calculations, we transpose to [time, batch, num_classes]
  inputs = deprecation.deprecated_argument_lookup(
      "logits", logits, "inputs", inputs)
  if not time_major:
    inputs = array_ops.transpose(inputs, [1, 0, 2])  # (B,T,N) => (T,B,N)

  loss, _ = gen_ctc_ops.ctc_loss(
      inputs,
      labels.indices,
      labels.values,
      sequence_length,
      preprocess_collapse_repeated=preprocess_collapse_repeated,
      ctc_merge_repeated=ctc_merge_repeated,
      ignore_longer_outputs_than_inputs=ignore_longer_outputs_than_inputs)

  return loss
コード例 #34
0
def expand_dims(input, axis=None, name=None, dim=None):
    axis = deprecation.deprecated_argument_lookup("axis", axis, "dim", dim)
    return gen_array_ops.expand_dims(input, axis, name)
コード例 #35
0
def build_factored_surrogate_posterior(
    event_shape=None,
    bijector=None,
    constraining_bijectors=None,
    initial_unconstrained_loc=_sample_uniform_initial_loc,
    initial_unconstrained_scale=1e-2,
    trainable_distribution_fn=_build_trainable_normal_dist,
    seed=None,
    validate_args=False,
    name=None):
  """Builds a joint variational posterior that factors over model variables.

  By default, this method creates an independent trainable Normal distribution
  for each variable, transformed using a bijector (if provided) to
  match the support of that variable. This makes extremely strong
  assumptions about the posterior: that it is approximately normal (or
  transformed normal), and that all model variables are independent.

  Args:
    event_shape: `Tensor` shape, or nested structure of `Tensor` shapes,
      specifying the event shape(s) of the posterior variables.
    bijector: Optional `tfb.Bijector` instance, or nested structure of such
      instances, defining support(s) of the posterior variables. The structure
      must match that of `event_shape` and may contain `None` values. A
      posterior variable will be modeled as
      `tfd.TransformedDistribution(underlying_dist, bijector)` if a
      corresponding constraining bijector is specified, otherwise it is modeled
      as supported on the unconstrained real line.
    constraining_bijectors: Deprecated alias for `bijector`.
    initial_unconstrained_loc: Optional Python `callable` with signature
      `tensor = initial_unconstrained_loc(shape, seed)` used to sample
      real-valued initializations for the unconstrained representation of each
      variable. May alternately be a nested structure of
      `Tensor`s, giving specific initial locations for each variable; these
      must have structure matching `event_shape` and shapes determined by the
      inverse image of `event_shape` under `bijector`, which may optionally be
      prefixed with a common batch shape.
      Default value: `functools.partial(tf.random.uniform,
        minval=-2., maxval=2., dtype=tf.float32)`.
    initial_unconstrained_scale: Optional scalar float `Tensor` initial
      scale for the unconstrained distributions, or a nested structure of
      `Tensor` initial scales for each variable.
      Default value: `1e-2`.
    trainable_distribution_fn: Optional Python `callable` with signature
      `trainable_dist = trainable_distribution_fn(initial_loc, initial_scale,
      event_ndims, validate_args)`. This is called for each model variable to
      build the corresponding factor in the surrogate posterior. It is expected
      that the distribution returned is supported on unconstrained real values.
      Default value: `functools.partial(
        tfp.experimental.vi.build_trainable_location_scale_distribution,
        distribution_fn=tfd.Normal)`, i.e., a trainable Normal distribution.
    seed: Python integer to seed the random number generator. This is used
      only when `initial_loc` is not specified.
    validate_args: Python `bool`. Whether to validate input with asserts. This
      imposes a runtime cost. If `validate_args` is `False`, and the inputs are
      invalid, correct behavior is not guaranteed.
      Default value: `False`.
    name: Python `str` name prefixed to ops created by this function.
      Default value: `None` (i.e., 'build_factored_surrogate_posterior').

  Returns:
    surrogate_posterior: A `tfd.Distribution` instance whose samples have
      shape and structure matching that of `event_shape` or `initial_loc`.

  ### Examples

  Consider a Gamma model with unknown parameters, expressed as a joint
  Distribution:

  ```python
  Root = tfd.JointDistributionCoroutine.Root
  def model_fn():
    concentration = yield Root(tfd.Exponential(1.))
    rate = yield Root(tfd.Exponential(1.))
    y = yield tfd.Sample(tfd.Gamma(concentration=concentration, rate=rate),
                         sample_shape=4)
  model = tfd.JointDistributionCoroutine(model_fn)
  ```

  Let's use variational inference to approximate the posterior over the
  data-generating parameters for some observed `y`. We'll build a
  surrogate posterior distribution by specifying the shapes of the latent
  `rate` and `concentration` parameters, and that both are constrained to
  be positive.

  ```python
  surrogate_posterior = tfp.experimental.vi.build_factored_surrogate_posterior(
    event_shape=model.event_shape_tensor()[:-1],  # Omit the observed `y`.
    bijector=[tfb.Softplus(),   # Rate is positive.
              tfb.Softplus()])  # Concentration is positive.
  ```

  This creates a trainable joint distribution, defined by variables in
  `surrogate_posterior.trainable_variables`. We use `fit_surrogate_posterior`
  to fit this distribution by minimizing a divergence to the true posterior.

  ```python
  y = [0.2, 0.5, 0.3, 0.7]
  losses = tfp.vi.fit_surrogate_posterior(
    lambda rate, concentration: model.log_prob([rate, concentration, y]),
    surrogate_posterior=surrogate_posterior,
    num_steps=100,
    optimizer=tf.optimizers.Adam(0.1),
    sample_size=10)

  # After optimization, samples from the surrogate will approximate
  # samples from the true posterior.
  samples = surrogate_posterior.sample(100)
  posterior_mean = [tf.reduce_mean(x) for x in samples]     # mean ~= [1.1, 2.1]
  posterior_std = [tf.math.reduce_std(x) for x in samples]  # std  ~= [0.3, 0.8]
  ```

  If we wanted to initialize the optimization at a specific location, we can
  specify one when we build the surrogate posterior. This function requires the
  initial location to be specified in *unconstrained* space; we do this by
  inverting the constraining bijectors (note this section also demonstrates the
  creation of a dict-structured model).

  ```python
  initial_loc = {'concentration': 0.4, 'rate': 0.2}
  bijector={'concentration': tfb.Softplus(),   # Rate is positive.
            'rate': tfb.Softplus()}   # Concentration is positive.
  initial_unconstrained_loc = tf.nest.map_fn(
    lambda b, x: b.inverse(x) if b is not None else x, bijector, initial_loc)
  surrogate_posterior = tfp.experimental.vi.build_factored_surrogate_posterior(
    event_shape=tf.nest.map_fn(tf.shape, initial_loc),
    bijector=bijector,
    initial_unconstrained_loc=initial_unconstrained_state,
    initial_unconstrained_scale=1e-4)
  ```

  """

  with tf.name_scope(name or 'build_factored_surrogate_posterior'):
    bijector = deprecation.deprecated_argument_lookup(
        'bijector', bijector, 'constraining_bijectors', constraining_bijectors)

    seed = tfp_util.SeedStream(seed, salt='build_factored_surrogate_posterior')

    # Convert event shapes to Tensors.
    shallow_structure = _get_event_shape_shallow_structure(event_shape)
    event_shape = nest.map_structure_up_to(
        shallow_structure, lambda s: tf.convert_to_tensor(s, dtype=tf.int32),
        event_shape)

    if nest.is_nested(bijector):
      bijector = nest.map_structure(
          lambda b: identity.Identity() if b is None else b,
          bijector)

      # Support mismatched nested structures for backwards compatibility (e.g.
      # non-nested `event_shape` and a single-element list of `bijector`s).
      bijector = nest.pack_sequence_as(event_shape, nest.flatten(bijector))

      event_space_bijector = joint_map.JointMap(
          bijector, validate_args=validate_args)
    else:
      event_space_bijector = bijector

    if event_space_bijector is None:
      unconstrained_event_shape = event_shape
    else:
      unconstrained_event_shape = (
          event_space_bijector.inverse_event_shape_tensor(event_shape))

    # Construct initial locations for the internal unconstrained dists.
    if callable(initial_unconstrained_loc):  # Sample random initialization.
      initial_unconstrained_loc = nest.map_structure(
          lambda s: initial_unconstrained_loc(shape=s, seed=seed()),
          unconstrained_event_shape)

    if not nest.is_nested(initial_unconstrained_scale):
      initial_unconstrained_scale = nest.map_structure(
          lambda _: initial_unconstrained_scale,
          unconstrained_event_shape)

    # Extract the rank of each event, so that we build distributions with the
    # correct event shapes.
    unconstrained_event_ndims = nest.map_structure(
        ps.rank_from_shape,
        unconstrained_event_shape)

    # Build the component surrogate posteriors.
    unconstrained_distributions = nest.map_structure_up_to(
        unconstrained_event_shape,
        lambda loc, scale, ndims: trainable_distribution_fn(  # pylint: disable=g-long-lambda
            loc, scale, ndims, validate_args=validate_args),
        initial_unconstrained_loc,
        initial_unconstrained_scale,
        unconstrained_event_ndims)

    base_distribution = (
        joint_distribution_util.independent_joint_distribution_from_structure(
            unconstrained_distributions, validate_args=validate_args))
    if event_space_bijector is None:
      return base_distribution
    return transformed_distribution.TransformedDistribution(
        base_distribution, event_space_bijector)
コード例 #36
0
def norm(tensor,
         ord='euclidean',
         axis=None,
         keepdims=None,
         name=None,
         keep_dims=None):
  r"""Computes the norm of vectors, matrices, and tensors.

  This function can compute several different vector norms (the 1-norm, the
  Euclidean or 2-norm, the inf-norm, and in general the p-norm for p > 0) and
  matrix norms (Frobenius, 1-norm, 2-norm and inf-norm).

  Args:
    tensor: `Tensor` of types `float32`, `float64`, `complex64`, `complex128`
    ord: Order of the norm. Supported values are 'fro', 'euclidean',
      `1`, `2`, `np.inf` and any positive real number yielding the corresponding
      p-norm. Default is 'euclidean' which is equivalent to Frobenius norm if
      `tensor` is a matrix and equivalent to 2-norm for vectors.
      Some restrictions apply:
        a) The Frobenius norm `fro` is not defined for vectors,
        b) If axis is a 2-tuple (matrix norm), only 'euclidean', 'fro', `1`,
           `2`, `np.inf` are supported.
      See the description of `axis` on how to compute norms for a batch of
      vectors or matrices stored in a tensor.
    axis: If `axis` is `None` (the default), the input is considered a vector
      and a single vector norm is computed over the entire set of values in the
      tensor, i.e. `norm(tensor, ord=ord)` is equivalent to
      `norm(reshape(tensor, [-1]), ord=ord)`.
      If `axis` is a Python integer, the input is considered a batch of vectors,
      and `axis` determines the axis in `tensor` over which to compute vector
      norms.
      If `axis` is a 2-tuple of Python integers it is considered a batch of
      matrices and `axis` determines the axes in `tensor` over which to compute
      a matrix norm.
      Negative indices are supported. Example: If you are passing a tensor that
      can be either a matrix or a batch of matrices at runtime, pass
      `axis=[-2,-1]` instead of `axis=None` to make sure that matrix norms are
      computed.
    keepdims: If True, the axis indicated in `axis` are kept with size 1.
      Otherwise, the dimensions in `axis` are removed from the output shape.
    name: The name of the op.
    keep_dims: Deprecated alias for `keepdims`.

  Returns:
    output: A `Tensor` of the same type as tensor, containing the vector or
      matrix norms. If `keepdims` is True then the rank of output is equal to
      the rank of `tensor`. Otherwise, if `axis` is none the output is a scalar,
      if `axis` is an integer, the rank of `output` is one less than the rank
      of `tensor`, if `axis` is a 2-tuple the rank of `output` is two less
      than the rank of `tensor`.

  Raises:
    ValueError: If `ord` or `axis` is invalid.

  @compatibility(numpy)
  Mostly equivalent to numpy.linalg.norm.
  Not supported: ord <= 0, 2-norm for matrices, nuclear norm.
  Other differences:
    a) If axis is `None`, treats the flattened `tensor` as a vector
     regardless of rank.
    b) Explicitly supports 'euclidean' norm as the default, including for
     higher order tensors.
  @end_compatibility
  """
  keepdims = deprecation.deprecated_argument_lookup('keepdims', keepdims,
                                                    'keep_dims', keep_dims)
  if keepdims is None:
    keepdims = False

  is_matrix_norm = ((isinstance(axis, tuple) or isinstance(axis, list)) and
                    len(axis) == 2)
  if is_matrix_norm:
    axis = tuple(axis)
    if (not isinstance(axis[0], int) or not isinstance(axis[1], int) or
        axis[0] == axis[1]):
      raise ValueError(
          "'axis' must be None, an integer, or a tuple of 2 unique integers")
    supported_matrix_norms = ['euclidean', 'fro', 1, 2, np.inf]
    if ord not in supported_matrix_norms:
      raise ValueError("'ord' must be a supported matrix norm in %s, got %s" %
                       (supported_matrix_norms, ord))
  else:
    if not (isinstance(axis, int) or axis is None):
      raise ValueError(
          "'axis' must be None, an integer, or a tuple of 2 unique integers")

    supported_vector_norms = ['euclidean', 1, 2, np.inf]
    if (not np.isreal(ord) or ord <= 0) and ord not in supported_vector_norms:
      raise ValueError("'ord' must be a supported vector norm, got %s" % ord)
    if axis is not None:
      axis = (axis,)

  with ops.name_scope(name, 'norm', [tensor]):
    tensor = ops.convert_to_tensor(tensor)

    if ord in ['fro', 'euclidean', 2, 2.0]:
      if is_matrix_norm and ord in [2, 2.0]:
        rank = array_ops.rank(tensor)
        positive_axis = map_fn.map_fn(
            lambda i: control_flow_ops.cond(i >= 0, lambda: i, lambda: i + rank),
            ops.convert_to_tensor(axis))
        axes = math_ops.range(rank)
        perm_before = array_ops.concat(
            [array_ops.setdiff1d(axes, positive_axis)[0], positive_axis],
            axis=0)
        perm_after = map_fn.map_fn(
            lambda i: math_ops.cast(
                array_ops.squeeze(
                    array_ops.where(math_ops.equal(perm_before, i))),
                dtype=dtypes.int32), axes)
        permed = array_ops.transpose(tensor, perm=perm_before)
        matrix_2_norm = array_ops.expand_dims(
            math_ops.reduce_max(
                math_ops.abs(gen_linalg_ops.svd(permed, compute_uv=False)[0]),
                axis=-1,
                keepdims=True),
            axis=-1)
        result = array_ops.transpose(matrix_2_norm, perm=perm_after)
      else:
        result = math_ops.sqrt(
            math_ops.reduce_sum(
                tensor * math_ops.conj(tensor), axis, keepdims=True))
    else:
      result = math_ops.abs(tensor)
      if ord == 1:
        sum_axis = None if axis is None else axis[0]
        result = math_ops.reduce_sum(result, sum_axis, keepdims=True)
        if is_matrix_norm:
          result = math_ops.reduce_max(result, axis[-1], keepdims=True)
      elif ord == np.inf:
        if is_matrix_norm:
          result = math_ops.reduce_sum(result, axis[1], keepdims=True)
        max_axis = None if axis is None else axis[0]
        result = math_ops.reduce_max(result, max_axis, keepdims=True)
      else:
        # General p-norms (positive p only)
        result = math_ops.pow(
            math_ops.reduce_sum(math_ops.pow(result, ord), axis, keepdims=True),
            1.0 / ord)
    if not keepdims:
      result = array_ops.squeeze(result, axis)
    return result
コード例 #37
0
def _ragged_squeeze_v1(input, axis=None, name=None, squeeze_dims=None):  # pylint: disable=redefined-builtin
  axis = deprecation.deprecated_argument_lookup('axis', axis, 'squeeze_dims',
                                                squeeze_dims)
  return ragged_squeeze_op.squeeze(input, axis, name)
コード例 #38
0
def barrier_price(volatilities,
                  strikes,
                  expiries,
                  spots,
                  barriers,
                  rebates=None,
                  discount_rates=None,
                  dividend_rates=None,
                  continuous_dividends=None,
                  cost_of_carries=None,
                  is_barrier_down=None,
                  is_knock_out=None,
                  is_call_options=None,
                  dtype=None,
                  name=None):
  """Prices barrier options in a Black-Scholes Model.

  Computes the prices of options with a single barrier in Black-Scholes world as
  described in Ref. [1]. Note that the barrier is applied continuously.

  #### Example

  This example is taken from Ref. [2], Page 154.

  ```python
  import tf_quant_finance as tff

  dtype = np.float32
  discount_rates = np.array([.08, .08])
  dividend_rates = np.array([.04, .04])
  spots = np.array([100., 100.])
  strikes = np.array([90., 90.])
  barriers = np.array([95. 95.])
  rebates = np.array([3. 3.])
  volatilities = np.array([.25, .25])
  expiries = np.array([.5, .5])
  barriers_type = np.array([5, 1])
  is_barrier_down = np.array([True, False])
  is_knock_out = np.array([False, False])
  is_call_option = np.array([True, True])

  price = tff.black_scholes.barrier_price(
    discount_rates, dividend_rates, spots, strikes,
    barriers, rebates, volatilities,
    expiries, is_barrier_down, is_knock_out, is_call_options)

  # Expected output
  #  `Tensor` with values [9.024, 7.7627]
  ```

  #### References

  [1]: Lee Clewlow, Javier Llanos, Chris Strickland, Caracas Venezuela
    Pricing Exotic Options in a Black-Scholes World, 1994
    https://warwick.ac.uk/fac/soc/wbs/subjects/finance/research/wpaperseries/1994/94-54.pdf
  [2]: Espen Gaarder Haug, The Complete Guide to Option Pricing Formulas,
    2nd Edition, 1997

  Args:
    volatilities: Real `Tensor` of any shape and dtype. The volatilities to
      expiry of the options to price.
    strikes: A real `Tensor` of the same dtype and compatible shape as
      `volatilities`. The strikes of the options to be priced.
    expiries: A real `Tensor` of same dtype and compatible shape as
      `volatilities`. The expiry of each option. The units should be such that
      `expiry * volatility**2` is dimensionless.
    spots: A real `Tensor` of any shape that broadcasts to the shape of the
      `volatilities`. The current spot price of the underlying.
    barriers: A real `Tensor` of same dtype as the `volatilities` and of the
      shape that broadcasts with `volatilities`. The barriers of each option.
    rebates: A real `Tensor` of same dtype as the `volatilities` and of the
      shape that broadcasts with `volatilities`. For knockouts, this is a
      fixed cash payout in case the barrier is breached. For knockins, this is a
      fixed cash payout in case the barrier level is not breached. In the former
      case, the rebate is paid immediately on breach whereas in the latter, the
      rebate is paid at the expiry of the option.
      Default value: `None` which maps to no rebates.
    discount_rates: A real `Tensor` of same dtype as the
      `volatilities` and of the shape that broadcasts with `volatilities`.
      Discount rates, or risk free rates.
      Default value: `None`, equivalent to discount_rate = 0.
    dividend_rates: A real `Tensor` of same dtype as the
      `volatilities` and of the shape that broadcasts with `volatilities`. A
      continuous dividend rate paid by the underlier. If `None`, then
      defaults to zero dividends.
      Default value: `None`, equivalent to zero dividends.
    continuous_dividends: `Tensor` equivalent to `dividend_rates`, to be
      deprecated.
    cost_of_carries: A optional real `Tensor` of same dtype as the
      `volatilities` and of the shape that broadcasts with `volatilities`.
      Cost of storing a physical commodity, the cost of interest paid when
      long, or the opportunity cost, or the cost of paying dividends when short.
      If not `None`, `dividend_rates` is calculated as r - c,
      where r are the `discount_rates` and c is `cost_of_carries`.
    is_barrier_down: A real `Tensor` of `boolean` values and of the shape
      that broadcasts with `volatilities`. True if barrier is below asset
      price at expiration.
      Default value: `True`.
    is_knock_out: A real `Tensor` of `boolean` values and of the shape
      that broadcasts with `volatilities`. True if option is knock out
      else false.
      Default value: `True`.
    is_call_options: A real `Tensor` of `boolean` values and of the shape
      that broadcasts with `volatilities`. True if option is call else
      false.
      Default value: `True`.
    dtype: Optional `tf.DType`. If supplied, the dtype to be used for conversion
      of any supplied non-`Tensor` arguments to `Tensor`.
      Default value: `None` which maps to the default dtype inferred by
      TensorFlow.
    name: str. The name for the ops created by this function.
      Default value: `None` which is mapped to the default name `barrier_price`.
  Returns:
    option_prices: A `Tensor` of same shape as `spots`. The approximate price of
    the barriers option under black scholes.
  """
  # The computation is done as in Ref [2] where each integral is split into
  # two matrices. The first matrix contains the algebraic terms and the second
  # matrix contains the probability distribution terms. Masks are used to filter
  # appropriate terms for calculating the integral. Then a dot product of each
  # row in the matricies coupled with the masks work to calculate the prices of
  # the barriers option.
  dividend_rates = deprecation.deprecated_argument_lookup(
      'dividend_rates', dividend_rates,
      'continuous_dividends', continuous_dividends)
  if (dividend_rates is not None) and (cost_of_carries is not None):
    raise ValueError('At most one of dividend_rates and cost of carries '
                     'may be supplied')
  with tf.name_scope(name or 'barrier_price'):
    spots = tf.convert_to_tensor(spots, dtype=dtype, name='spots')
    dtype = spots.dtype
    strikes = tf.convert_to_tensor(strikes, dtype=dtype, name='strikes')
    volatilities = tf.convert_to_tensor(
        volatilities, dtype=dtype, name='volatilities')
    expiries = tf.convert_to_tensor(expiries, dtype=dtype, name='expiries')
    barriers = tf.convert_to_tensor(barriers, dtype=dtype, name='barriers')
    if rebates is not None:
      rebates = tf.convert_to_tensor(rebates, dtype=dtype, name='rebates')
    else:
      rebates = tf.zeros_like(spots, dtype=dtype, name='rebates')

    # Convert all to tensor and enforce float dtype where required
    if discount_rates is not None:
      discount_rates = tf.convert_to_tensor(
          discount_rates, dtype=dtype, name='discount_rates')
    else:
      discount_rates = tf.convert_to_tensor(
          0.0, dtype=dtype, name='discount_rates')

    if dividend_rates is None:
      dividend_rates = tf.convert_to_tensor(
          0.0, dtype=dtype, name='dividend_rates')

    if cost_of_carries is not None:
      cost_of_carries = tf.convert_to_tensor(
          cost_of_carries, dtype=dtype, name='cost_of_carries')
    else:
      cost_of_carries = discount_rates - dividend_rates

    if is_barrier_down is None:
      is_barrier_down = tf.constant(1, name='is_barrier_down')
    else:
      is_barrier_down = tf.convert_to_tensor(is_barrier_down, dtype=tf.bool,
                                             name='is_barrier_down')
      is_barrier_down = tf.where(is_barrier_down, 1, 0)
    if is_knock_out is None:
      is_knock_out = tf.constant(1, name='is_knock_out')
    else:
      is_knock_out = tf.convert_to_tensor(is_knock_out, dtype=tf.bool,
                                          name='is_knock_out')
      is_knock_out = tf.where(is_knock_out, 1, 0)
    if is_call_options is None:
      is_call_options = tf.constant(1, name='is_call_options')
    else:
      is_call_options = tf.convert_to_tensor(is_call_options, dtype=tf.bool,
                                             name='is_call_options')
      is_call_options = tf.where(is_call_options, 1, 0)

    # Indices which range from 0-7 are used to select the appropriate
    # mask for each barrier
    indices = tf.bitwise.left_shift(
        is_barrier_down, 2) + tf.bitwise.left_shift(
            is_knock_out, 1) + is_call_options

    # Masks select the appropriate terms for integral approximations
    # Integrals are seperated by algebraic terms and probability
    # distribution terms. This give 12 different terms per matrix
    # (6 integrals, 2 terms each)
    # shape = [8, 12]
    mask_matrix_greater_strike = tf.constant([
        [1, 1, -1, -1, 0, 0, 1, 1, 1, 1, 0, 0],  # up and in put
        [1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0],  # up and in call
        [0, 0, 1, 1, 0, 0, -1, -1, 0, 0, 1, 1],  # up and out put
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],  # up and out call
        [0, 0, 1, 1, -1, -1, 1, 1, 0, 0, 1, 1],  # down and in put
        [0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0],  # down and in call
        [1, 1, -1, -1, 1, 1, -1, -1, 0, 0, 1, 1],  # down and out put
        [1, 1, 0, 0, -1, -1, 0, 0, 0, 0, 1, 1]])  # down and out call

    mask_matrix_lower_strike = tf.constant([
        [0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0],  # up and in put
        [0, 0, 1, 1, -1, -1, 1, 1, 1, 1, 0, 0],  # up and in call
        [1, 1, 0, 0, -1, -1, 0, 0, 0, 0, 1, 1],  # up and out put
        [1, 1, -1, -1, 1, 1, -1, -1, 0, 0, 1, 1],  # up and out call
        [1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0],  # down and in put
        [1, 1, -1, -1, 0, 0, 1, 1, 1, 1, 0, 0],  # down and in call
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],  # down and out put
        [0, 0, 1, 1, 0, 0, -1, -1, 0, 0, 1, 1]])  # down and out call

    # Create masks
    # Masks are shape [strikes.shape, 12]
    masks_lower = tf.gather(mask_matrix_lower_strike, indices, axis=0)
    masks_greater = tf.gather(mask_matrix_greater_strike, indices, axis=0)
    strikes_greater = tf.expand_dims(strikes > barriers, axis=-1)
    masks = tf.where(strikes_greater, masks_greater, masks_lower)
    masks = tf.cast(masks, dtype=dtype)
    one = tf.constant(1, dtype=dtype)
    call_or_put = tf.cast(tf.where(tf.equal(is_call_options, 0), -one, one),
                          dtype=dtype)
    below_or_above = tf.cast(tf.where(tf.equal(is_barrier_down, 0), -one, one),
                             dtype=dtype)

    # Calculate params for integrals
    sqrt_var = volatilities * tf.math.sqrt(expiries)
    mu = (cost_of_carries) - ((volatilities**2) / 2)
    lamda = 1 + (mu / (volatilities**2))
    x = (tf.math.log(spots / strikes) / (sqrt_var)) + (lamda * sqrt_var)
    x1 = (tf.math.log(spots / barriers) / (sqrt_var)) + (lamda * sqrt_var)
    y = (tf.math.log((barriers**2) / (spots * strikes)) / (
        sqrt_var)) + (lamda * sqrt_var)
    y1 = (tf.math.log(barriers / spots) / (sqrt_var)) + (lamda * sqrt_var)
    b = ((mu**2) + (2 * (volatilities**2) * discount_rates)) / (volatilities**2)
    z = (tf.math.log(barriers / spots) / (sqrt_var)) + (b * sqrt_var)
    a = mu / (volatilities**2)

    # Other params used for integrals
    discount_rates_exponent = tf.math.exp(-discount_rates * expiries,  # pylint: disable=invalid-unary-operand-type
                                          name='discount_rates_exponent')
    continuous_dividends_exponent = tf.math.exp(
        (cost_of_carries - discount_rates) * expiries,
        name='continuous_dividends_exponent')
    barriers_ratio = tf.math.divide(barriers, spots, name='barriers_ratio')
    spots_term = call_or_put * spots * continuous_dividends_exponent
    strikes_term = call_or_put * strikes * discount_rates_exponent

    # rank is used to stack elements and reduce_sum
    strike_rank = strikes.shape.rank

    # Constructing Matrix with first and second algebraic terms for each
    # integral [strike.shape, 12]
    terms_mat = tf.stack(
        (spots_term, -strikes_term,
         spots_term, -strikes_term,
         spots_term * (barriers_ratio**(2 * lamda)),
         -strikes_term * (barriers_ratio**((2 * lamda) - 2)),
         spots_term * (barriers_ratio**(2 * lamda)),
         -strikes_term * (barriers_ratio**((2 * lamda) - 2)),
         rebates * discount_rates_exponent,
         -rebates * discount_rates_exponent * (  # pylint: disable=invalid-unary-operand-type
             barriers_ratio**((2 * lamda) - 2)),
         rebates * (barriers_ratio**(a + b)),
         rebates * (barriers_ratio**(a - b))),
        name='term_matrix', axis=strike_rank)

    # Constructing Matrix with first and second norm for each integral
    # [strikes.shape, 12]
    cdf_mat = tf.stack(
        (call_or_put * x,
         call_or_put * (x - sqrt_var),
         call_or_put * x1,
         call_or_put * (x1 - sqrt_var),
         below_or_above * y,
         below_or_above * (y - sqrt_var),
         below_or_above * y1,
         below_or_above * (y1 - sqrt_var),
         below_or_above * (x1 - sqrt_var),
         below_or_above * (y1 - sqrt_var),
         below_or_above * z,
         below_or_above * (z - (2 * b * sqrt_var))),
        name='cdf_matrix', axis=strike_rank)
    cdf_mat = _ncdf(cdf_mat)
    # Calculating and returning price for each option
    return tf.reduce_sum(masks * terms_mat * cdf_mat, axis=strike_rank)
コード例 #39
0
ファイル: ctc_ops.py プロジェクト: flavz27/master_PA
def ctc_loss(labels,
             inputs=None,
             sequence_length=None,
             preprocess_collapse_repeated=False,
             ctc_merge_repeated=True,
             ignore_longer_outputs_than_inputs=False,
             time_major=True,
             logits=None):
    """Computes the CTC (Connectionist Temporal Classification) Loss.

  This op implements the CTC loss as presented in the article:

  [A. Graves, S. Fernandez, F. Gomez, J. Schmidhuber.
  Connectionist Temporal Classification: Labeling Unsegmented Sequence Data
  with Recurrent Neural Networks. ICML 2006, Pittsburgh, USA,
  pp. 369-376.](http://www.cs.toronto.edu/~graves/icml_2006.pdf)

  Input requirements:

  ```
  sequence_length(b) <= time for all b

  max(labels.indices(labels.indices[:, 1] == b, 2))
    <= sequence_length(b) for all b.
  ```

  Notes:

  This class performs the softmax operation for you, so inputs should
  be e.g. linear projections of outputs by an LSTM.

  The `inputs` Tensor's innermost dimension size, `num_classes`, represents
  `num_labels + 1` classes, where num_labels is the number of true labels, and
  the largest value `(num_classes - 1)` is reserved for the blank label.

  For example, for a vocabulary containing 3 labels `[a, b, c]`,
  `num_classes = 4` and the labels indexing is `{a: 0, b: 1, c: 2, blank: 3}`.

  Regarding the arguments `preprocess_collapse_repeated` and
  `ctc_merge_repeated`:

  If `preprocess_collapse_repeated` is True, then a preprocessing step runs
  before loss calculation, wherein repeated labels passed to the loss
  are merged into single labels.  This is useful if the training labels come
  from, e.g., forced alignments and therefore have unnecessary repetitions.

  If `ctc_merge_repeated` is set False, then deep within the CTC calculation,
  repeated non-blank labels will not be merged and are interpreted
  as individual labels.  This is a simplified (non-standard) version of CTC.

  Here is a table of the (roughly) expected first order behavior:

  * `preprocess_collapse_repeated=False`, `ctc_merge_repeated=True`

    Classical CTC behavior: Outputs true repeated classes with blanks in
    between, and can also output repeated classes with no blanks in
    between that need to be collapsed by the decoder.

  * `preprocess_collapse_repeated=True`, `ctc_merge_repeated=False`

    Never learns to output repeated classes, as they are collapsed
    in the input labels before training.

  * `preprocess_collapse_repeated=False`, `ctc_merge_repeated=False`

    Outputs repeated classes with blanks in between, but generally does not
    require the decoder to collapse/merge repeated classes.

  * `preprocess_collapse_repeated=True`, `ctc_merge_repeated=True`

    Untested.  Very likely will not learn to output repeated classes.

  The `ignore_longer_outputs_than_inputs` option allows to specify the behavior
  of the CTCLoss when dealing with sequences that have longer outputs than
  inputs. If true, the CTCLoss will simply return zero gradient for those
  items, otherwise an InvalidArgument error is returned, stopping training.

  Args:
    labels: An `int32` `SparseTensor`.
      `labels.indices[i, :] == [b, t]` means `labels.values[i]` stores the id
        for (batch b, time t). `labels.values[i]` must take on values in `[0,
        num_labels)`. See `core/ops/ctc_ops.cc` for more details.
    inputs: 3-D `float` `Tensor`.
      If time_major == False, this will be a `Tensor` shaped: `[batch_size,
        max_time, num_classes]`.
      If time_major == True (default), this will be a `Tensor` shaped:
        `[max_time, batch_size, num_classes]`. The logits.
    sequence_length: 1-D `int32` vector, size `[batch_size]`. The sequence
      lengths.
    preprocess_collapse_repeated: Boolean.  Default: False. If True, repeated
      labels are collapsed prior to the CTC calculation.
    ctc_merge_repeated: Boolean.  Default: True.
    ignore_longer_outputs_than_inputs: Boolean. Default: False. If True,
      sequences with longer outputs than inputs will be ignored.
    time_major: The shape format of the `inputs` Tensors. If True, these
      `Tensors` must be shaped `[max_time, batch_size, num_classes]`. If False,
      these `Tensors` must be shaped `[batch_size, max_time, num_classes]`.
      Using `time_major = True` (default) is a bit more efficient because it
      avoids transposes at the beginning of the ctc_loss calculation.  However,
      most TensorFlow data is batch-major, so by this function also accepts
      inputs in batch-major form.
    logits: Alias for inputs.

  Returns:
    A 1-D `float` `Tensor`, size `[batch]`, containing the negative log
      probabilities.

  Raises:
    TypeError: if labels is not a `SparseTensor`.
  """
    # The second, third, etc output tensors contain the gradients.  We use it in
    # _CTCLossGrad() below.
    if not isinstance(labels, sparse_tensor.SparseTensor):
        raise TypeError(
            "Expected labels (first argument) to be a SparseTensor")

    # For internal calculations, we transpose to [time, batch, num_classes]
    inputs = deprecation.deprecated_argument_lookup("logits", logits, "inputs",
                                                    inputs)
    if not time_major:
        inputs = array_ops.transpose(inputs, [1, 0, 2])  # (B,T,N) => (T,B,N)

    loss, _ = gen_ctc_ops.ctc_loss(
        inputs,
        labels.indices,
        labels.values,
        sequence_length,
        preprocess_collapse_repeated=preprocess_collapse_repeated,
        ctc_merge_repeated=ctc_merge_repeated,
        ignore_longer_outputs_than_inputs=ignore_longer_outputs_than_inputs)

    return loss
コード例 #40
0
def strings_split_v1(
        input=None,
        sep=None,
        maxsplit=-1,  # pylint: disable=redefined-builtin
        result_type="SparseTensor",
        source=None,
        name=None):
    """Split elements of `input` based on `sep`.

  Let N be the size of `input` (typically N will be the batch size). Split each
  element of `input` based on `sep` and return a `SparseTensor` or
  `RaggedTensor` containing the split tokens. Empty tokens are ignored.

  Examples:

  ```python
  >>> tf.strings.split(['hello world', 'a b c'])
  tf.SparseTensor(indices=[[0, 0], [0, 1], [1, 0], [1, 1], [1, 2]],
                  values=['hello', 'world', 'a', 'b', 'c']
                  dense_shape=[2, 3])

  >>> tf.strings.split(['hello world', 'a b c'], result_type="RaggedTensor")
  <tf.RaggedTensor [['hello', 'world'], ['a', 'b', 'c']]>
  ```

  If `sep` is given, consecutive delimiters are not grouped together and are
  deemed to delimit empty strings. For example, `input` of `"1<>2<><>3"` and
  `sep` of `"<>"` returns `["1", "2", "", "3"]`. If `sep` is None or an empty
  string, consecutive whitespace are regarded as a single separator, and the
  result will contain no empty strings at the start or end if the string has
  leading or trailing whitespace.

  Note that the above mentioned behavior matches python's str.split.

  Args:
    input: `1-D` string `Tensor`, the strings to split.
    sep: `0-D` string `Tensor`, the delimiter character.
    maxsplit: An `int`. If `maxsplit > 0`, limit of the split of the result.
    result_type: The tensor type for the result: one of `"RaggedTensor"` or
      `"SparseTensor"`.
    source: alias for "input" argument.
    name: A name for the operation (optional).

  Raises:
    ValueError: If sep is not a string.

  Returns:
    A `SparseTensor` of rank `2`, the strings split according to the delimiter.
    The first column of the indices corresponds to the row in `source` and the
    second column corresponds to the index of the split component in this row.
  """
    source = deprecation.deprecated_argument_lookup("input", input, "source",
                                                    source)
    with ops.name_scope(name, "StringSplit", [source]):
        sparse_result = string_ops.string_split_v2(source,
                                                   sep=sep,
                                                   maxsplit=maxsplit)
        if result_type == "SparseTensor":
            return sparse_result
        elif result_type == "RaggedTensor":
            return ragged_tensor.RaggedTensor.from_value_rowids(
                values=sparse_result.values,
                value_rowids=sparse_result.indices[:, 0],
                nrows=sparse_result.dense_shape[0])
        else:
            raise ValueError(
                "result_type must be 'RaggedTensor' or 'SparseTensor'.")
コード例 #41
0
def european_option_price(strikes=None,
                          expiries=None,
                          is_call_options=None,
                          variances=None,
                          kappas=None,
                          thetas=None,
                          sigmas=None,
                          rhos=None,
                          spots=None,
                          forwards=None,
                          discount_rates=None,
                          dividend_rates=None,
                          continuous_dividends=None,
                          cost_of_carries=None,
                          discount_factors=None,
                          integration_method=None,
                          dtype=None,
                          name=None,
                          **kwargs):
    """Calculates European option prices under the Heston model.

  Heston originally published in 1993 his eponymous model [3]. He provided
  a semi- analytical formula for pricing European option via Fourier transform
  under his model. However, as noted by Albrecher [1], the characteristic
  function used in Heston paper can suffer numerical issues because of the
  discontinuous nature of the square root function in the complex plane, and a
  second version of the characteric function which doesn't suffer this
  shortcoming should be used instead. Attari [2] further refined the numerical
  method by reducing the number of numerical integrations (only one Fourier
  transform instead of two) and with an integrand function decaying
  quadratically instead of linearly. Attari's numerical method is implemented
  here.

  Heston model:
  ```
    dF/F = sqrt(V) * dW_1
    dV = kappa * (theta - V) * dt * sigma * sqrt(V) * dW_2
    <dW_1,dW_2> = rho *dt
  ```
  The variance V follows a square root process.

  #### Example
  ```python
  import tf_quant_finance as tff
  import numpy as np
  prices = tff.models.heston.approximations.european_option_price(
      variances=0.11,
      strikes=102.0,
      expiries=1.2,
      forwards=100.0,
      is_call_options=True,
      kappas=2.0,
      thetas=0.5,
      sigmas=0.15,
      rhos=0.3,
      discount_factors=1.0,
      dtype=np.float64)
  # Expected print output of prices:
  # 24.82219619
  ```
  #### References
  [1] Hansjorg Albrecher, The Little Heston Trap
  https://perswww.kuleuven.be/~u0009713/HestonTrap.pdf
  [2] Mukarram Attari, Option Pricing Using Fourier Transforms: A Numerically
  Efficient Simplification
  https://papers.ssrn.com/sol3/papers.cfm?abstract_id=520042
  [3] Steven L. Heston, A Closed-Form Solution for Options with Stochastic
  Volatility with Applications to Bond and Currency Options
  http://faculty.baruch.cuny.edu/lwu/890/Heston93.pdf
  Args:
    strikes: A real `Tensor` of any shape and dtype. The strikes of the options
      to be priced.
    expiries: A real `Tensor` of the same dtype and compatible shape as
      `strikes`.  The expiry of each option.
    is_call_options: A boolean `Tensor` of a shape compatible with
      `strikes`. Indicates whether the option is a call (if True) or a put
      (if False). If not supplied, call options are assumed.
    variances: A real `Tensor` of the same dtype and compatible shape as
      `strikes`. The initial value of the variance.
    kappas: A real `Tensor` of the same dtype and compatible shape as
      `strikes`. The mean reversion strength of the variance square root
      process.
    thetas: A real `Tensor` of the same dtype and compatible shape as
      `strikes`. The mean reversion level of the variance square root process.
    sigmas: A real `Tensor` of the same dtype and compatible shape as
      `strikes`. The volatility of the variance square root process (volatility
      of volatility)
    rhos: A real `Tensor` of the same dtype and compatible shape as
      `strikes`. The correlation between spot and variance.
        spots: A real `Tensor` of any shape that broadcasts to the shape of the
      `volatilities`. The current spot price of the underlying. Either this
      argument or the `forwards` (but not both) must be supplied.
    forwards: A real `Tensor` of any shape that broadcasts to the shape of
      `strikes`. The forwards to maturity. Either this argument or the
      `spots` must be supplied but both must not be supplied.
    discount_rates: An optional real `Tensor` of same dtype as the
      `strikes` and of the shape that broadcasts with `strikes`.
      If not `None`, discount factors are calculated as e^(-rT),
      where r are the discount rates, or risk free rates. At most one of
      discount_rates and discount_factors can be supplied.
      Default value: `None`, equivalent to r = 0 and discount factors = 1 when
      discount_factors also not given.
    dividend_rates: An optional real `Tensor` of same dtype as the
      `strikes` and of the shape that broadcasts with `strikes`.
      If not `None`, `cost_of_carries` is calculated as r - q,
      where r are the `discount_rates` and q is `dividend_rates`. Either
      this or `cost_of_carries` can be given.
      Default value: `None`, equivalent to q = 0.
    continuous_dividends: `Tensor` equivalent to `dividend_rates`, to be
      deprecated.
    cost_of_carries: An optional real `Tensor` of same dtype as the
      `strikes` and of the shape that broadcasts with `strikes`.
      Cost of storing a physical commodity, the cost of interest paid when
      long, or the opportunity cost, or the cost of paying dividends when short.
      If not `None`, and `spots` is supplied, used to calculate forwards from
      `spots`: F = e^(bT) * S, where F is the forwards price, b is the cost of
      carries, T is expiries and S is the spot price. If `None`, value assumed
      to be equal to the `discount_rate` - `dividend_rates`
      Default value: `None`, equivalent to b = r.
    discount_factors: An optional real `Tensor` of same dtype as the
      `strikes`. If not `None`, these are the discount factors to expiry
      (i.e. e^(-rT)). Mutually exclusive with discount_rate and cost_of_carry.
      If neither is given, no discounting is applied (i.e. the undiscounted
      option price is returned). If `spots` is supplied and `discount_factors`
      is not `None` then this is also used to compute the forwards to expiry.
      At most one of discount_rates and discount_factors can be supplied.
      Default value: `None`, which maps to -log(discount_factors) / expiries
    integration_method: An instance of `math.integration.IntegrationMethod`.
      Default value: `None` which maps to the Simpsons integration rule.
    dtype: Optional `tf.DType`. If supplied, the dtype to be used for conversion
      of any supplied non-`Tensor` arguments to `Tensor`.
      Default value: None which maps to the default dtype inferred by
      TensorFlow.
    name: str. The name for the ops created by this function.
      Default value: None which is mapped to the default name
      `heston_price`.
    **kwargs: Additional parameters for the underlying integration method.
      If not supplied and `integration_method` is Simpson, then uses
      `IntegrationMethod.COMPOSITE_SIMPSONS_RULE` with `num_points=1001`, and
      bounds `lower=1e-9`, `upper=100`.
  Returns:
    A `Tensor` of the same shape as the input data which is the price of
    European options under the Heston model.
  """
    dividend_rates = deprecation.deprecated_argument_lookup(
        'dividend_rates', dividend_rates, 'continuous_dividends',
        continuous_dividends)
    if (spots is None) == (forwards is None):
        raise ValueError(
            'Either spots or forwards must be supplied but not both.')
    if (discount_rates is not None) and (discount_factors is not None):
        raise ValueError(
            'At most one of discount_rates and discount_factors may '
            'be supplied')
    if (dividend_rates is not None) and (cost_of_carries is not None):
        raise ValueError('At most one of dividend_rates and cost_of_carries '
                         'may be supplied')

    with tf.compat.v1.name_scope(name, default_name='eu_option_price'):
        strikes = tf.convert_to_tensor(strikes, dtype=dtype, name='strikes')
        dtype = strikes.dtype
        expiries = tf.convert_to_tensor(expiries, dtype=dtype, name='expiries')
        kappas = tf.convert_to_tensor(kappas, dtype=dtype, name='kappas')
        thetas = tf.convert_to_tensor(thetas, dtype=dtype, name='thetas')
        sigmas = tf.convert_to_tensor(sigmas, dtype=dtype, name='sigmas')
        rhos = tf.convert_to_tensor(rhos, dtype=dtype, name='rhos')
        variances = tf.convert_to_tensor(variances,
                                         dtype=dtype,
                                         name='variances')

        if discount_factors is not None:
            discount_factors = tf.convert_to_tensor(discount_factors,
                                                    dtype=dtype,
                                                    name='discount_factors')

        if discount_rates is not None:
            discount_rates = tf.convert_to_tensor(discount_rates,
                                                  dtype=dtype,
                                                  name='discount_rates')
        elif discount_factors is not None:
            discount_rates = -tf.math.log(discount_factors) / expiries
        else:
            discount_rates = tf.convert_to_tensor(0.0,
                                                  dtype=dtype,
                                                  name='discount_rates')

        if dividend_rates is None:
            dividend_rates = tf.convert_to_tensor(0.0,
                                                  dtype=dtype,
                                                  name='dividend_rates')

        if cost_of_carries is not None:
            cost_of_carries = tf.convert_to_tensor(cost_of_carries,
                                                   dtype=dtype,
                                                   name='cost_of_carries')
        else:
            cost_of_carries = discount_rates - dividend_rates

        if discount_factors is None:
            discount_factors = tf.exp(-discount_rates * expiries)  # pylint: disable=invalid-unary-operand-type

        if forwards is not None:
            forwards = tf.convert_to_tensor(forwards,
                                            dtype=dtype,
                                            name='forwards')
        else:
            spots = tf.convert_to_tensor(spots, dtype=dtype, name='spots')
            forwards = spots * tf.exp(cost_of_carries * expiries)

        # Cast as complex for the characteristic function calculation
        expiries_real = tf.complex(expiries, tf.zeros_like(expiries))
        kappas_real = tf.complex(kappas, tf.zeros_like(kappas))
        thetas_real = tf.complex(thetas, tf.zeros_like(thetas))
        sigmas_real = tf.complex(sigmas, tf.zeros_like(sigmas))
        rhos_real = tf.complex(rhos, tf.zeros_like(rhos))
        variances_real = tf.complex(variances, tf.zeros_like(variances))

        # Prepare inputs to build an integrand_function
        expiries_real = tf.expand_dims(expiries_real, -1)
        kappas_real = tf.expand_dims(kappas_real, -1)
        thetas_real = tf.expand_dims(thetas_real, -1)
        sigmas_real = tf.expand_dims(sigmas_real, -1)
        rhos_real = tf.expand_dims(rhos_real, -1)
        variances_real = tf.expand_dims(variances_real, -1)
        if integration_method is None:
            integration_method = _COMPOSITE_SIMPSONS_RULE
        if integration_method == _COMPOSITE_SIMPSONS_RULE:
            if 'num_points' not in kwargs:
                kwargs['num_points'] = 1001
            if 'lower' not in kwargs:
                kwargs['lower'] = 1e-9
            if 'upper' not in kwargs:
                kwargs['upper'] = 100

        def char_fun(u):
            # Using 'second formula' for the (first) characteristic function of
            # log( spot_T / forwards )
            # (noted 'phi_2' in 'The Little Heston Trap', (Albrecher))
            u_real = tf.complex(u, tf.zeros_like(u))
            u_imag = tf.complex(tf.zeros_like(u), u)
            s = rhos_real * sigmas_real * u_imag
            # TODO(b/156221007): investigate why s_kappa = (s - kappas_real)**2 leads
            # to a wrong result in graph mode.
            s_kappa = (s - kappas_real) * s - (s - kappas_real) * kappas_real
            d = s_kappa - sigmas_real**2 * (-u_imag - u_real**2)
            d = tf.math.sqrt(d)
            g = (kappas_real - s - d) / (kappas_real - s + d)
            a = kappas_real * thetas_real
            h = g * tf.math.exp(-d * expiries_real)
            m = 2 * tf.math.log((1 - h) / (1 - g))
            c = (a / sigmas_real**2) * (
                (kappas_real - s - d) * expiries_real - m)
            e = (1 - tf.math.exp(-d * expiries_real))
            d_new = (kappas_real - s - d) / sigmas_real**2 * (e / (1 - h))
            return tf.math.exp(c + d_new * variances_real)

        def integrand_function(u, k):
            # Note that with [2], integrand is in 1 / u**2,
            # which converges faster than Heston 1993 (which is in 1 /u)
            char_fun_complex = char_fun(u)
            char_fun_real_part = tf.math.real(char_fun_complex)
            char_fun_imag_part = tf.math.imag(char_fun_complex)

            a = (char_fun_real_part + char_fun_imag_part / u) * tf.math.cos(
                u * k)
            b = (char_fun_imag_part - char_fun_real_part / u) * tf.math.sin(
                u * k)

            return (a + b) / (1.0 + u * u)

        k = tf.expand_dims(tf.math.log(strikes / forwards), axis=-1)

        integral = integration.integrate(lambda u: integrand_function(u, k),
                                         method=integration_method,
                                         dtype=dtype,
                                         **kwargs)
        undiscounted_call_prices = forwards - strikes * (0.5 + integral / _PI_)

        if is_call_options is None:
            return undiscounted_call_prices * discount_factors
        else:
            is_call_options = tf.convert_to_tensor(is_call_options,
                                                   dtype=tf.bool,
                                                   name='is_call_options')
            # Use call-put parity for Put
            undiscounted_put_prices = undiscounted_call_prices - forwards + strikes

            undiscount_prices = tf.where(is_call_options,
                                         undiscounted_call_prices,
                                         undiscounted_put_prices)
            return undiscount_prices * discount_factors