【深度学习_TensorFlow】索引与切片

写在前面

这是一篇关于 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 )冒号切片:变量[ 开始 ; 结束 ]

  • 简单介绍

单冒号:变量[ start : end ]
原理:
前一个索引表示切片的起始位置,后一个索引表示切片的结束位置(结束位置不包括该位置的元素,简言之就是左闭右开。)
我们将从0-9的10个元素组成的tensor中( [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] )切片
若从左到右正向索引,第一位元素0的下标就为0,后面依次是1,2,3…
若从右向左逆向索引,最后一位元素9的下标就为-1,从右向左依次为-2,-3…
特殊情况:
若左边的下标不写,编译器默认为1,若右边的下标不写,编译器默认为-1

双冒号:变量[ start : end : step ]
原理
在单冒号切片的基础之上,又加了一个步长(可正可负),就能实现相隔指定位置来切片
我们讲从0~9的10个元素组成的tensor中( [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] )切片
若步长为正值,则从左到右,正向每隔指定步长取值
若步长为负值,则从右到左,逆向每隔指定步长取值
特殊情况
若左边的下标不写,逆向时start对应最后一个元素,end对应第一个元素

  • 单冒号代码示例
# 创建一个包含 [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( )函数

  • 简单介绍

tf.gather( tensor, axis, indices=[ ] )
value:代表tensor数据
axis: 代表取哪个维度
indices: 数据收集顺序,指定维度的具体索引

  • 代码示例
# 假设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( )函数

  • 简单介绍

tf.boolean_mask( tensor, mask=布尔标记, axis=指定维度 )
布尔标记为True或者False
axis在不赋值的情况下,默认为0

  • 代码示例
# 假设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)

写在后面

👍🏻点赞,你的认可是我创作的动力!
⭐收藏,你的青睐是我努力的方向!
✏️评论,你的意见是我进步的财富!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

畅游星辰大海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值