1. 索引

首先先建立一个张量,假设这是一张图片: x = tf.random.normal([4, 32, 32, 3])

接着是索引操作:

  1. 取第一张图片的数据 x[0]
  2. 取第一张图片的第二行 x[0][1]
  3. 取第一张图片的第二行,第三列的数据 x[0][1][2]
  4. 取第 3 张图片,第 2 行,第 1 列的像素,B 通道(第 2 个通道)颜色强度值 x[2][1][0][1]
  5. 当张量的维度数较高时,使用?. . .[?]的方式书写不方便,也可以采用[?,?, … , ?]的方式索引
  6. 取第2张图片,第10行,第3列的数据 x[1,9,2]

2. 切片

通过start:end:step切片方式可以方便地提取一段数据,start为开始读取位置的索引,end为结束读取位置的索引(不包含end位),step为采样步长

  1. 读取第2,3张图片x[1:3]
    全部省略时为::,表示从最开始读到末尾,步长为1,不跳过任何元素
  2. 读取第1张图片 x[0, ::]

大体的简写方式为下表所示:

维度变换

主要函数如下:

改变视图 reshape()

插入新维度 expand_dims()

删除维度 squeeze()

交换维度 transpose()

复制数据 tile()


为什么需要维度变换? 算法的每个模块对于数据张量的格式有不同的逻辑要求,当现有的数据格式不满足算法要求时,需要通过维度变换将数据调整为正确的格式

1. 改变视图

数据在创建时按着初始的维度顺序写入,改变张量的视图仅仅是改变了张量的理解方式,并不需要改变张量的存储顺序,这在一定程度上是从计算效率考虑的,大量数据的写入操作会消耗较多的计算资源。由于存储时数据只有平坦结构,与数据的逻辑结构是分离的,因此如果新的逻辑结构不需要改变数据的存储方式,就可以节省大量计算资源,这也是改变视图操作的优势首先通过tf.range()模拟生成一个向量数据,接着通过tf.reshape改变函数产生的不同视图

1
2
x = tf.range(96)
x=tf.reshape(x,[2,4,4,3]) # 改变x的视图,获得4D张量,存储并未改变

2. 增,删维度

增加维度 增加一个长度为 1 的维度相当于给原有的数据添加一个新维度的概念,维度长度为 1,故数据并不需要改变,仅仅是改变数据的理解方式,因此它其实可以理解为改变视图的一种特殊方式 考虑一个具体例子,一张28 × 28大小的灰度图片的数据保存为 shape 为[28,28]的张量,在末尾给张量增加一新维度,定义为通道数维度,此时张量的 shape 变为[28,28,1]

1
2
3
x = tf.random.uniform([28,28],maxval=10,dtype=tf.int32)
# 通过 tf.expand_dims(x, axis)可在指定的 axis 轴前可以插入一个新的维度
x = tf.expand_dims(x,axis=2) # axis=2 表示宽维度后面的一个维度

删除维度 增加维度的逆操作,与增加维度一样,删除维度只能删除长度为 1 的维度,也不会改变张量的存储

1
x = tf.squeeze(x, axis=0) # 删除图片数量维度

交换维度 在实现算法逻辑时,在保持维度顺序不变的条件下,仅仅改变张量的理解方式是不够的,有时需要直接调整的存储顺序,即交换维度(Transpose)。通过交换维度操作,改变了张量的存储顺序,同时也改变了张量的视图 以[?, ℎ, , ?]转换到[?, ?, ℎ, ]为例,使用tf.transpose(x, prem)函数

1
2
x = tf.random.normal([2,32,32,3])
tf.transpose(x,perm=[0,3,1,2]) # 交换维度

复制数据 在新的维度上面复制若干份数据,满足后续算法的格式要求. 通过 tf.tile(x, multiples)函数完成数据在指定维度上的复制操作,multiples 分别指定了每个维度上面的复制倍数,对应位置为 1 表明不复制,为 2 表明新长度为原来长度的2 倍,即数据复制一份,以此类推

1
2
3
b = tf.constant([1,2]) # 创建向量 b
b = tf.expand_dims(b, axis=0) # 插入新维度,变成矩阵
b = tf.tile(b, multiples=[2,1]) # 样本维度上复制一份

注意!必须先增加维度后,才能进行tile。 另外一个例子,在2行2列的矩阵上进行运算.

Broadcasting(代替tile)

原理示意图

基础数学运算

记了也没用,不如实战边查边学

1
2
3
4
5
6
7
8
9
10
11
12
13
a//b # 整除运算
a%b # 余除运算
tf.pow(x,3) # 乘方运算
x**2 # 乘方运算符
x**(0.5) # 平方根
x = tf.square(x) # 平方
tf.sqrt(x) # 平方根
tf.exp(1.) # 自然指数运算
2**x # 指数运算
tf.math.log(x) # 对数运算
tf.math.log(x)/tf.math.log(10.) # 换底公式
a@b # 批量形式的矩阵相乘
tf.matmul(a,b) # 先自动扩展,再矩阵相乘

站内搜索

没有找到内容!