コード例 #1
0
    def test_tf_dtypes_and_shapes_to_type_with_dict(self):
        t1 = type_utils.tf_dtypes_and_shapes_to_type(
            {
                'a': tf.int32,
                'b': tf.bool,
            },
            {
                'a': tf.TensorShape([]),
                'b': tf.TensorShape([5]),
            },
        )
        self.assertEqual(str(t1), '<a=int32,b=bool[5]>')
        self.assertIsInstance(
            t1, computation_types.NamedTupleTypeWithPyContainerType)
        self.assertIs(
            computation_types.NamedTupleTypeWithPyContainerType.
            get_container_type(t1), dict)

        t2 = type_utils.tf_dtypes_and_shapes_to_type(
            {
                'b': tf.bool,
                'a': tf.int32,
            },
            {
                'a': tf.TensorShape([]),
                'b': tf.TensorShape([5]),
            },
        )
        self.assertEqual(str(t2), '<a=int32,b=bool[5]>')
        self.assertIsInstance(
            t2, computation_types.NamedTupleTypeWithPyContainerType)
        self.assertIs(
            computation_types.NamedTupleTypeWithPyContainerType.
            get_container_type(t2), dict)
コード例 #2
0
ファイル: type_utils_test.py プロジェクト: abogdanova/FedMed
 def test_tf_dtypes_and_shapes_to_type_with_dict(self):
     self.assertEqual(
         str(
             type_utils.tf_dtypes_and_shapes_to_type(
                 {
                     'a': tf.int32,
                     'b': tf.bool,
                 },
                 {
                     'a': tf.TensorShape([]),
                     'b': tf.TensorShape([5]),
                 },
             )), '<a=int32,b=bool[5]>')
     self.assertEqual(
         str(
             type_utils.tf_dtypes_and_shapes_to_type(
                 {
                     'b': tf.bool,
                     'a': tf.int32,
                 },
                 {
                     'a': tf.TensorShape([]),
                     'b': tf.TensorShape([5]),
                 },
             )), '<a=int32,b=bool[5]>')
コード例 #3
0
ファイル: type_utils_test.py プロジェクト: abogdanova/FedMed
 def test_tf_dtypes_and_shapes_to_type_with_list(self):
     self.assertEqual(
         str(
             type_utils.tf_dtypes_and_shapes_to_type(
                 [tf.int32, tf.bool],
                 [tf.TensorShape([1]),
                  tf.TensorShape([2])])), '<int32[1],bool[2]>')
コード例 #4
0
 def test_tf_dtypes_and_shapes_to_type_with_three_level_nesting(self):
     foo = collections.namedtuple('_', 'y x')
     t = type_utils.tf_dtypes_and_shapes_to_type(
         foo(x=[tf.int32, {
             'bar': tf.float32
         }], y=tf.bool),
         foo(x=[tf.TensorShape([1]), {
             'bar': tf.TensorShape([2])
         }],
             y=tf.TensorShape([3])))
     self.assertEqual(str(t), '<y=bool[3],x=<int32[1],<bar=float32[2]>>>')
     self.assertIsInstance(
         t, computation_types.NamedTupleTypeWithPyContainerType)
     self.assertIs(
         computation_types.NamedTupleTypeWithPyContainerType.
         get_container_type(t), foo)
     self.assertIsInstance(
         t.x, computation_types.NamedTupleTypeWithPyContainerType)
     self.assertIs(
         computation_types.NamedTupleTypeWithPyContainerType.
         get_container_type(t.x), list)
     self.assertIsInstance(
         t.x[1], computation_types.NamedTupleTypeWithPyContainerType)
     self.assertIs(
         computation_types.NamedTupleTypeWithPyContainerType.
         get_container_type(t.x[1]), dict)
コード例 #5
0
ファイル: type_utils_test.py プロジェクト: abogdanova/FedMed
 def test_tf_dtypes_and_shapes_to_type_with_namedtuple(self):
     foo = collections.namedtuple('_', 'y x')
     self.assertEqual(
         str(
             type_utils.tf_dtypes_and_shapes_to_type(
                 foo(x=tf.int32, y=tf.bool),
                 foo(x=tf.TensorShape([1]), y=tf.TensorShape([2])))),
         '<y=bool[2],x=int32[1]>')
