各位同学好,今天和大家分享一下TensorFlow2.0中的数学运算方法、合并与分割。内容有:
(1)基本运算;(2)矩阵相乘;(3)合并 tf.concat()、tf.stack();(4)分割 tf.split()、tf.unstack()
那我们开始吧。
1. 基本数学运算
开始之前,我们先定义两个tensor,下面的计算都使用这两个
# 2行2列的全为2的tensor
a = tf.fill([2,2],2.)
# 2行2列全1tensor,默认float32
b = tf.ones([2,2])
1.1 加减乘除
计算前要保证两个tensor的数据类型相同。
# ==1== 加减乘除
a+b # 元素之间相加
a-b # 元素之间相减
a*b # 元素之间相乘,理解为矩阵的点乘
a/b # 元素之间相除
1.2 求余取整
# ==2== 取整求余
a // b # a/b 取整除数
a % b # a/b 取余数
1.3 对数和指数
求对数log: tf.math.log(a)
注意,这里的 log 的底数统一都是 e
a = tf.ones([2,2])
# 求a的每一个元素求对数
tf.math.log(a)
如果想要对数的底数是其他值,需要通过公式计算:
如果在tensorflow中要计算 ,方法如下,保证计算的两个tensor数据类型相同
tf.math.log(8.)/tf.math.log(2.)
指数计算
:tf.exp(tensor)
a = tf.ones([2,2])
# 对tensor中的每一个元素求ex
tf.exp(a)
1.4 求次方、开平方
求n次方:(1)tf.pow(tensor, n) (2)tensor**n
对tensor中的每个元素求n次方
求平方: tf.square(tensor)
对tensor中的每个元素求平方
开平方: tf.sqrt(tensor)
对tensor中的每个元素求平方根
a = tf.fill([2,2],2.)
#(1)求n次方
# 法一:
tf.pow(a,2)
# 法二:
a**2
#(2)开平方
tf.sqrt(a)
2. 矩阵相乘
方法:(1)变量1 @ 变量2 (2)tf.mutmul(变量1, 变量2)
2.1 对于二维矩阵
# 创建二维矩阵,保证数据类型相同
a = tf.ones([2,2]) # 2行2列全1.0
b = tf.fill([2,2],2.) # 2行2列全2.0
# 法一:
a @ b
# 法二:
tf.matmul(a,b)
2.2 对于高维矩阵
# 创建三维tensor
a = tf.ones([4,2,3])
b = tf.fill([4,3,5],2.)
# 法一:
a@b
# 法二:
tf.matmul(a,b)
可以将这几个维度理解为 [图像,行,列],将图像维度单独看作一个维度,对后面两个维度进行矩阵相乘计算,维度相乘公式如下 [b, h, w] @ [b, w, k] = [b, h, k]
利用广播对不满足要求的矩阵扩张后再进行矩阵运算,维度相乘公式为:
[b, h, w] @ [w, k] = [b, h, k]
a = tf.ones([4,2,3])
b = tf.fill([3,5],2.)
# 矩阵相乘
a @ b #计算时自动广播
3. 合并
3.1 tf.concat()
tf.concat( [tensor1,tensor2,..] , axis )
在指定的某个维度上合并,其他维度不变,不产生新的维度。在使用该方法进行合并两个tensor变量时,除axis指定的维度可以不相等,其他维度必须相等。
首先创建2个三维的tensor变量,在axis=0时的维度不同,其他维度相同。指定轴axis=0对两个tensor合并。
# 创建三维的tensor
a = tf.ones([4,35,8]) # 可以理解为收集前4个班级35名学生8门课的成绩
b = tf.ones([2,35,8])
# 将a和b合并,指定轴axis=0,在班级维度上合并
c = tf.concat([a,b],axis=0)
c.shape
3.2 tf.stack()
tf.stack([tensor1,tensor,...], axis)
在指定轴的位置创建一个新的维度,用来合并几个所有维度都相同的tensor变量。要求被合并的tensor变量的shape完全一样。如果axis是正数,在指定轴前面创建一个维度;axis是负数,在指定轴后面创建。
# 创建两个相同shape的tensor变量
a = tf.ones([4,35,8])
b = tf.ones([4,35,8])
# 在指定轴前面创建新维度合并,保证其他维度的shape相同
c = tf.stack([a,b],axis=0)
c.shape
# 若为负数在axis后面创建
d = tf.stack([a,b],axis=-2)
d.shape
4. 拆分
4.1 tf.unstack()
tf.unstack(tensor, axis)
在一个tensor变量的指定维度上,拆分这个维度。将指定维度全部拆分,该维度的shape是多少就拆分多少个。拆分后这个维度消失,不会修改原数据,需要用一个新变量接收拆分结果。
# 创建一个四维全1的tensor
a = tf.ones([2,4,35,8])
# 指定拆分axis=1这个维度,全部拆分,为4份
res = tf.unstack(a,axis=1)
# 返回一个列表,查看某个tensor的维度
res[0].shape
对指定维度axis=1进行拆分,拆分后这个维度消失,返回由4个三维tensor组成的列表,列表中每一个tensor的shape都是[2, 35, 8]
4.2 tf.split()
tf.split(tensor, axis, num_or_size_splits)
tensor为需要切分的张量;axis指定在第几个维度上切分;num_or_size_splits表示要切几份,怎么切,如果是一个整数,那直接在指定维度上把张量平均切分成几个小张量,如果是一个向量,就根据这个向量有几个元素分为几项。
拆分后,指定的轴不消失。
a = tf.ones([2,4,35,8])
# 在第1个轴上拆分,平均拆分成2份
res = tf.split(a,axis=1,num_or_size_splits=2)
res[0].shape
# 在第3个轴上拆分成2/2/4,返回一个列表
con = tf.split(a,axis=3,num_or_size_splits=[2,2,4])
con[2].shape
在轴axis=1上拆分,将该轴的shape为4,平均分成两份,返回一个由两个tensor构成的列表,每个tensor的维度都是[2,2,35,8]
在轴axis=3上按列表指定的方式来拆分,axis=3的shape为8,拆分成2/2/4,返回值是由三个tensor组成的列表,分别为[2,4,35,2]、[2,4,35,2]、[2,4,35,4]