提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、数据合并
1. concat
cancat就是让两个维度相同的张量连接在一起,可指定某一axis对应的维度连接,但是其他维度数值均要相等
import tensorflow as tf
a = tf.ones([4, 35, 8])
b = tf.ones([4, 22, 8])
c = tf.concat([a, b], axis=1) #除了axis=1这个维度,其他的维度两个张量均要相等
print(c.shape)
2. stack
stack 使用过后会增加新的维度。eg:一个张量a【4,35,8】表示4个班级,每个班级有35个学生,每个学生有8门课的成绩;现在又有一个张量b【4,35,8】表示另一个学校的4个班级,其他数量一样,在理解层面上,如果把这两个张量相加,应该是【2,4,35,8】第一个维度2代表两个学校,这样的方式理解起来更有意义。所以stack就是这样一种操作,会生成新的维度。并且,两个相加的张量需要保证每个维度数值都相等。
m = tf.ones([4, 35, 8])
n = tf.ones([4, 35, 8])
print(tf.stack([m, n]).shape)
print(tf.stack([m, n], axis=0).shape)
print(tf.stack([m, n], axis=2).shape)
print(tf.stack([m, n],axis=3).shape)
可以指定axis的值用于放置新生成的维度,一般会放在最前面,符合理解的意义。
二、数据分割
1. unstack
unstack就是stack的逆操作,把一个张量按照某一个维度切分开
代码如下(示例):
p = tf.ones([2, 4, 35, 8])
q, r = tf.unstack(p, axis=0)
print(q.shape, r.shape)
这里有一个问题:如果把axis设为3,就是说把8那个维度分隔开,还能分成两个吗?
答案是不可以,按8那个维度进行切分,就会生成8个新张量,每个张量的shape都为【2,4,35】.
这就是unstack的问题,它并不能指定分成几份。
p = tf.ones([2, 4, 35, 8])
res = tf.unstack(p, axis=3)
print(len(res))
print(res[0].shape)
并且用unstack切分后,数据的shape会自动降维,去除为1的维度
2. split
split就是在unstack的基础上进行完善,可以指定任意的切割份数,并且控制每一份的大小。
代码如下(示例):
x = tf.ones([2, 4, 35, 8])
# num_or_size_splits指定切分成几份
lips1 = tf.split(x, axis=3, num_or_size_splits=2)
lips2 = tf.split(x, axis=3, num_or_size_splits=8)
print(len(lips1))
print(lips1[0].shape)
print(len(lips2))
print(lips2[0].shape)
# 也可以确切指出在axis轴上切成每一份的大小
lips3 = tf.split(x, axis=3, num_or_size_splits=[2, 2, 4])
print(len(lips3))
print(lips3[0].shape)
print(lips3[1].shape)
print(lips3[2].shape)
即使维度的数值有1,split也不会自动降维
三、数据统计
1. 范数
- 一范数: 张量中各个元素取绝对值然后求和
- 二范数:张量中各个元素取平方然后求和最后开根号
- 无穷范数:张量中各个元素取绝对值然后取绝对值最大的那个值
tf.norm 函数用于求范数
- 设定ord=1表示求L1范数,令ord=2表示求L2范数,不给出ord时默认求L2范数
- 设定axis值表示在某一维度上进行求范数运算
代码如下(示例):
a = tf.ones([2, 2])
print(tf.norm(a))
print(tf.norm(a, ord=1))
print(tf.norm(a, ord=1, axis=1))
b = tf.ones([4, 28, 28, 3])
print(tf.norm(b))
2. 最大值最小值均值
p = tf.random.normal([4, 10])
# 求最小值
print(tf.reduce_min(p)) # 不给出axis时,默认求整个张量的最小值
print(tf.reduce_min(p, axis=1)) # 在axis=1的坐标轴上求最小值,因为有4个10列,所以会返回4个数据
# 求最大值
print(tf.reduce_max(p))
print(tf.reduce_max(p, axis=1)) # 在axis=1的坐标轴上求最大值,因为有4个10列,所以会返回4个数据
# 求均值
print(tf.reduce_mean(p))
print(tf.reduce_mean(p, axis=1)) # 在axis=1的坐标轴上求均值,因为有4个10列,所以会返回4个数据
对于求最大值和最小值,还有argmax和argmin函数用于返回目标值的位置信息。
p = tf.random.normal([4, 10])
print(tf.argmin(p)) # 不指定axis时,默认axis=0,所以会返回10个数据,每一个数据代表每一列最小元素的索引
print(tf.argmin(p, axis=1).shape) # axis=1,那么返回的数就有4个
print(tf.argmax(p))
print(tf.argmax(p, axis=1).shape)
3. 比较
tf.equal 用于比较张量间的大小关系,前提是两个张量的shape要一样。其比较的方法是:依次比较每一组对应的元素,判断是否相等,若相等记为True,若不等,记为False。
返回值就是一个对应shape的真值表。
m = tf.random.normal([4, 10])
n = tf.random.normal([4, 10])
print(tf.equal(m, n))
利用这样一种方法可以判断预测值与真实值有多少个相等,即可以算出Accuracy。一般True=1,False=0, 可以将得到的真值表从bool型转化为int型,再对整个表求和,sum值就代表了有多少个值相等。
m = tf.random.normal([4, 10])
n = tf.random.normal([4, 10])
print(tf.equal(m, n))
res = tf.equal(m, n)
sum = tf.reduce_sum(tf.cast(res, dtype=tf.int32))
print(sum)
4. 去重
tf.unique 函数返回一个张量中不重复的元素,并且都是记录新元素第一次出现的位置
x = tf.range(5)
print(tf.unique(x))
y = tf.constant([4, 2, 3, 2, 3, 6])
print(tf.unique(y))
unique的输出分为两部分:
- 第一部分就是去重后的数据
- 第二部分是操作前的数据再去重后的数据上位置的映射