コード例 #6
0
ファイル: type_utils_test.py プロジェクト: abogdanova/FedMed
 def test_tf_dtypes_and_shapes_to_type_with_ordered_dict(self):
     self.assertEqual(
         str(
             type_utils.tf_dtypes_and_shapes_to_type(
                 collections.OrderedDict([('b', tf.int32), ('a', tf.bool)]),
                 collections.OrderedDict([
                     ('b', tf.TensorShape([1])),
                     ('a', tf.TensorShape([])),
                 ]))), '<b=int32[1],a=bool>')
コード例 #7
0
 def test_tf_dtypes_and_shapes_to_type_with_tuple(self):
     t = type_utils.tf_dtypes_and_shapes_to_type(
         (tf.int32, tf.bool), (tf.TensorShape([1]), tf.TensorShape([2])))
     self.assertEqual(str(t), '<int32[1],bool[2]>')
     self.assertIsInstance(
         t, computation_types.NamedTupleTypeWithPyContainerType)
     self.assertIs(
         computation_types.NamedTupleTypeWithPyContainerType.
         get_container_type(t), tuple)
コード例 #8
0
ファイル: type_utils_test.py プロジェクト: abogdanova/FedMed
 def test_tf_dtypes_and_shapes_to_type_with_list_of_lists(self):
     self.assertEqual(
         str(
             type_utils.tf_dtypes_and_shapes_to_type(
                 [[tf.int32, tf.int32], [tf.bool, tf.bool]], [
                     [tf.TensorShape([1]),
                      tf.TensorShape([2])],
                     [tf.TensorShape([]),
                      tf.TensorShape([])],
                 ])), '<<int32[1],int32[2]>,<bool,bool>>')
コード例 #9
0
 def test_tf_dtypes_and_shapes_to_type_with_namedtuple(self):
     foo = collections.namedtuple('_', 'y x')
     t = type_utils.tf_dtypes_and_shapes_to_type(
         foo(x=tf.int32, y=tf.bool),
         foo(x=tf.TensorShape([1]), y=tf.TensorShape([2])))
     self.assertEqual(str(t), '<y=bool[2],x=int32[1]>')
     self.assertIsInstance(
         t, computation_types.NamedTupleTypeWithPyContainerType)
     self.assertIs(
         computation_types.NamedTupleTypeWithPyContainerType.
         get_container_type(t), foo)
コード例 #10
0
 def test_tf_dtypes_and_shapes_to_type_with_ordered_dict(self):
     t = type_utils.tf_dtypes_and_shapes_to_type(
         collections.OrderedDict([('b', tf.int32), ('a', tf.bool)]),
         collections.OrderedDict([
             ('b', tf.TensorShape([1])),
             ('a', tf.TensorShape([])),
         ]))
     self.assertEqual(str(t), '<b=int32[1],a=bool>')
     self.assertIsInstance(
         t, computation_types.NamedTupleTypeWithPyContainerType)
     self.assertIs(
         computation_types.NamedTupleTypeWithPyContainerType.
         get_container_type(t), collections.OrderedDict)
コード例 #11
0
ファイル: type_utils_test.py プロジェクト: abogdanova/FedMed
 def test_tf_dtypes_and_shapes_to_type_with_three_level_nesting(self):
     foo = collections.namedtuple('_', 'y x')
     self.assertEqual(
         str(
             type_utils.tf_dtypes_and_shapes_to_type(
                 foo(x=[tf.int32, {
                     'bar': tf.float32
                 }], y=tf.bool),
                 foo(x=[tf.TensorShape([1]), {
                     'bar': tf.TensorShape([2])
                 }],
                     y=tf.TensorShape([3])))),
         '<y=bool[3],x=<int32[1],<bar=float32[2]>>>')
コード例 #12
0
 def test_tf_dtypes_and_shapes_to_type_with_list_of_lists(self):
     t = type_utils.tf_dtypes_and_shapes_to_type(
         [[tf.int32, tf.int32], [tf.bool, tf.bool]], [
             [tf.TensorShape([1]), tf.TensorShape([2])],
             [tf.TensorShape([]), tf.TensorShape([])],
         ])
     self.assertEqual(str(t), '<<int32[1],int32[2]>,<bool,bool>>')
     self.assertIsInstance(
         t, computation_types.NamedTupleTypeWithPyContainerType)
     self.assertIs(
         computation_types.NamedTupleTypeWithPyContainerType.
         get_container_type(t), list)
     self.assertIsInstance(
         t[0], computation_types.NamedTupleTypeWithPyContainerType)
     self.assertIs(
         computation_types.NamedTupleTypeWithPyContainerType.
         get_container_type(t[0]), list)
