tensorflow2.0---tensor高阶操作
tensor的合并与分割
合并
tf.concat([a, b], axis = )
注:
(1)不创建新的维度;
(2)在哪个维度合并,哪个维度数量增加;其他维度必须相同。
a = tf.ones([4, 35, 8]) b = tf.ones([2, 35, 8]) c = tf.ones([4, 35, 8]) d = tf.concat([a, b], axis=0) print(d.shape) # (6, 35, 8) e = tf.concat([a, c], axis=-1) print(e.shape) # (4, 35, 16)
tf.stack([a, b], axis = )
注意,会创建新的维度!
a = tf.ones([4, 35, 8]) b = tf.ones([4, 35, 8]) c = tf.stack([a, b], axis=0) print(c.shape) d = tf.stack([a, b], axis=-1) print(d.shape) # (4, 35, 8, 2)
a、b的原始维度必须完全相同,否则报错:
a = tf.ones([4, 35, 8]) b = tf.ones([2, 35, 8]) c = tf.stack([a, b], axis=0) print(c.shape) # ensorflow.python.framework.errors_impl.InvalidArgumentError: Shapes of all inputs must match: values[0].shape = [4,35,8] != values[1].shape = [2,35,8] [Op:Pack] name: stack
分割
tf.unstack(a, axis = )
注意,返回一个list,list里面的内容是tensor
a = tf.ones([4, 35, 8]) b = tf.ones([4, 35, 8]) c = tf.stack([a, b], axis=0) print(c.shape) # (2, 4, 35, 8) d = tf.unstack(c, axis=0) print(type(d)) # <class 'list'> print(d[0].shape) # (4, 35, 8) e = tf.unstack(c, axis=-1) print(len(e)) # 8 print(e[0].shape) # (2, 4, 35) 范围e[0]~e[7]
tf.split(a, axis = , num_or_size_splits = )
a = tf.ones([4, 35, 8]) b = tf.ones([4, 35, 8]) c = tf.stack([a, b], axis=0) print(c.shape) # (2, 4, 35, 8) d = tf.split(c, axis=3, num_or_size_splits=2) # 分成两份 print(type(d)) # <class 'list'> print(len(d)) # 2 print(d[0].shape) # (2, 4, 35, 4) e = tf.split(c, axis=3, num_or_size_splits=[2, 2, 4]) print(e[0].shape) # (2, 4, 35, 2) print(e[2].shape) # (2, 4, 35, 4)
数据统计
向量的范数:
tf.norm (范数)
a = tf.ones([2, 2]) print(tf.norm(a)) # tf.Tensor(2.0, shape=(), dtype=float32) # 不指定几范数和轴,默认二范数 print(tf.sqrt(tf.reduce_sum(tf.square(a)))) # 同样的效果
a = tf.ones([2, 3]) b = tf.norm(a, ord=2, axis=1) print(b.shape) # (2,) 指定列方向,结果为行数
a = tf.ones([2, 3]) b = tf.norm(a, ord=1, axis=0) print(b) # tf.Tensor([2. 2. 2.], shape=(3,), dtype=float32)
reduce_min/max/mean
注:reduce表示降维的意思。
tf.reduce_min(a, axis = )
a = tf.random.normal([4, 10]) print(tf.reduce_max(a)) # 不指定轴,默认全局最大值(返回值仍然是一个tensor) # tf.Tensor(2.6767023, shape=(), dtype=float32)
a = tf.random.normal([4, 10]) print(tf.reduce_max(a, axis=0).shape) # (10,) print(tf.reduce_max(a, axis=1).shape) # (4,)
a = tf.constant([1]) print(a.shape) # (1,) b = tf.constant([[1]]) print(b.shape) # (1, 1)
tf.argmax、tf.argmin
返回最大值、最小值的索引位置(默认axis = 0,结果与列数相等)。
a = tf.random.uniform([3, 4], maxval=10, dtype=tf.int32) print(a) print(tf.argmax(a)) # tf.Tensor([0 1 1 1], shape=(4,), dtype=int64) 默认即为axis=0,形状与列数相等 print(tf.argmax(a, axis=0).shape) # (4,) print(tf.argmax(a, axis=1).shape) # (3,)
import tensorflow as tf
a = tf.random.uniform([3, 4], maxval=10, dtype=tf.int32) print(a) print(tf.argmax(a, axis=0))
运行结果:
tf.equal(a, b)
返回内容为布尔型的tensor
a = tf.constant([1, 2, 3, 2, 4]) b = tf.range(5) print(tf.equal(a, b)) # tf.Tensor([False False False False True], shape=(5,), dtype=bool)
用以下方法可以求得相同元素的个数(准确率):
a = tf.constant([1, 2, 3, 2, 4]) b = tf.range(5) c = tf.equal(a, b) print(tf.reduce_sum(tf.cast(c, dtype=tf.int32))) # tf.Tensor(1, shape=(), dtype=int32)
# 假设a为神经网络经过softmax得到的结果(如手写数字识别) a = tf.constant([[0.1, 0.2, 0.7], [0.9, 0.05, 0.05]]) pred = tf.cast(tf.argmax(a, axis=1), dtype=tf.int32) # 实际标签y y = tf.constant([2, 1]) # 计算准确率 eq = tf.equal(y, pred) correct_number = tf.reduce_sum(tf.cast(eq, dtype=tf.int32)) correct = correct_number/2 # 总数为2 print(correct) # tf.Tensor(0.5, shape=(), dtype=float64) print(correct.numpy()) # 0.5
tf.unique(a)
a必须是一维的!
获得不重复的数据(类似于求集合中的元素),结果为两部分,一部分是包含数据的tensor, 一部分包含可以用来恢复原始数据的索引的tensor。
a = tf.constant([[0.1, 0.2, 0.7], [0.2, 0.05, 0.05]]) print(tf.unique(a)) # 报错 InvalidArgumentError: unique expects a 1D vector. [Op:Unique]
a = tf.constant([[0.1, 0.2, 0.7], [0.2, 0.05, 0.05]]) a = tf.reshape(a, [-1]) prit(a.numpy()) print(tf.unique(a)) # 结果有两部分,数据和index # Unique(y=<tf.Tensor: shape=(4,), dtype=float32, numpy=array([0.1 , 0.2 , 0.7 , 0.05], dtype=float32)>, idx=<tf.Tensor: shape=(6,), dtype=int32, numpy=array([0, 1, 2, 1, 3, 3])>)
a = tf.constant([[0.1, 0.2, 0.7], [0.2, 0.05, 0.05]]) a = tf.reshape(a, [-1]) print(a.numpy()) # [0.1 0.2 0.7 0.2 0.05 0.05] b = tf.unique(a) print(type(b)) # <class'tensorflow.python.ops.gen_array_ops.Unique'> print(b.numpy()) # AttributeError: 'Unique' object has no attribute 'numpy' print(b[0]) # tf.Tensor([0.1 0.2 0.7 0.05], shape=(4,), dtype=float32) print(b[1]) # tf.Tensor([0 1 2 1 3 3], shape=(6,), dtype=int32) c = tf.gather(b[0], b[1]) print(c) # tf.Tensor([0.1 0.2 0.7 0.2 0.05 0.05], shape=(6,), dtype=float32) d = tf.gather(b[0], b[1].numpy()) print(d) # tf.Tensor([0.1 0.2 0.7 0.2 0.05 0.05], shape=(6,), dtype=float32)
a = tf.random.uniform([2, 5, 4]) a = tf.reshape(a, [-1]) # 用此方法可以将任意维转化为一维 print(a.shape) # (40,)
张量排序
tf.sort (a, axis = -1, direction="")、tf.argsort (a, direction="")
a = tf.random.shuffle(tf.range(5)) print(a) # tf.Tensor([4 0 3 2 1], shape=(5,), dtype=int32) b = tf.sort(a, direction="DESCENDING") print(b) # tf.Tensor([4 3 2 1 0], shape=(5,), dtype=int32) idx = tf.argsort(a, direction="DESCENDING") print(idx) # tf.Tensor([0 2 3 4 1], shape=(5,), dtype=int32) c = tf.gather(a, idx) print(c) # tf.Tensor([4 3 2 1 0], shape=(5,), dtype=int32)
对矩阵排序:
a = tf.random.uniform([3, 3], maxval=10, dtype=tf.int32) print(a.numpy()) # [[9 9 8] # [5 0 3] # [2 9 5]] b = tf.sort(a) print(b.numpy()) # 对矩阵,默认对行升序排列 # [[8 9 9] # [0 3 5] # [2 5 9]] c = tf.sort(a, direction="DESCENDING") print(c.numpy()) # [[9 9 8] # [5 3 0] # [9 5 2]] ind = tf.argsort(a) print(ind.numpy()) # [[2 1 0] # [1 0 2] # [1 2 0]]
tf.math.top_k (a, k)
a = tf.random.uniform([2, 3], maxval=10, dtype=tf.int32) print(a.numpy()) # [[6 8 0] # [7 9 2]] res = tf.math.top_k(a, 2) # 依然是按行 print(res.values) # tf.Tensor( # [[8 6] # [9 7]], shape=(2, 2), dtype=int32) print(res.indices) # tf.Tensor( # [[1 0] # [1 0]], shape=(2, 2), dtype=int32)
prob = tf.constant([[0.1, 0.2, 0.7], [0.2, 0.7, 0.1]]) target = tf.constant([2, 0]) k_b = tf.math.top_k(prob, 1).indices print(k_b) k_b = tf.transpose(k_b, [1, 0]) print(k_b) target = tf.broadcast_to(target, [1, 2]) correct_bool = tf.equal(k_b, target) correct_num = tf.cast(correct_bool, dtype=tf.int32) result = tf.reduce_sum(correct_num)/2 print(result) # tf.Tensor(0.5, shape=(), dtype=float64)
填充与复制
tf.pad(a, [[行维度上,下],[列维度左,右]])
a = tf.reshape(tf.range(9), [3, 3]) print(a.numpy()) # [[0 1 2] # [3 4 5] # [6 7 8]] b = tf.pad(a, [[1, 0], [0, 1]]) print(b.numpy()) # [[0 0 0 0] # [0 1 2 0] # [3 4 5 0] # [6 7 8 0]]
Image padding:
a = tf.random.normal([4, 28, 28, 3]) b = tf.pad(a, [[0, 0], [2, 2], [2, 2], [0, 0]]) print(b.shape) # (4, 32, 32, 3)
tf.tile(a, [维度1复制倍数, 维度2复制倍数,……])
a = tf.reshape(tf.range(8), [2, 4]) print(a.numpy()) # [[0 1 2 3] # [4 5 6 7]] b = tf.tile(a, [1, 2]) print(b.numpy()) # [[0 1 2 3 0 1 2 3] # [4 5 6 7 4 5 6 7]] c = tf.tile(a, [2, 1]) print(c.numpy()) # [[0 1 2 3] # [4 5 6 7] # [0 1 2 3] # [4 5 6 7]]
tf.tile 和 tf.broadcast_to() 都能实现复制,但是broadcast只在运行时复制,不占用内存,性能更好。
a.shape为(1, 3, 3)
tf.tile(a, [2, 1, 1])的效果与tf.broadcast_to(a, [2, 3, 3])相同。
张量限幅
tf.clip_by_value(a, min, max)
a = tf.range(10) b = tf.maximum(a, 2) # 取两者中的大值 print(b.numpy()) # [2 2 2 3 4 5 6 7 8 9] c = tf.minimum(a, 8) print(c.numpy()) # [0 1 2 3 4 5 6 7 8 8] d = tf.clip_by_value(a, 2, 8) # 将值限制在2~8之间(比2小的变为2,比8大的变为8) print(d.numpy()) # [2 2 2 3 4 5 6 7 8 8]
实现relu函数(即y = max(0, x)):
a = tf.range(10) a = a-5 print(tf.nn.relu(a).numpy()) # [0 0 0 0 0 0 1 2 3 4] print(tf.maximum(a, 0).numpy()) # [0 0 0 0 0 0 1 2 3 4]
tf.clip_by_norm(a, 15)
将a的二阶范数限制为15.
a = tf.random.normal([2, 2], mean=10) print(tf.norm(a)) # tf.Tensor(20.621208, shape=(), dtype=float32) b = tf.clip_by_norm(a, 15) print(tf.norm(b)) # tf.Tensor(14.999999, shape=(), dtype=float32)
tf.clip_by_global_norm(grads, 15)
-----Gradient Clippping
a = tf.Variable(1.) b = tf.Variable(2.) with tf.GradientTape() as tape: y = a**2 + b**2 grad = tape.gradient(y, [a, b]) print(type(grad)) # <class 'list'> print(grad) # [<tf.Tensor: shape=(), dtype=float32, numpy=2.0>, <tf.Tensor: shape=(), dtype=float32, numpy=4.0>]
函数源代码(ctrl+b):
a = tf.Variable(6.) b = tf.Variable(8.) with tf.GradientTape() as tape: y = a**2 + b**2 grads = tape.gradient(y, [a, b]) print(grads) print("after") grads = tf.clip_by_global_norm(grads, 10) print(grads) for g in grads: print(tf.norm(g))
运行结果:
修正:
a = tf.Variable(6.) b = tf.Variable(8.) with tf.GradientTape() as tape: y = a**2 + b**2 grads= tape.gradient(y, [a, b]) print(grads) print("after") grads, _ = tf.clip_by_global_norm(grads, 5) print(grads) for g in grads: print(tf.norm(g))
其他高阶操作
tf.where(mask)
a = tf.random.normal([3, 3]) mask = a > 0 print(mask) b = tf.boolean_mask(a, mask) print(b)
运行结果:
a = tf.random.normal([3, 3]) mask = a > 0 print(mask) indices = tf.where(mask) print(indices) b = tf.gather_nd(a, indices) print(b)
运行结果:
tf.where(cond, A, B)
mask = tf.cast(tf.random.uniform([3,3], minval=-2, maxval=3, dtype=tf.int32), dtype=tf.bool) print(mask) a = tf.ones([3, 3]) b = tf.zeros([3, 3]) # mask中true从a中对应位置取值,false从b中对应位置取值 c = tf.where(mask, a, b) print(c)
tf.scatter_nd(indices, updates, shape)
默认基底shape为全零
indices = tf.constant([[4], [3], [1], [7]]) updates = tf.constant([9, 10, 11, 12]) shape = tf.constant([8]) result = tf.scatter_nd(indices, updates, shape) print(result) # tf.Tensor([ 0 11 0 10 9 0 0 12], shape=(8,), dtype=int32)
tf.meshgrid(x, y)
y = tf.linspace(-2., 2, 5) # 浮点型,否则报错 print(y) # tf.Tensor([-2. -1. 0. 1. 2.], shape=(5,), dtype=float32) x = tf.linspace(-2., 2, 5) points_x, points_y = tf.meshgrid(x, y) print(points_x) # tf.Tensor( #[[-2. -1. 0. 1. 2.] # [-2. -1. 0. 1. 2.] # [-2. -1. 0. 1. 2.] # [-2. -1. 0. 1. 2.] # [-2. -1. 0. 1. 2.]], shape=(5, 5), dtype=float32) print(points_y) # tf.Tensor( #[[-2. -2. -2. -2. -2.] # [-1. -1. -1. -1. -1.] # [ 0. 0. 0. 0. 0.] # [ 1. 1. 1. 1. 1.] # [ 2. 2. 2. 2. 2.]], shape=(5, 5), dtype=float32) points = tf.stack([points_x, points_y], axis=2) print(points.shape) # (5, 5, 2) print(points) # 变成坐标
例:
import tensorflow as tf import matplotlib.pyplot as plt def func(x): z = tf.math.sin(x[..., 0]) + tf.math.sin(x[..., 1]) return z if __name__ == '__main__': x = tf.linspace(0., 2 * 3.14, 500) y = tf.linspace(0., 2 * 3.14, 500) point_x, point_y = tf.meshgrid(x, y) points = tf.stack([point_x, point_y], axis=2) # [50, 50, 2 ] z = func(points) print(z.shape) # (500,500) plt.figure('plot 2d func value') plt.imshow(z, origin='lower', interpolation='none') plt.colorbar() plt.figure('plot 2d func contour') plt.contour(point_x, point_y, z) plt.colorbar() plt.show()
本文地址:https://blog.csdn.net/weixin_43543210/article/details/108230823