2.索引切片
TensorFlow索引切片的方式方法与Numpy类似,但又比较简洁
In [4]: a=tf.random.normal([4,28,28,3])
In [6]: a[1].shape
Out[6]: TensorShape([28, 28, 3])
In [7]: a[0].shape #与a[1].shape相同
Out[7]: TensorShape([28, 28, 3])
In [8]: a[1,2].shape
Out[8]: TensorShape([28, 3])
In [9]: a[1,2,3].shape
Out[9]: TensorShape([3])
a[1].shape 结果与a[1]相同
I. 切片
start:end
In [11]: a=tf.range(4)
In [12]: a
Out[12]: <tf.Tensor: id=28, shape=(4,), dtype=int32, numpy=array([0, 1, 2, 3])>
In [13]: a[-1:]
Out[13]: <tf.Tensor: id=32, shape=(1,), dtype=int32, numpy=array([3])>
In [14]: a[:2]
Out[14]: <tf.Tensor: id=36, shape=(2,), dtype=int32, numpy=array([0, 1])>
In [15]: a[:-1]
Out[15]: <tf.Tensor: id=40, shape=(3,), dtype=int32, numpy=array([0, 1, 2])>
Indexing by:
表示该维度全取
In [20]: a=tf.random.normal([4,5,6,7])
In [21]: a[:,:,:,0].shape
Out[21]: TensorShape([4, 5, 6])
In [22]: a[:,:,1,:].shape
Out[22]: TensorShape([4, 5, 7])
In [23]: a[:,:,2,:].shape
Out[23]: TensorShape([4, 5, 7])
Indexing by ::
In [24]: a=tf.random.normal([4,28,28,3])
In [25]: a.shape
Out[25]: TensorShape([4, 28, 28, 3])
In [26]: a[0:2,:,:,:].shape
Out[26]: TensorShape([2, 28, 28, 3])
In [27]: a[:,0:28:2,:,:].shape
Out[27]: TensorShape([4, 14, 28, 3])
In [28]: a[:,0:28:2,0:28:2,:].shape
Out[28]: TensorShape([4, 14, 14, 3])
In [29]: a[:,::2,::2,:].shape
Out[29]: TensorShape([4, 14, 14, 3])
::-1 逆序
In [30]: c=tf.range(4)
In [31]: c
Out[31]: <tf.Tensor: id=102, shape=(4,), dtype=int32, numpy=array([0, 1, 2, 3])>
In [32]: c[::-1]
Out[32]: <tf.Tensor: id=106, shape=(4,), dtype=int32, numpy=array([3, 2, 1, 0])>
In [33]: c[::-2] # 下标为0,1,2,3 倒着是从右向左,每隔2取一
Out[33]: <tf.Tensor: id=110, shape=(2,), dtype=int32, numpy=array([3, 1])>
In [34]: c[2::-2]
Out[34]: <tf.Tensor: id=114, shape=(2,), dtype=int32, numpy=array([2, 0])>
…省略号
可代替任意一行;每次索引只能出现一次,否则会报错
In [35]: d=tf.random.normal([2,4,28,28,3])
In [36]: d[0].shape
Out[36]: TensorShape([4, 28, 28, 3])
In [37]: d[0,:,:,:,:].shape
Out[37]: TensorShape([4, 28, 28, 3])
In [38]: d[0,...].shape #与前两个结果相同
Out[38]: TensorShape([4, 28, 28, 3])
In [40]: d[...,0].shape #省略后面的4个维度
Out[40]: TensorShape([2, 4, 28, 28])
In [41]: d[0,...,0].shape #省略中间的3个维度
Out[41]: TensorShape([4, 28, 28])
In [42]: d[0,1,...,0].shape #省略中间偏右的2个维度
Out[42]: TensorShape([28, 28])
II. Selective Indexing选择索引
tf.gather (params,indices,validate_indices=None,axis=0)
根据索引从参数轴上收集切片
索引必须是任何维度的整数张量,生产输出张量,该张量的形状为:params.shape[:axis] + indices.shape + params.shape[axis + 1:]
参数:
params:张量,是用来收集数值的,此张量的秩必须至少是axis+1
indices:int型,索引张量必须在( 0 , params.shape[axis] )的范围内
axis:int型,在参数轴从中收集索引,默认为第一维度,支持负索引
In [43]: d=tf.random.normal([4,35,8]) #4个班级,每班35人,每人的8门成绩
In [44]: tf.gather(d,axis=0,indices=[2,3]).shape #d代表data,axis代表行,indices代表索引列表
Out[44]: TensorShape([2, 35, 8])
In [46]: d[2:4].shape
Out[46]: TensorShape([2, 35, 8])
In [47]: tf.gather(d,axis=0,indices=[2,1,4,0]).shape
Out[47]: TensorShape([4, 35, 8])
In [48]: tf.gather(d,axis=1,indices=[2,3,7,9,16]).shape
Out[48]: TensorShape([4, 5, 8])
In [49]: tf.gather(d,axis=2,indices=[2,3,16]).shape
Out[49]: TensorShape([4, 35, 3])
tf.gather_nd(params,indices)
多维指定取值
In [50]: d.shape
Out[50]: TensorShape([4, 35, 8])
In [51]: tf.gather_nd(d,[0]).shape #取0号班级
Out[51]: TensorShape([35, 8])
In [52]: tf.gather_nd(d,[0,1]).shape #取0号班级的1号学生的成绩
Out[52]: TensorShape([8])
In [57]: tf.gather_nd(d,[0,1,2]).shape #取0号班级的1号学生的2号成绩,结果是一个标量
Out[57]: TensorShape([])
In [56]: tf.gather_nd(d,[ [0,1,2] ]).shape #取0号班级的1号学生的2号成绩结果是一个标量,又把结果放在了[]里,返回了一个1,可看作a[0][1][2]
Out[56]: TensorShape([1])
In [58]: tf.gather_nd(d,[ [0,0] ,[1,1]]).shape #取0号班级的0号学生和1号班级1号学的成绩
Out[58]: TensorShape([2, 8])
In [59]: tf.gather_nd(d,[ [0,0,0] ,[1,1,1]]).shape #取0号班级的0号学生的0号成绩和1号班级1号学生的1号成绩
Out[59]: TensorShape([2])
In [60]: tf.gather_nd(d,[[ [0,0,0] ,[1,1,1]]]).shape #把上述结果再放进[]里,相当于增加了一个维度
Out[60]: TensorShape([1, 2])
tf.boolean_mask(tensor,mask,axis=0)
tensor 是N维度的tensor
mask是K维度的,注意K小于等于N,axis所对应的mask维度的列表长度要与tensor所对应的维度的列表长度一致,否则会报错
axis是一个0维度的int型的tensor,表示维度
将mask中的所有为true的抽取出来,放在一起,降维
返回值:
返回一个张量,是tensor中与mask和axis所对应的内容
In [63]: a.shape
Out[63]: TensorShape([4, 28, 28, 3])
In [64]: tf.boolean_mask(a,mask=[True,True,False,False]).shape #默认axis为0轴,返回为True的结果
Out[64]: TensorShape([2, 28, 28, 3])
In [65]: tf.boolean_mask(a,mask=[True,True,False],axis=3).shape
Out[65]: TensorShape([4, 28, 28, 2]) #指定第3个轴
In [67]: b=tf.ones([2,3,4])
In [68]: tf.boolean_mask(b,mask=[[True,False,False],[True,False,False]
...: ]) #mask是对应的是2行3列,则对应的b中的前面2行3列
# 第0行的第一个元素是T,则取对于的[4],同理第二行的第一个元素是T,则取对于的[4]。最后有2个[4]
Out[68]:
<tf.Tensor: id=282, shape=(2, 4), dtype=float32, numpy=
array([[1., 1., 1., 1.],
[1., 1., 1., 1.]], dtype=float32)>
以上解释来自于不同版本,会与2.0版本的内容有所出入