コード例 #13
0
ファイル: type_utils_test.py プロジェクト: abogdanova/FedMed
 def test_tf_dtypes_and_shapes_to_type_with_int_vector(self):
     self.assertEqual(
         str(
             type_utils.tf_dtypes_and_shapes_to_type(
                 tf.int32, tf.TensorShape([2]))), 'int32[2]')
コード例 #14
0
ファイル: graph_utils.py プロジェクト: aliceyiwang/federated
def capture_result_from_graph(result, graph):
    """Captures a result stamped into a tf.Graph as a type signature and binding.

  Args:
    result: The result to capture, a Python object that is composed of tensors,
      possibly nested within Python structures such as dictionaries, lists,
      tuples, or named tuples.
    graph: The instance of tf.Graph to use.

  Returns:
    A tuple (type_spec, binding), where 'type_spec' is an instance of
    computation_types.Type that describes the type of the result, and 'binding'
    is an instance of TensorFlow.Binding that indicates how parts of the result
    type relate to the tensors and ops that appear in the result.

  Raises:
    TypeError: If the argument or any of its parts are of an uexpected type.
  """
    def _get_bindings_for_elements(name_value_pairs, graph, type_fn):
        """Build `(type_spec, binding)` tuple for name value pairs."""
        element_name_type_binding_triples = [
            ((k, ) + capture_result_from_graph(v, graph))
            for k, v in name_value_pairs
        ]
        type_spec = type_fn([((e[0], e[1]) if e[0] else e[1])
                             for e in element_name_type_binding_triples])
        binding = pb.TensorFlow.Binding(tuple=pb.TensorFlow.NamedTupleBinding(
            element=[e[2] for e in element_name_type_binding_triples]))
        return type_spec, binding

    # TODO(b/113112885): The emerging extensions for serializing SavedModels may
    # end up introducing similar concepts of bindings, etc., we should look here
    # into the possibility of reusing some of that code when it's available.
    if isinstance(result, dtype_utils.TENSOR_REPRESENTATION_TYPES):
        with graph.as_default():
            result = tf.constant(result)
    if tf.contrib.framework.is_tensor(result):
        if hasattr(result, 'read_value'):
            # We have a tf.Variable-like result, get a proper tensor to fetch.
            with graph.as_default():
                result = result.read_value()
        return (computation_types.TensorType(result.dtype.base_dtype,
                                             result.shape),
                pb.TensorFlow.Binding(tensor=pb.TensorFlow.TensorBinding(
                    tensor_name=result.name)))
    elif py_typecheck.is_named_tuple(result):
        # Special handling needed for collections.namedtuples since they do not have
        # anything in the way of a shared base class. Note we don't want to rely on
        # the fact that collections.namedtuples inherit from 'tuple' because we'd be
        # failing to retain the information about naming of tuple members.
        # pylint: disable=protected-access
        name_value_pairs = six.iteritems(result._asdict())
        # pylint: enable=protected-access
        return _get_bindings_for_elements(
            name_value_pairs, graph,
            functools.partial(
                computation_types.NamedTupleTypeWithPyContainerType,
                container_type=type(result)))
    elif isinstance(result, anonymous_tuple.AnonymousTuple):
        return _get_bindings_for_elements(anonymous_tuple.to_elements(result),
                                          graph,
                                          computation_types.NamedTupleType)
    elif isinstance(result, dict):
        if isinstance(result, collections.OrderedDict):
            name_value_pairs = six.iteritems(result)
        else:
            name_value_pairs = sorted(six.iteritems(result))
        return _get_bindings_for_elements(
            name_value_pairs, graph,
            functools.partial(
                computation_types.NamedTupleTypeWithPyContainerType,
                container_type=type(result)))
    elif isinstance(result, (list, tuple)):
        element_type_binding_pairs = [
            capture_result_from_graph(e, graph) for e in result
        ]
        return (computation_types.NamedTupleTypeWithPyContainerType(
            [e[0] for e in element_type_binding_pairs], type(result)),
                pb.TensorFlow.Binding(tuple=pb.TensorFlow.NamedTupleBinding(
                    element=[e[1] for e in element_type_binding_pairs])))
    elif isinstance(result,
                    (tf.compat.v1.data.Dataset, tf.compat.v2.data.Dataset)):
        variant_tensor = tf.data.experimental.to_variant(result)
        # TODO(b/130032140): Switch to TF2.0 way of doing it while cleaning up the
        # legacy structures all over the code base and replacing them with the new
        # tf.data.experimenta.Structure variants.
        element_type = type_utils.tf_dtypes_and_shapes_to_type(
            tf.compat.v1.data.get_output_types(result),
            tf.compat.v1.data.get_output_shapes(result))
        return (computation_types.SequenceType(element_type),
                pb.TensorFlow.Binding(sequence=pb.TensorFlow.SequenceBinding(
                    variant_tensor_name=variant_tensor.name)))
    elif isinstance(result, OneShotDataset):
        # TODO(b/129956296): Eventually delete this deprecated code path.
        element_type = type_utils.tf_dtypes_and_shapes_to_type(
            tf.compat.v1.data.get_output_types(result),
            tf.compat.v1.data.get_output_shapes(result))
        handle_name = result.make_one_shot_iterator().string_handle().name
        return (computation_types.SequenceType(element_type),
                pb.TensorFlow.Binding(sequence=pb.TensorFlow.SequenceBinding(
                    iterator_string_handle_name=handle_name)))
    else:
        raise TypeError(
            'Cannot capture a result of an unsupported type {}.'.format(
                py_typecheck.type_string(type(result))))
