Guest User

Untitled

a guest
Dec 16th, 2017
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.92 KB | None | 0 0
  1. def make_tensor_proto(values, dtype=None, shape=None, verify_shape=False):
  2. """Create a TensorProto.
  3. Args:
  4. values: Values to put in the TensorProto.
  5. dtype: Optional tensor_pb2 DataType value.
  6. shape: List of integers representing the dimensions of tensor.
  7. verify_shape: Boolean that enables verification of a shape of values.
  8. Returns:
  9. A TensorProto. Depending on the type, it may contain data in the
  10. "tensor_content" attribute, which is not directly useful to Python programs.
  11. To access the values you should convert the proto back to a numpy ndarray
  12. with tensor_util.MakeNdarray(proto).
  13. Raises:
  14. TypeError: if unsupported types are provided.
  15. ValueError: if arguments have inappropriate values or if verify_shape is
  16. True and shape of values is not equals to a shape from the argument.
  17. make_tensor_proto accepts "values" of a python scalar, a python list, a
  18. numpy ndarray, or a numpy scalar.
  19. If "values" is a python scalar or a python list, make_tensor_proto
  20. first convert it to numpy ndarray. If dtype is None, the
  21. conversion tries its best to infer the right numpy data
  22. type. Otherwise, the resulting numpy array has a compatible data
  23. type with the given dtype.
  24. In either case above, the numpy ndarray (either the caller provided
  25. or the auto converted) must have the compatible type with dtype.
  26. make_tensor_proto then converts the numpy array to a tensor proto.
  27. If "shape" is None, the resulting tensor proto represents the numpy
  28. array precisely.
  29. Otherwise, "shape" specifies the tensor's shape and the numpy array
  30. can not have more elements than what "shape" specifies.
  31. """
  32. if dtype:
  33. dtype = dtypes.as_dtype(dtype)
  34.  
  35. is_quantized = (dtype in [dtypes.qint8, dtypes.quint8, dtypes.qint16,
  36. dtypes.quint16, dtypes.qint32])
  37.  
  38. # We first convert value to a numpy array or scalar.
  39. if isinstance(values, (np.ndarray, np.generic)):
  40. if dtype:
  41. nparray = values.astype(dtype.as_numpy_dtype)
  42. else:
  43. nparray = values
  44. else:
  45. if values is None:
  46. raise ValueError("None values not supported.")
  47. # if dtype is provided, forces numpy array to be the type
  48. # provided if possible.
  49. if dtype and dtype.is_numpy_compatible:
  50. np_dt = dtype.as_numpy_dtype
  51. else:
  52. np_dt = None
  53. if np.prod(shape) == 0:
  54. nparray = np.empty(shape, dtype=np_dt)
  55. else:
  56. _AssertCompatible(values, dtype)
  57. nparray = np.array(values, dtype=np_dt)
  58. # check to them.
  59. # We need to pass in quantized values as tuples, so don't apply the shape
  60. if (list(nparray.shape) != _GetDenseDimensions(values) and
  61. not is_quantized):
  62. raise ValueError("""Argument must be a dense tensor: %s"""
  63. """ - got shape %s, but wanted %s.""" % (
  64. values, list(nparray.shape),
  65. _GetDenseDimensions(values)))
  66.  
  67. # python/numpy default float type is float64. We prefer float32 instead.
  68. if (nparray.dtype == np.float64) and dtype is None:
  69. nparray = nparray.astype(np.float32)
  70. # python/numpy default int type is int64. We prefer int32 instead.
  71. elif (nparray.dtype == np.int64) and dtype is None:
  72. downcasted_array = nparray.astype(np.int32)
  73. # Do not down cast if it leads to precision loss.
  74. if np.array_equal(downcasted_array, nparray):
  75. nparray = downcasted_array
  76.  
  77. # if dtype is provided, it must be compatible with what numpy
  78. # conversion says.
  79. numpy_dtype = dtypes.as_dtype(nparray.dtype)
  80. if numpy_dtype is None:
  81. raise TypeError("Unrecognized data type: %s" % nparray.dtype)
  82.  
  83. # If dtype was specified and is a quantized type, we convert
  84. # numpy_dtype back into the quantized version.
  85. if is_quantized:
  86. numpy_dtype = dtype
  87.  
  88. if dtype is not None and (not hasattr(dtype, "base_dtype") or
  89. dtype.base_dtype != numpy_dtype.base_dtype):
  90. raise TypeError("Incompatible types: %s vs. %s" % (dtype, nparray.dtype))
  91.  
  92. # If shape is not given, get the shape from the numpy array.
  93. if shape is None:
  94. shape = nparray.shape
  95. is_same_size = True
  96. shape_size = nparray.size
  97. else:
  98. shape = [int(dim) for dim in shape]
  99. shape_size = np.prod(shape)
  100. is_same_size = shape_size == nparray.size
  101.  
  102. if verify_shape:
  103. if not nparray.shape == tuple(shape):
  104. raise TypeError("Expected Tensor's shape: %s, got %s." %
  105. (tuple(shape), nparray.shape))
  106.  
  107. if nparray.size > shape_size:
  108. raise ValueError(
  109. "Too many elements provided. Needed at most %d, but received %d" %
  110. (shape_size, nparray.size))
  111.  
  112. tensor_proto = tensor_pb2.TensorProto(
  113. dtype=numpy_dtype.as_datatype_enum,
  114. tensor_shape=tensor_shape.as_shape(shape).as_proto())
  115.  
  116. if is_same_size and numpy_dtype in _TENSOR_CONTENT_TYPES and shape_size > 1:
  117. if nparray.size * nparray.itemsize >= (1 << 31):
  118. raise ValueError(
  119. "Cannot create a tensor proto whose content is larger than 2GB.")
  120. tensor_proto.tensor_content = nparray.tostring()
  121. return tensor_proto
  122.  
  123. # If we were not given values as a numpy array, compute the proto_values
  124. # from the given values directly, to avoid numpy trimming nulls from the
  125. # strings. Since values could be a list of strings, or a multi-dimensional
  126. # list of lists that might or might not correspond to the given shape,
  127. # we flatten it conservatively.
  128. if numpy_dtype == dtypes.string and not isinstance(values, np.ndarray):
  129. proto_values = _FlattenToStrings(values)
  130. tensor_proto.string_val.extend([compat.as_bytes(x) for x in proto_values])
  131. return tensor_proto
  132.  
  133. # TensorFlow expects C order (a.k.a., eigen row major).
  134. proto_values = nparray.ravel()
  135.  
  136. append_fn = GetNumpyAppendFn(proto_values.dtype)
  137. if append_fn is None:
  138. raise TypeError("Element type not supported in TensorProto: %s" %
  139. numpy_dtype.name)
  140. append_fn(tensor_proto, proto_values)
  141.  
  142. return tensor_proto
Add Comment
Please, Sign In to add comment