TensorFlow中的Tensor表示张量,其实就是多维数组。在Python中,张量通常存储在NunPy数组中,仅作输入输出来使用;在TensorFlow中,所有的运算都是在张量之间进行。
名称 | 区别 |
---|---|
Python列表(list ) |
元素可使用不同的数据类型,可以嵌套运用;在内存中离散存放,是一个动态的指针数组,读写效率低,占用内存,且不适合做数值计算 |
NumPy数组(ndarray ) |
元素数据类型相同,在内存中连续存放,存储空间小,读写速度快 |
TensorFlow张量(Tensor ) |
高速运行于GPU和CPU上,支持CPU、嵌入式等多种计算环境,高速的实现神经网络和深度学习的复杂算法 |
张量概念的引入是为了方便数据输入,例如将字符串文本,图像、视频等数据数字化,以便后续更容易的处理。可以通俗的作如下理解:
阶 | 数学实例 | Pyhton例子 |
---|---|---|
0阶张量 | 标量 | a=512 |
1阶张量 | 矢量(大小和方向) | v = [1, 2, 3] |
2阶张量 | 矩阵 | n = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] |
3阶张量 | t = [ [ [1], [2], [3] ], [ [4], [5], [6] ], [ [7], [8], [9] ] ] | |
n阶张量 | … | … |
tf.constant(value,dtype,shape)
函数:创建张量
其中,value值一般是数字、Python列表和NymPy数组,也可以是布尔型等
tf.convert_to_tensor()
函数:将数组、列表、数字、布尔型、字符串转换为张量。
判断张量
tf.is_tensor()
函数:判断数据对象是否为张量(tf方法)isinstance()
函数:判断数据对象是否为张量(Python方法)tf.cast(x,dtype)
函数:张量数据类型转换
张量元素的数据类型
数据类型 | 说明 | 数据类型 | 说明 |
---|---|---|---|
tf.int8 | 8位有符号整数 | tf.int16 | 16位有符号整数 |
tf.int32 | 32位有符号整数 | tf.int | 64位有符号整数 |
tf.unit8 | 8位无符号整数 | tf.complex64 | 复数的实部和虚部分别为32位浮点型 |
tf.float32 | 32位浮点数 | tf.float64 | 64位浮点数 |
tf.string | 字符串 | tf.bool | 布尔型 |
函数 | 说明 |
---|---|
tf.constant(value,dtype,shape) | 创建张量 |
tf.convert_to_tensor() | 转换为张量 |
tf.zeros(shape,dtype=tf.float32) | 创建全0张量 |
tf.ones(shale,dtype=tf.float32) | 创建全1张量 |
tf.fill(shape,value) | 创建元素相同的张量 |
tf.random.normal() | 创建元素值符合正太分布的张量 |
tf.normal.trunvated_normal(shape,mean,stddev) | 创建元素值符合截取正太分布的张量 |
tf.normal.uniform(shape,minval,maxval,dtype) | 创建元素值为整数序列的张量 |
tf.random.shuffle() | 随机打乱 |
tf.range(start,limit,delta) | range函数创建序列 |
tf.reshape(tensor,shape)
函数tf.reshape(tf.reshape(tf.range(24),[2,3,4]),[4,-1])
表示把0-23这24个数转换成3行4列的二维数组,[4, -1] 表示把二维数组转换成第一维长度为4,-1表示第二维长度根据张量元素总个数和其他维度长度自动推导出来
此操作只改变张量数组的视图,在NumPy数组中的存储数据并没有改变。
张量中轴的用法和NumPy数组中的一样,如图所示:
轴也可以是负数,表示往后向前索引,例如上图中三维张量的axis的值为也可以是-3,-2,-1
tf.expand_dlim(tensor,axis)
,axis表示增加的维度,axis可负x=tf.expand_dims(tf.constant([1,2]),axis=1)
x
将 shape = (2, ) 的一维张量增加1个维度后 shape = (2, 1)
tf.squeeze(tensor,axis)
,只能删除长度为1的维度,axis省略时删除所有长度为1的维度y=tf.squeeze(x,axis=1)
y
增加维度和删除维度只改变了张量的视图,不会改变张量的存储。
tf.transpose(a,perm)
,perm表示轴的顺序,值空时表示转置。tf.transpose(tf.reshape(tf.range(24),[2,3,4]),perm=[1,0,2])
将 shape = (2, 3, 4) 的三维张量变成 shape = (3, 2, 4) 的三维张量:
交换维度不仅改变了张量的视图,也改变了张量的存储顺序。
tf.concat(tensors,axis)
,axis表示在哪个轴上进行拼接。tf.concat([tf.constant([[1,2],[3,4]]),tf.constant([[5,6],[7,8]])],1)
在轴1上将 t2 拼接到 t1:
tf.split(value,x,axis)
,当x为数字时,表示切割成x个张量;当x为数组时,按数组值进行切割。tf.split(tf.reshape(range(12),[3,4]),[1,3],1)
将24个数形状定义为4×6的张量,再将分量以2:4的比例分割
[,
]
图像的分割与拼接,改变了张量的视图,但没有改变存储顺序。
tf.stack(values,axis)
,合并张量时创建一个新的维度。tf.stack((tf.constant([1,2]),tf.constant([3,4])),axis=1)
tf.unstack(values,axis)
,将张量分解为多个张量,分解后得到的张量和原张量维数都少了一维。tf.unstack(tf.constant([[1,2,3],[4,5,6]]),axis=0)
[,
]
索引:和Python中列表的使用方法类似,以MNIST为例(60000, 28, 28)表示有6万张图片,28表示二维图片中每个像素的灰度值。mnist[0][1][2]表示取第1张图片中的第2行的第3列。
切片:对象名[起始位置:结束位置:步长]
,三个参数都可以省略,起始位置到结束位置前闭后开。
采用切片的方式,只能进行连续的、或者有规律的采样。
gether(tensors,indices)
,用一个索引列表,将给定张量中对应索引值的元素提取处来。
tf.gather(tf.range(1,5),indices=[0,2,3])
gather(tensors,axis,indices)
,一次只能对一个维度进行索引。
tf.gather(tf.reshape(tf.range(20),[4,5]),axis=1,indices=[0,2,3])
gather_nd()
,通过指定坐标,同时采样多个点,可以同时对多个维度进行索引。
tf.gather_nd(tf.reshape(tf.range(20),[4,5]),[[0,0],[1,1],[2,3]])
# 三维张量采样——彩色图片lena(512,512,3)
import tensorflow as tf
from PIL import Image
import numpy as np
path='./pic/lena.tiff'
img=Image.open(path)
lena=np.array(img) # 图像数据化
tf.gather_nd(lena,[[0,0],[1,1],[2,3]])
算数操作 | 说明 |
---|---|
tf.add(x,y) | 将x和y逐元素相加 |
tf.subtract(x,y) | 将x和y逐元素相减 |
tf.multiply(x,y) | 将x和y逐元素相乘 |
tf.divide(x,y) | 将x和y逐元素相除 |
tf.math.mod(x,y) | 对x逐元素取模 |
tf.add(tf.constant([0,1,2]),tf.constant([3,4,5]))
算数操作 | 说明 |
---|---|
tf.pow(x,y) | 对x求y的幂次方 |
tf.square(x) | 对x逐元素求计算平方 |
tf.sqrt(x) | 对x逐元素开平方根 |
tf.exp(x) | 计算e的x次方 |
tf.math.log(x) | 计算自然对数,底数为e |
# 二维张量幂运算
tf.pow(tf.reshape(tf.range(4),[2,2]),tf.reshape(tf.range(1,5),[2,2]))
# 平方
tf.square(tf.constant([1,2,3,4]))
# 开方:开方元素必须是浮点数
tf.sqrt(tf.constant([[1.,4.],[9.,16.]]))
# 自然指数:张量的元素必须是浮点数类型
tf.exp(3.)
# 对数运算
tf.math.log(tf.constant([[1.,9.],[16.,100.]]))/tf.math.log(tf.constant([[2.,3.],[2.,10.]]))
算数操作 | 说明 |
---|---|
tf.sign(x) | 返回x的符号 |
tf.abs(x) | 对x逐元素求绝对值 |
tf.negative(x) | 对x逐元素求相反数,y = -x |
tf.reciprocal(x) | 取x的倒数 |
tf.logical_not(x) | 对x逐元素求的逻辑非 |
tf.ceil(x) | 向上取整 |
tf.floor(x) | 向下取整 |
tf.rint(x) | 取最接近的整数 |
tf.round(x) | 对x逐元素求舍入最接近的整数 |
tf.maximum(x, y) | 返回两tensor中的最大值 |
tf.minimum(x, y) | 返回两tensor中的最小值 |
算数操作 | 说明 |
---|---|
tf.cos(x) | 三角函数cos |
tf.sin(x) | 三角函数sin |
tf.tan(x) | 三角函数tan |
tf.acos(x) | 反三角函数arccos |
tf.asin(x) | 反三角函数arcsin |
tf.atan(x) | 反三角函数arctan |
方法和前面的类似,创建a=tf.constant()
后,可以直接直接对 a 使用运算符。
运算符 | 构造方法 | 运算符 | 构造方法 |
---|---|---|---|
x+y | tf.add( ) | x&y | tf.logical_and( ) |
x-y | tf.subtract( ) | x|y | tf.logical_or( ) |
x*y | tf.multiply( ) | x^y | tf.logical_xor( ) |
x/y (python2.0) | tf.divide( ) | ~x | tf.logical_not() |
x/y (python3.0) | tf.truediv( ) | xtf.less( ) |
|
x//y (python3.0) | tf.floordiv( ) | x<=y | tf.less_equal( ) |
x%y | tf.math.mod( ) | x>y | tf.greater( ) |
x**y | tf.pow( ) | x>=y | tf.greater_equal( ) |
-x | tf.neg( ) | abs(x) | tf.abs() |
a=tf.constant([[0,1,2,3],[0,-1,-2,-3]])
a//2 #整除
两个不同维度的张量相加,两个张量最后一个维度的长度必须相等。一个数字和多维张量进行算法操作时,这个数字对张量中的每一个元素进行相应的算法操作;一维张量和多维张量进行运算时,一维张量和多维张量的每一行进行运算操作;以此类推。
a=tf.constant([1,2,3])
b=tf.constant([np.arange(12).reshape(2,2,3)])
a*b
执行TensorFlow操作,TensorFlow将自动的把NumPy数组转换为张量;执行NumPy操作, NumPy将自动的张量转换为NumPy数组;只要操作数中有一个Tensor对象,就把所有 的操作数都转化为张量, 然后再进行运算。
以四维张量来举例:
a=tf.constant(np.arange(24).reshape(2,2,2,3))
b=tf.constant(np.arange(24).reshape(2,2,3,2))
a@b
前面二维相同,后面二维(2,3)×(3,2)→(2,2)→广播→(2,2,2,2)
算数操作 | 说明 |
---|---|
tf.reduce_sum(tensor,axis) | 求axis轴上值的和 |
tf.reduce_mean(tensor,axis) | 求axis轴平均值 |
tf.reduce_max(tensor,axis) | 求axis轴最大值 |
tf.reduce_min(tensor,axis) | 求axis轴最小值 |
tf.argmax() | 最值索引 |
tf.argmin() | 最值索引 |