def test_setitem(self): # Single integer index. a = array_creation.array([1., 2., 3.]) b = array_creation.array(5.) c = array_creation.array(10.) tensors = [arr.data for arr in [a, b, c]] with tf.GradientTape() as g: g.watch(tensors) a[1] = b + c loss = math.sum(a) gradients = g.gradient(loss.data, tensors) self.assertSequenceEqual( array_creation.array(gradients[0]).tolist(), [1., 0., 1.]) self.assertEqual(array_creation.array(gradients[1]).tolist(), 1.) self.assertEqual(array_creation.array(gradients[2]).tolist(), 1.) # Tuple index. a = array_creation.array([[[1., 2.], [3., 4.]], [[5., 6.], [7., 8.]]]) # 2x2x2 array. b = array_creation.array([10., 11.]) tensors = [arr.data for arr in [a, b]] with tf.GradientTape() as g: g.watch(tensors) a[(1, 0)] = b loss = math.sum(a) gradients = g.gradient(loss.data, tensors) self.assertSequenceEqual( array_creation.array(gradients[0]).tolist(), [[[1., 1.], [1., 1.]], [[0., 0.], [1., 1.]]]) self.assertEqual(array_creation.array(gradients[1]).tolist(), [1., 1.])
def testLogSpace(self): array_transforms = [ lambda x: x, # Identity, tf.convert_to_tensor, np.array, lambda x: np.array(x, dtype=np.float32), lambda x: np.array(x, dtype=np.float64), array_creation.array, lambda x: array_creation.array(x, dtype=np.float32), lambda x: array_creation.array(x, dtype=np.float64) ] def run_test(start, stop, **kwargs): for fn1 in array_transforms: for fn2 in array_transforms: arg1 = fn1(start) arg2 = fn2(stop) self.match(array_creation.logspace(arg1, arg2, **kwargs), np.logspace(arg1, arg2, **kwargs), msg='logspace({}, {})'.format(arg1, arg2), almost=True) run_test(0, 5) run_test(0, 5, num=10) run_test(0, 5, endpoint=False) run_test(0, 5, base=2.0) run_test(0, -5) run_test(0, -5, num=10) run_test(0, -5, endpoint=False) run_test(0, -5, base=2.0)
def _testReduce(self, math_fun, np_fun, name): axis_transforms = [ lambda x: x, # Identity, tf.convert_to_tensor, np.array, array_creation.array, lambda x: array_creation.array(x, dtype=np.float32), lambda x: array_creation.array(x, dtype=np.float64), ] def run_test(a, **kwargs): axis = kwargs.pop('axis', None) for fn1 in self.array_transforms: for fn2 in axis_transforms: arg1 = fn1(a) axis_arg = fn2(axis) if axis is not None else None self.match( math_fun(arg1, axis=axis_arg, **kwargs), np_fun(arg1, axis=axis, **kwargs), msg='{}({}, axis={}, keepdims={})'.format( name, arg1, axis, kwargs.get('keepdims'))) run_test(5) run_test([2, 3]) run_test([[2, -3], [-6, 7]]) run_test([[2, -3], [-6, 7]], axis=0) run_test([[2, -3], [-6, 7]], axis=0, keepdims=True) run_test([[2, -3], [-6, 7]], axis=1) run_test([[2, -3], [-6, 7]], axis=1, keepdims=True) run_test([[2, -3], [-6, 7]], axis=(0, 1)) run_test([[2, -3], [-6, 7]], axis=(1, 0))
def setUp(self): super(MathTest, self).setUp() self.array_transforms = [ lambda x: x, # Identity, tf.convert_to_tensor, np.array, lambda x: np.array(x, dtype=np.float32), lambda x: np.array(x, dtype=np.float64), array_creation.array, lambda x: array_creation.array(x, dtype=np.float32), lambda x: array_creation.array(x, dtype=np.float64), ] self.types = [np.int32, np.int64, np.float32, np.float64]
def testArgMaxArgMin(self): data = [ 0, 5, [1], [1, 2, 3], [[1, 2, 3]], [[4, 6], [7, 8]], [[[4, 6], [9, 10]], [[7, 8], [12, 34]]], ] for fn, d in itertools.product(self.array_transforms, data): arr = fn(d) self.match(array_methods.argmax(arr), np.argmax(arr)) self.match(array_methods.argmin(arr), np.argmin(arr)) if hasattr(arr, 'shape'): ndims = len(arr.shape) else: ndims = array_creation.array(arr, copy=False).ndim if ndims == 0: # Numpy flattens the scalar ndarray and treats it as a 1-d array of # size 1. ndims = 1 for axis in range(-ndims, ndims): self.match(array_methods.argmax(arr, axis=axis), np.argmax(arr, axis=axis)) self.match(array_methods.argmin(arr, axis=axis), np.argmin(arr, axis=axis))
def run_test(a, b): for fn in self.array_transforms: arg1 = fn(a) arg2 = fn(b) self.match(math_fun(arg1, arg2), np_fun(arg1, arg2), msg='{}({}, {})'.format(name, arg1, arg2)) # Tests type promotion for type_a in self.types: for type_b in self.types: if not check_promotion and type_a != type_b: continue arg1 = array_creation.array(a, dtype=type_a) arg2 = array_creation.array(b, dtype=type_b) self.match(math_fun(arg1, arg2), np_fun(arg1, arg2), msg='{}({}, {})'.format(name, arg1, arg2), check_type=check_promotion_result_type)
def testIndexedSlices(self): dtype = tf.int64 iss = tf.IndexedSlices(values=tf.ones([2, 3], dtype=dtype), indices=tf.constant([1, 9]), dense_shape=[10, 3]) a = array_creation.array(iss, copy=False) expected = tf.scatter_nd([[1], [9]], tf.ones([2, 3], dtype=dtype), [10, 3]) self.assertAllEqual(expected, a)
def setUp(self): super(ArrayCreationTest, self).setUp() python_shapes = [ 0, 1, 2, (), (1, ), (2, ), (1, 2, 3), [], [1], [2], [1, 2, 3] ] self.shape_transforms = [ lambda x: x, lambda x: np.array(x, dtype=int), lambda x: array_creation.array(x, dtype=int), tf.TensorShape ] self.all_shapes = [] for fn in self.shape_transforms: self.all_shapes.extend([fn(s) for s in python_shapes]) if sys.version_info.major == 3: # There is a bug of np.empty (and alike) in Python 3 causing a crash when # the `shape` argument is an arrays.ndarray scalar (or tf.Tensor scalar). def not_ndarray_scalar(s): return not (isinstance(s, arrays.ndarray) and s.ndim == 0) self.all_shapes = list(filter(not_ndarray_scalar, self.all_shapes)) self.all_types = [ int, float, np.int16, np.int32, np.int64, np.float16, np.float32, np.float64 ] source_array_data = [ 1, 5.5, 7, (), (8, 10.), ((), ()), ((1, 4), (2, 8)), [], [7], [8, 10.], [[], []], [[1, 4], [2, 8]], ([], []), ([1, 4], [2, 8]), [(), ()], [(1, 4), (2, 8)], ] self.array_transforms = [ lambda x: x, tf.convert_to_tensor, np.array, array_creation.array, ] self.all_arrays = [] for fn in self.array_transforms: self.all_arrays.extend([fn(s) for s in source_array_data])
def run_test(arr, index, value): for fn in self.array_transforms: value_arg = fn(value) tf_array = array_creation.array(arr) np_array = np.array(arr) tf_array[index] = value_arg # TODO(srbs): "setting an array element with a sequence" is thrown # if we do not wrap value_arg in a numpy array. Investigate how this can # be avoided. np_array[index] = np.array(value_arg) self.match(tf_array, np_array)
def equal(x1, x2): """Compare two arrays for equality element-wise. Both arrays must either be of the same shape or one should be broadcastable to the other. Args: x1: array_like. Could be an ndarray, a Tensor or any object that can be converted to a Tensor using `tf.convert_to_tensor`. x2: array_like. Could be an ndarray, a Tensor or any object that can be converted to a Tensor using `tf.convert_to_tensor`. Returns: An ndarray of type bool and broadcasted shape of x1 and x2. """ dtype = utils.result_type(x1, x2) # Cast x1 and x2 to the result_type if needed. x1 = array_creation.array(x1, copy=False, dtype=dtype) x2 = array_creation.array(x2, copy=False, dtype=dtype) return utils.tensor_to_ndarray(tf.equal(x1.data, x2.data))
def normal(key, shape, dtype=tf.float32): """Sample standard-normal random values. Args: key: not used since TF doesn't pass RNG states explicitly. shape: the shape of the result. dtype: the dtype of the result. Returns: Random values in standard-normal distribution. """ del key return array(tf.random_normal(shape, dtype=dtype), copy=False)
def testDiag(self): array_transforms = [ lambda x: x, # Identity, tf.convert_to_tensor, np.array, lambda x: np.array(x, dtype=np.float32), lambda x: np.array(x, dtype=np.float64), array_creation.array, lambda x: array_creation.array(x, dtype=np.float32), lambda x: array_creation.array(x, dtype=np.float64) ] def run_test(arr): for fn in array_transforms: arr = fn(arr) self.match(array_creation.diag(arr), np.diag(arr), msg='diag({})'.format(arr)) for k in range(-3, 3): self.match(array_creation.diag(arr, k), np.diag(arr, k), msg='diag({}, k={})'.format(arr, k)) # 2-d arrays. run_test(np.arange(9).reshape((3, 3)).tolist()) run_test(np.arange(6).reshape((2, 3)).tolist()) run_test(np.arange(6).reshape((3, 2)).tolist()) run_test(np.arange(3).reshape((1, 3)).tolist()) run_test(np.arange(3).reshape((3, 1)).tolist()) run_test([[5]]) run_test([[]]) run_test([[], []]) # 1-d arrays. run_test([]) run_test([1]) run_test([1, 2])
def bernoulli(key, mean=np.float32(0.5), shape=()): """Sample Bernoulli random values with given shape and mean. Args: key: a random key, not used in the TF backend (stored in graph). mean: optional, an array_like broadcastable to `shape` for the mean of the random variables (default 0.5). shape: optional, a tuple of nonnegative integers representing the shape (default scalar). Returns: A random array with the specified shape and boolean dtype. """ # TODO(wangpeng): convert types TF <-> numpy. shape = shape or arrays.convert_to_tensor(value=mean).shape return array(tf.less(uniform(key, shape), mean), copy=False)
def setUp(self): super(ArrayCreationTest, self).setUp() python_shapes = [ 0, 1, 2, (), (1, ), (2, ), (1, 2, 3), [], [1], [2], [1, 2, 3] ] self.shape_transforms = [ lambda x: x, lambda x: np.array(x, dtype=int), lambda x: array_creation.array(x, dtype=int), tf.TensorShape ] self.all_shapes = [] for fn in self.shape_transforms: self.all_shapes.extend([fn(s) for s in python_shapes]) self.all_types = [ int, float, np.int16, np.int32, np.int64, np.float16, np.float32, np.float64 ] source_array_data = [ 1, 5.5, 7, (), (8, 10.), ((), ()), ((1, 4), (2, 8)), [], [7], [8, 10.], [[], []], [[1, 4], [2, 8]], ([], []), ([1, 4], [2, 8]), [(), ()], [(1, 4), (2, 8)], ] self.array_transforms = [ lambda x: x, tf.convert_to_tensor, np.array, array_creation.array, ] self.all_arrays = [] for fn in self.array_transforms: self.all_arrays.extend([fn(s) for s in source_array_data])
def uniform(key, shape, dtype=random.DEFAULT_RANDN_DTYPE, minval=0., maxval=1.): """Sample uniform random values in range [`minval`, `maxval`). Args: key: not used by this implementation. shape: the shape of the result. dtype: the dtype of the result. minval: the minimal value (inclusive). maxval: the maximal value (exclusive). Returns: An ndarray with shape `shape` and dtype `dtype`. Each value in the ndarray is sampled uniformly randomly in range [`minval`, `maxval`). """ del key return array( tf.random_uniform(shape, dtype=dtype, minval=minval, maxval=maxval), copy=False)
def testArray(self): ndmins = [0, 1, 2, 5] for a, dtype, ndmin, copy in itertools.product(self.all_arrays, self.all_types, ndmins, [True, False]): self.match( array_creation.array(a, dtype=dtype, ndmin=ndmin, copy=copy), np.array(a, dtype=dtype, ndmin=ndmin, copy=copy)) zeros_list = array_creation.zeros(5) # TODO(srbs): Test that copy=True when context.device is different from # tensor device copies the tensor. # Backing tensor is the same if copy=False, other attributes being None. self.assertIs( array_creation.array(zeros_list, copy=False).data, zeros_list.data) self.assertIs( array_creation.array(zeros_list.data, copy=False).data, zeros_list.data) # Backing tensor is different if ndmin is not satisfied. self.assertIsNot( array_creation.array(zeros_list, copy=False, ndmin=2).data, zeros_list.data) self.assertIsNot( array_creation.array(zeros_list.data, copy=False, ndmin=2).data, zeros_list.data) self.assertIs( array_creation.array(zeros_list, copy=False, ndmin=1).data, zeros_list.data) self.assertIs( array_creation.array(zeros_list.data, copy=False, ndmin=1).data, zeros_list.data) # Backing tensor is different if dtype is not satisfied. self.assertIsNot( array_creation.array(zeros_list, copy=False, dtype=int).data, zeros_list.data) self.assertIsNot( array_creation.array(zeros_list.data, copy=False, dtype=int).data, zeros_list.data) self.assertIs( array_creation.array(zeros_list, copy=False, dtype=float).data, zeros_list.data) self.assertIs( array_creation.array(zeros_list.data, copy=False, dtype=float).data, zeros_list.data)
def copy(a): """Returns a copy of the array.""" return array_creation.array(a, copy=True)
def f(x): if isinstance(x, (tf.Tensor, tf.IndexedSlices)): return array(x, copy=False) else: return x