コード例 #15
0
def capture_result_from_graph(result, graph):
  """Captures a result stamped into a tf.Graph as a type signature and binding.

  Args:
    result: The result to capture, a Python object that is composed of tensors,
      possibly nested within Python structures such as dictionaries, lists,
      tuples, or named tuples.
    graph: The instance of tf.Graph to use.

  Returns:
    A tuple (type_spec, binding), where 'type_spec' is an instance of
    computation_types.Type that describes the type of the result, and 'binding'
    is an instance of TensorFlow.Binding that indicates how parts of the result
    type relate to the tensors and ops that appear in the result.

  Raises:
    TypeError: If the argument or any of its parts are of an uexpected type.
  """
  # TODO(b/113112885): The emerging extensions for serializing SavedModels may
  # end up introducing similar concepts of bindings, etc., we should look here
  # into the possibility of reusing some of that code when it's available.
  if isinstance(result, dtype_utils.TENSOR_REPRESENTATION_TYPES):
    with graph.as_default():
      result = tf.constant(result)
  if tf.contrib.framework.is_tensor(result):
    if hasattr(result, 'read_value'):
      # We have a tf.Variable-like result, get a proper tensor to fetch.
      with graph.as_default():
        result = result.read_value()
    return (computation_types.TensorType(result.dtype.base_dtype, result.shape),
            pb.TensorFlow.Binding(
                tensor=pb.TensorFlow.TensorBinding(tensor_name=result.name)))
  elif py_typecheck.is_named_tuple(result):
    # Special handling needed for collections.namedtuples since they do not have
    # anything in the way of a shared base class. Note we don't want to rely on
    # the fact that collections.namedtuples inherit from 'tuple' because we'd be
    # failing to retain the information about naming of tuple members.
    # pylint: disable=protected-access
    return capture_result_from_graph(result._asdict(), graph)
    # pylint: enable=protected-access
  elif isinstance(result, (dict, anonymous_tuple.AnonymousTuple)):
    if isinstance(result, anonymous_tuple.AnonymousTuple):
      name_value_pairs = anonymous_tuple.to_elements(result)
    elif isinstance(result, collections.OrderedDict):
      name_value_pairs = six.iteritems(result)
    else:
      name_value_pairs = sorted(six.iteritems(result))
    element_name_type_binding_triples = [
        ((k,) + capture_result_from_graph(v, graph))
        for k, v in name_value_pairs
    ]
    return (computation_types.NamedTupleType([
        ((e[0], e[1]) if e[0] else e[1])
        for e in element_name_type_binding_triples
    ]),
            pb.TensorFlow.Binding(
                tuple=pb.TensorFlow.NamedTupleBinding(
                    element=[e[2] for e in element_name_type_binding_triples])))
  elif isinstance(result, (list, tuple)):
    element_type_binding_pairs = [
        capture_result_from_graph(e, graph) for e in result
    ]
    return (computation_types.NamedTupleType(
        [e[0] for e in element_type_binding_pairs]),
            pb.TensorFlow.Binding(
                tuple=pb.TensorFlow.NamedTupleBinding(
                    element=[e[1] for e in element_type_binding_pairs])))
  elif isinstance(result, DATASET_REPRESENTATION_TYPES):
    element_type = type_utils.tf_dtypes_and_shapes_to_type(
        result.output_types, result.output_shapes)
    handle_name = result.make_one_shot_iterator().string_handle().name
    return (computation_types.SequenceType(element_type),
            pb.TensorFlow.Binding(
                sequence=pb.TensorFlow.SequenceBinding(
                    iterator_string_handle_name=handle_name)))
  else:
    raise TypeError('Cannot capture a result of an unsupported type {}.'.format(
        py_typecheck.type_string(type(result))))
