broadcasting、tile
tf.broadcasting
在同一个维度上重复N次,但是不复制数据。可以大量节省内存空间。只有当待扩张的维度外的所有维度的数值是一样的时候,才能使用。
# 测试broadcasting
a = tf.ones([4, 32, 14, 14])
b = tf.ones([14])
c = tf.ones([1, 32, 1, 14])
d = tf.ones([3, 32, 14, 1])
e = a+b
print(e.shape)
e = a+c
print(e.shape)
e = a+d
print(e.shape)
# 直接将两个原始数据初始化为一个shape
userdata = tf.broadcast_to(tf.random.normal([4, 1, 1, 1]), [4, 32, 32, 3])
print(userdata.shape)
输出:
(4, 32, 14, 14)
(4, 32, 14, 14)
#当同维度的值不同,但又没有一个值是1时,是不能broadcast的
InvalidArgumentError: Incompatible shapes: [4,32,14,14] vs. [3,32,14,1] [Op:AddV2] name: add/
(4, 32, 32, 3)
tf.tile
在一个维度上重复N次并复制数据
tf.concat
合并。指定维度进行合并,其它维度数据不变。除开指定的合并维度外,其他各维度必须一致。合并不会增加维度。
# 测试合并与分割
a = tf.ones([8, 15, 22])
b = tf.ones([4, 15, 22])
c = tf.concat([a,b], axis=0)
print(c.shape)
输出:
(12, 15, 22)
tf.split
也是打散一个shape。区别在于split可以将一个维度任意的分为几个shape。
# 测试tf.split
# 均分
a = tf.ones([8, 15, 22])
e = tf.split(a, axis=2, num_or_size_splits=2)
print(e[0].shape)
print(e[1].shape)
# 任意分
e = tf.split(a, axis=2, num_or_size_splits=[2,10,10])
print(e[0].shape)
print(e[1].shape)
print(e[2].shape)
输出:
# 均分
(8, 15, 11)
(8, 15, 11)
#任意分
(8, 15, 2)
(8, 15, 10)
(8, 15, 10)
tf.stack
合并并在指定的位置创建一个新的维度。要求合并的数据的shape必须完全一致。
# 测试合并与分割
# 测试stack
b = tf.ones([4, 15, 22])
d = tf.ones([4, 15, 22]) #必须是([4, 15, 22]),不是的话会报错
e = tf.stack([d, b], axis=0)
print(e.shape)
e = tf.stack([d, b], axis=1)
print(e.shape)
输出:
(2, 4, 15, 22)
(4, 2, 15, 22)
tf.unstack
是tf.stack的逆向操作。但是tf.unstack在只指定轴的时候,会将指定的轴全部打散,什么意思呢,就是该轴值是几就会生成多少个shape相同的tensor。
# 测试unstack
f = tf.unstack(a, axis=1)
print(f[0].shape, f[14].shape)
f = tf.unstack(a, axis=0)
print(f[0].shape, f[7].shape)
输出:
(8, 22) (8, 22)
(15, 22) (15, 22)
norm
不指定维度时,默认是求所有数据的二泛数,同样的,也可以指定维度和泛数类型。
-
Eukl.Norm 二泛数
( ∑ x i 2 ) \sqrt(\sum x{_{i}}^{2}) (∑xi2) -
Max.norm 矩阵泛数:只考虑矩阵1泛数,即列泛数,矩阵每一列的所有数的绝对值的和的最大值。
-
max ∑ i m ∥ x i ∥ \max \sum_{i}^{m}\left \| x_{i} \right \| maxi∑m∥xi∥
-
L1-Norm 一泛数
∑ ∣ x i ∣ \sum |x_{i}| ∑∣xi∣
# tf.norm(sahpe, type, axis)
# tf.norm(数据, 泛数类型, 轴)
# 验证二泛数
a = tf.ones([2, 2])
b = tf.norm(a)
print(b)
c = tf.sqrt(tf.reduce_sum(tf.square(a)))
print(b)
# 指定维度求二泛数
d = tf.norm(a, ord=2, axis=1)
print(d)
a = tf.ones([32, 25, 11, 4, 3])
b = tf.norm(a)
print(b)
c = tf.sqrt(tf.reduce_sum(tf.square(a)))
print(b)
# 求一泛数
d = tf.norm(a, ord=1)
print(d)
# 指定维度求一泛数
d = tf.norm(a, ord=1, axis=1)
#print(d)
print(d.shape)
输出:
tf.Tensor(2.0, shape=(), dtype=float32)
tf.Tensor(2.0, shape=(), dtype=float32)
tf.Tensor([1.4142135 1.4142135], shape=(2,), dtype=float32)
tf.Tensor(324.96155, shape=(), dtype=float32)
tf.Tensor(324.96155, shape=(), dtype=float32)
tf.Tensor(105600.0, shape=(), dtype=float32)
(32, 11, 4, 3)