Tensorflow 这个框架一开始创建的时候,想做成一个类似编程语言似的东西,所以它像编程语言一样有数据类型的概念。
在学习数据类型之前,我们先了解一下数学的一个概念。
维数 | 阶 | 数学叫法 |
---|---|---|
0-D | 0 | 标量(scalar) |
1-D | 1 | 向量(vector) |
2-D | 2 | 矩阵(matrix) |
n-D | n | 张量(tensor) |
张量是指(标量,向量,矩阵,多维度的...),所以通俗意义上来说:标量,向量,矩阵统称张量。
在后面的学习中,我们使用 tensorflow 定义张量(标量,向量,矩阵,多维度张量)。
注意:为了少打几个字母,后面我会用 tf 来简称 tensorflow。
tf 的数据类型很简单,基本上有以下几种:
tf.int 整数类型
tf.float 浮点类型
tf.bool 布尔类型
tf.string 字符串类型
注意:tf 的数据在做四则运算的时候,只有同类型才可以,整数类型和浮点数类型做四则运算也会报错,它不会像 C 语言一样支持模糊转换。
我们可以使用 tf 的 constant 函数来定义常量。
import tensorflow as tf a = tf.constant(5) print(a)
运行结果如下:
tf.Tensor(5, shape=(), dtype=int32)
重要说明:在 tf 中,每个数据(无论什么类型)都是一个 tensor,tf 中的变量无论是初始化还是运算的结果,都是一个 tensor。
以上代码中,我们用 tf.constant(5)
构建一个 tensor,然后赋值给变量 a。我们打印出 a 这个
tensor 的值,该 tensor 的值为: tf.Tensor(5, shape=(), dtype=int32)
。
tf.Tensor(5, shape=(), dtype=int32)解析:
5 是 tensor 的数据值。
shape=() 表示该 tensor 的维度为 0-D,也就是该 tensor 是一个标量。
sdtype=int32 表示该 tensor 的数据值的类型是 int32(32位的整型)。
总结:有次我们可以知道变量 a 是一个 tensor,该 tensor 的数据值为 5,是一个 0-D 维度的标量,数据值的类型为 int32。
上面我们用一个数值初始化一个 tensor,得到的是维度为 0-D 的标量。
当用一维数组来初始化一个 tensor,得到的是维度为 1-D 的向量。
# 一维度(向量)张量 a = tf.constant([1, 2, 6]) #
当用二维数组来初始化一个 tensor,得到的是维度为 2-D 的矩阵。
# 二维(矩阵)张量 c = [[2, 3, 4], [4, 5, 6], [5, 5, 5]]
在人工智能实际开发中,我们常用的只有标量,向量和矩阵,更高维度的张量很少用到,在此不在赘述。
大家注意:以上 tensor 的数值都是整数,同样我们也可以用浮点数和字符串初始化 tensor。
tf2中可以用Variable 函数定义一个变量,变量和常量的区别,就在于变量可以改变自身的值,而常量不能改变。tf2 中的变量会被标记为:“可训练”,我们在神经网络反向传播中经常要改变变量的值,我们常常把参数定义为变量。
import tensorflow as tf t0 = tf.Variable(5) # t0 tensor 中的数值是一个变量 t1 = tf.constant(8) # t1 tensor 中的数值是一个常量 t0.assign(t1) # 正确,把 t1 tensor 中的数值赋值给 t0 tensor 中的数值 print(t0) t1.assign(t0) # 错误,t1 tensor 中的数值是常量,不允许被改变
由上可知:tensor 里面的数值为变量,该数值是可以修改的;tensor 里面的数值为常量,该数值是不可以修改的。
1.tf 的张量(无论是常量还是变量)提供以下常用的数学运算。
a.对应元素的四则运算:tf.add, tf.substract, tf.multiply, tf.divide
b.平方,次方和开方:tf.square, tf.pow, tf.sqrt
c.如果 tf 的张量是矩阵的话,支持矩阵的叉乘:tf.matmul
注意:tf 对参与运算的张量含有的 tensor(张量里面的某个元素)的数据类型要求必须相同。
a = tf.constant(3) b = tf.constant(5.0) print(a + b)
上面例子定义两个变量,然后做加法运算,因为张量 b 中的数据 5.0 是浮点数类型,而张量 a 中的数据 3 是整数类型,两个 tensor 数据类型不同,不符合运算规则,则会报错。
2.tf 的四则运算(加减乘除),对于不符合运算规则的数据,tf 会智能补齐,无法补齐的则报错。
import tensorflow as tf a = tf.constant([1, 2]) b = tf.constant([2]) print(a + b)
程序运行的结果为:
tf.Tensor([3 4], shape=(2,), dtype=int32)
我们定义向量 a 和向量 b,向量 a 含有 2 个元素,而向量 b 含有 1 个元素;很明显 a 和 b 不符合向量的四则运算规则。但是 tf 并没有报语法错误,而是会对向量 b 补上 1 个元素,补上的元素的值为第 1 个元素的值,然后让 a 和 b 做加法运算,
注意:建议大家不要让 tf 智能补齐,自己定义好符合运算规则的数据,再做计算。
3.tf 对非四则运算则不会补齐,比如下我们定义两个矩阵常量然后做叉乘(叉乘不是四则运算),如果让这两个矩阵不符合叉乘规则,tf 就会报语法错误。
import tensorflow as tf a = tf.constant([[1], [2]]) b = tf.constant([[3], [4]]) print(tf.matmul(a, b)) # 矩阵 a 和 矩阵 b 做叉乘
叉乘的规则是第 1 个矩阵的列必须等于第 2 个矩阵的行;很明显矩阵 a 和 b 不符合矩阵的叉乘规则,tf不会智能补齐,则会直接报错。
4.tf 对字符串类型只支持加法运算,不支持其它任何四则运算。
a = tf.constant(["hello"], ["birdpython"]) b = tf.constant(["xx"], ["xxxx"]) print(a + b) # tf 对 tensor 的数据值类型为字符串的,只支持加法运算
5.对于开方运算,tf 只支持 tensor 为浮点类型的值。
c = tf.constant([[1.0], [2.0]]) # 矩阵的数据值为浮点数 rst = tf.sqrt(c) # sqrt 只支持浮点类型的tensor print(rst)
6.tf 的数学运算大都有相应的数学符号代替函数的写法。
a = tf.constant([[1], [2]]) b = tf.constant([[3], [4]]) rst = a + b # rst = tf.add(a, b) rst2 = a - b # rst = tf.subtract(a, b) rst3 = a * b # rst = tf.multiply(a, b) rst4 = a / b # rst = tf.divide(a, b) rst5 = a ** 2 # tf.square(a) rst6 = a ** 4 # tf.pow(a, 4)
总结:大家对 tensor 进行计算时尽量要让其符合计算规则,而不是让 tf 自动补齐,一个好习惯的重要性可以避免很多不必要的问题。
(x2 + y2 - 1)3 - x2y3 = 0