コード例 #16
0
def to_representation_for_type(value, type_spec=None, device=None):
    """Verifies or converts the `value` to an eager objct matching `type_spec`.

  WARNING: This function is only partially implemented. It does not support
  data sets at this point.

  The output of this function is always an eager tensor, eager dataset, a
  representation of a TensorFlow computtion, or a nested structure of those
  that matches `type_spec`, and when `device` has been specified, everything
  is placed on that device on a best-effort basis.

  TensorFlow computations are represented here as zero- or one-argument Python
  callables that accept their entire argument bundle as a single Python object.

  Args:
    value: The raw representation of a value to compare against `type_spec` and
      potentially to be converted.
    type_spec: An instance of `tff.Type`, can be `None` for values that derive
      from `typed_object.TypedObject`.
    device: The optional device to place the value on (for tensor-level values).

  Returns:
    Either `value` itself, or a modified version of it.

  Raises:
    TypeError: If the `value` is not compatible with `type_spec`.
  """
    if device is not None:
        py_typecheck.check_type(device, six.string_types)
        with tf.device(device):
            return to_representation_for_type(value,
                                              type_spec=type_spec,
                                              device=None)
    type_spec = computation_types.to_type(type_spec)
    if isinstance(value, typed_object.TypedObject):
        if type_spec is not None:
            if not type_utils.are_equivalent_types(value.type_signature,
                                                   type_spec):
                raise TypeError(
                    'Expected a value of type {}, found {}.'.format(
                        str(type_spec), str(value.type_signature)))
        else:
            type_spec = value.type_signature
    if type_spec is None:
        raise ValueError(
            'Cannot derive an eager representation for a value of an unknown type.'
        )
    if isinstance(value, EagerValue):
        return value.internal_representation
    if isinstance(value, executor_value_base.ExecutorValue):
        raise TypeError(
            'Cannot accept a value embedded within a non-eager executor.')
    if isinstance(value, computation_base.Computation):
        return to_representation_for_type(
            computation_impl.ComputationImpl.get_proto(value), type_spec,
            device)
    if isinstance(value, pb.Computation):
        return embed_tensorflow_computation(value, type_spec, device)
    if isinstance(type_spec, computation_types.TensorType):
        if not isinstance(value, tf.Tensor):
            value = tf.constant(value, type_spec.dtype, type_spec.shape)
        value_type = (computation_types.TensorType(value.dtype.base_dtype,
                                                   value.shape))
        if not type_utils.is_assignable_from(type_spec, value_type):
            raise TypeError(
                'The apparent type {} of a tensor {} does not match the expected '
                'type {}.'.format(str(value_type), str(value), str(type_spec)))
        return value
    elif isinstance(type_spec, computation_types.NamedTupleType):
        type_elem = anonymous_tuple.to_elements(type_spec)
        value_elem = (anonymous_tuple.to_elements(
            anonymous_tuple.from_container(value)))
        result_elem = []
        if len(type_elem) != len(value_elem):
            raise TypeError(
                'Expected a {}-element tuple, found {} elements.'.format(
                    str(len(type_elem)), str(len(value_elem))))
        for (t_name, el_type), (v_name, el_val) in zip(type_elem, value_elem):
            if t_name != v_name:
                raise TypeError(
                    'Mismatching element names in type vs. value: {} vs. {}.'.
                    format(t_name, v_name))
            el_repr = to_representation_for_type(el_val, el_type, device)
            result_elem.append((t_name, el_repr))
        return anonymous_tuple.AnonymousTuple(result_elem)
    elif isinstance(type_spec, computation_types.SequenceType):
        py_typecheck.check_type(value,
                                (tf.data.Dataset, tf.compat.v1.data.Dataset,
                                 tf.compat.v2.data.Dataset))
        element_type = type_utils.tf_dtypes_and_shapes_to_type(
            tf.compat.v1.data.get_output_types(value),
            tf.compat.v1.data.get_output_shapes(value))
        value_type = computation_types.SequenceType(element_type)
        if not type_utils.are_equivalent_types(value_type, type_spec):
            raise TypeError('Expected a value of type {}, found {}.'.format(
                str(type_spec), str(value_type)))
        return value
    else:
        raise TypeError('Unexpected type {}.'.format(str(type_spec)))
