写在前面

这是一篇关于 TensorFlow基础索引与切片的操作,包括逗号索引,冒号索引,gather()函数, boolean_mask( )函数,作为初学者,文章难免有错误之处,还请不吝指正!


写在中间

( 1 )基础索引:变量[ ][ ]

  • 简单介绍

可以理解成多维数组的下标索引,索引方法是 变量名[ 下标 ][ 下标 ]

创建下面一个张量是什么意思?tf.ones( [ 3, 30, 30, 3 ] ) :它是一个四维的张量,形状为 (3, 30, 30, 3)。这个张量中的每个元素都是 1。具体来说,它是一个由 3 个 3x3x3 的矩阵组成的张量,每个矩阵中的每个元素都是 1 。

上述张量结合实际例子就可以理解为创建一个四维张量来储存图片信息,有3张照片,分别为30 * 30 的 3 通道彩色照片。

  • 代码示例
# 导入 TensorFlow 库
import tensorflow as tf
# 创建一个 3x30x30x3 的全1张量,默认dtype为float32
tensor = tf.ones([3, 30, 30, 3])
# 输出第一维(第一个3)的形状
print(tensor[0].shape)
# 输出第一维的第一行(索引0)的形状
print(tensor[0][0].shape)
# 输出第一维的第一行的第一个元素(索引0)的形状
print(tensor[0][0][0].shape)
  • 运行结果
(3, 3, 3)
(3, 3)
(3,)

( 2 )逗号索引:变量[ , ]

  • 简单介绍

还拿图像来举例,思路用法和上面的基础索引相同,只是形式上的不同。

  • 代码示例
# 生成一个形状为 [4, 28, 28, 3] 的四维张量,其中 4 表示样本数量,28 表示图像高度,28 表示图像宽度,3 表示图像通道数(RGB 三个通道)
tensor = tf.random.normal([4, 28, 28, 3])

# 打印 tensor[1] 的形状
print(tensor[1].shape)

# 打印 tensor[1, 2] 的形状,其中 1 表示第二个图像,2 表示高度的维度下标
print(tensor[1, 2].shape)

# 打印 tensor[1, 2, 3] 的形状,其中 3 表示宽度的维度下标
print(tensor[1, 2, 3].shape)

# 打印 tensor[1, 2, 3, 2] 的形状,其中 2 表示通道的维度下标
print(tensor[1, 2, 3, 2].shape)
  • 运行结果
(28, 28, 3)
(28, 3)
(3,)
()


( 3 )冒号切片:变量[ 开始 ; 结束 ]

  • 简单介绍
  • 单冒号代码示例
# 创建一个包含 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 的张量
tensor = tf.range(10)
# 输出整个张量
print(tensor)

# 输出张量最后一个元素(即索引为 -1 的元素)
print(tensor[-1:])

# 输出张量倒数第二个和最后一个元素(即索引为 -2 和 -1 的元素)
print(tensor[-2:])

# 输出张量前两个元素(即从索引 0 开始到索引 1 的元素)
print(tensor[:2])

# 输出张量除最后一个元素外的所有元素(即从索引 0 开始到索引 -2 的元素)
# 为什么看原理的红字部分
print(tensor[:-1])
  • 双冒号代码示例
# 导入 TensorFlow 库
import tensorflow as tf
# 创建一个 4x28x28x3 的全为一张量
tensor = tf.ones([4, 28, 28, 3])
# 打印张量的形状
print(tensor.shape)  # 输出: (4, 28, 28, 3)
# 打印张量的一部分形状
print(tensor[0:2, :, :, :].shape)

print(tensor[:, 0:28:2, 0:28:2, :].shape)

print(tensor[:, :14, :14, :].shape)

print(tensor[:, 14:, 14:, :].shape)

print(tensor[:, ::2, ::2, :].shape)

# 创建一个包含 [0, 1, 2, 3] 的张量
tensor = tf.range(4)
# 输出整个张量
print(tensor)
# 以倒序输出张量的每一个元素
print(tensor[::-1])
# 以倒序输出张量中的3和1
print(tensor[::-2])
# 以倒序输出张量中的2,1,0
print(tensor[2::-1])
  • 单冒号运行结果
tf.Tensor([0 1 2 3 4 5 6 7 8 9], shape=(10,), dtype=int32)
tf.Tensor([9], shape=(1,), dtype=int32)
tf.Tensor([8 9], shape=(2,), dtype=int32)
tf.Tensor([0 1], shape=(2,), dtype=int32)
tf.Tensor([0 1 2 3 4 5 6 7 8], shape=(9,), dtype=int32)
  • 双冒号运行结果
(4, 28, 28, 3)
(2, 28, 28, 3)
(4, 14, 14, 3)
(4, 14, 14, 3)
(4, 14, 14, 3)
(4, 14, 14, 3)
tf.Tensor([0 1 2 3], shape=(4,), dtype=int32)
tf.Tensor([3 2 1 0], shape=(4,), dtype=int32)
tf.Tensor([3 1], shape=(2,), dtype=int32)
tf.Tensor([2 1 0], shape=(3,), dtype=int32)

( 4 )tf.gather( )函数

  • 简单介绍
  • 代码示例
# 假设tensor为【班级,学生,科目】
tensor = tf.ones([4, 35, 8])

# axis=0代表班级维度,即收集第2个和第3个班级的所有人的所有成绩
# 会得到2个班级,35名同学的8门成绩
print(tf.gather(tensor, axis=0, indices=[2, 3]).shape)

# axis=1代表班级维度,即收集第2名、第3名、第7名和第9名学生的所有成绩
# 会得到4个班级,4名学生的8门成绩
print(tf.gather(tensor, axis=1, indices=[2, 3, 7, 9]).shape)

# axis=2代表成绩维度,即收集所有班级的所有学生的第2门和第3门成绩
# 会得到4个班级,35名同学的2门成绩
print(tf.gather(tensor, axis=2, indices=[2, 3]).shape)

  • 运行结果
(2, 35, 8)
(4, 4, 8)
(4, 35, 2)

( 5 )tf.boolean_mask( )函数

  • 简单介绍
  • 代码示例
# 假设tensor为【班级,学生,科目,作业】
tensor = tf.ones([4, 28, 8, 3])

# 收集班级维度中的第1个和第3个班级的全部学生的所有科目的所有作业
print(tf.boolean_mask(tensor, mask=[True, False, True, False], axis=0).shape)  # True和False不能少写

# 收集作业维度中的全部班级的所有学生的所有科目的第1门和第3门作业
print(tf.boolean_mask(tensor, mask=[True, False, True], axis=3).shape)
  • 运行结果
(2, 28, 8, 3)
(4, 28, 8, 2)

写在后面

06-19 04:24