コード例 #17
0
ファイル: graph_utils.py プロジェクト: aliceyiwang/federated
def make_data_set_from_elements(graph, elements, element_type):
    """Creates a `tf.data.Dataset` in `graph` from explicitly listed `elements`.

  NOTE: The underlying implementation attempts to use the
  `tf.data.Dataset.from_tensor_slices() method to build the data set quickly,
  but this doesn't always work. The typical scenario where it breaks is one
  with data set being composed of unequal batches. Typically, only the last
  batch is odd, so on the first attempt, we try to construct two data sets,
  one from all elements but the last one, and one from the last element, then
  concatenate the two. In the unlikely case that this fails (e.g., because
  all data set elements are batches of unequal sizes), we revert to the slow,
  but reliable method of constructing data sets from singleton elements, and
  then concatenating them all.

  Args:
    graph: The graph in which to construct the `tf.data.Dataset`.
    elements: A list of elements.
    element_type: The type of elements.

  Returns:
    The constructed `tf.data.Dataset` instance.

  Raises:
    TypeError: If element types do not match `element_type`.
    ValueError: If the elements are of incompatible types and shapes.
  """
    py_typecheck.check_type(graph, tf.Graph)
    py_typecheck.check_type(elements, list)
    element_type = computation_types.to_type(element_type)
    py_typecheck.check_type(element_type, computation_types.Type)

    def _make(element_subset):
        structure = make_empty_list_structure_for_element_type_spec(
            element_type)
        for el in element_subset:
            append_to_list_structure_for_element_type_spec(
                structure, el, element_type)
        tensor_slices = to_tensor_slices_from_list_structure_for_element_type_spec(
            structure, element_type)
        return tf.data.Dataset.from_tensor_slices(tensor_slices)

    with graph.as_default():
        if not elements:
            # Just return an empty data set with the appropriate types.
            dummy_element = _make_dummy_element_for_type_spec(element_type)
            ds = _make([dummy_element]).take(0)
        elif len(elements) == 1:
            ds = _make(elements)
        else:
            try:
                # It is common for the last element to be a batch of a size different
                # from all the preceding batches. With this in mind, we proactively
                # single out the last element (optimizing for the common case).
                ds = _make(elements[0:-1]).concatenate(_make(elements[-1:]))
            except ValueError:
                # In case elements beyond just the last one are of unequal shapes, we
                # may have failed (the most likely cause), so fall back onto the slow
                # process of constructing and joining data sets from singletons. Not
                # optimizing this for now, as it's very unlikely in scenarios
                # we're targeting.
                ds = None
                for i in range(len(elements)):
                    singleton_ds = _make(elements[i:i + 1])
                    ds = singleton_ds if ds is None else ds.concatenate(
                        singleton_ds)
        ds_element_type = type_utils.tf_dtypes_and_shapes_to_type(
            ds.output_types, ds.output_shapes)
        if not type_utils.is_assignable_from(element_type, ds_element_type):
            raise TypeError(
                'Failure during data set construction, expected elements of type {}, '
                'but the constructed data set has elements of type {}.'.format(
                    str(element_type), str(ds_element_type)))
    return ds