04_2_TensorFlow2基础_索引与切片&维度变换
索引与切片
Indexing
最基本的索引方式是给出每一个维度的index。
还有Numpy的索引风格是,[idx,idx, …],后面还有: 或 :: 或 …的方式
Basic indexing
最简单的索引方式,给定每一个维度的索引。
取[0] [0],那么它的shape是[5,3],每个元素的数值是1
要取更深层次的维度,[0] [0] [0],取上面的第0行,那么返回1维的向量。
如果再深入,返回的是标准的scalar(标量)
Numpy-style indexing
以下的数字均为下标
第二个为对第1张照片的shape:[28,28,3]
第三个为取第1张照片的第3行:[28,3]
第四个为第1张照片的第2行第3列的RGB具体数值:[3]
第五个为取xxx的第2通道,也就是RGB的B通道,是一个标量,0~255或归一化后的数值:[]
start:end
如果要读取数据的一部分,同时还支持倒着计数。
第1个的下标为0,最后1个的下标为-1。
A:B,相当于[A,B)
A:_和_:B,相当于取数从头或直到末尾(包含)
一些容易忘记的例子:
- a[-4:] 倒数第4个到最后一个
- a[:-4] 从-1开始到-4的元素(不包括)
例子如下图所示:
Indexing by : (冒号使用例子)
第五个为取所有行和列的R通道:[4,28,28]省略了最后面的1 ( [4,28,28,1] )
第六个为取B通道
第七个为取所有照片的所有的列的所有的通道
Indexing by ::
- start : end : step
- ::step
::-1 倒序
…
省略号可以代表任意长度的冒号
Selective Indexing
-
tf.gather
取你任意想要的行和顺序
-
tf.gather_nd
-
tf.boolean_mask
tf.gather
例子:data: [class, students, subjects],[4,35,8]
4个班级,35个学生,8个课程
tf.gather(a,axis=0,indices=[2,3,0]).shape
axis为第几个维度,indices为取哪些行
如果我们想要同时取特定同学的特定科目,进行两次函数即可
tf.gather_nd
为了获得不同班级的不同同学的成绩,也就是不连续的数据。
只取最内侧作为联合索引的坐标,作为整体。
外面套括号,会让其中合并或者再合并。
推荐,不推荐直接[0]
tf.boolean_mask
tf.boolean_mask(a,mask=[True,True,False,False],axis=0)
例子为[4,28,28,3]
下图为对第0个维度取第0和1下标行
axis为第几个维度,默认为0
tf.boolean_mask(a,mask=[[True,False,False],[False,True,True]])
下图表示 第0维度的第1维度为True,所以取第3维度的[4],等等。
最后取到三个[4],外面的[]将它们合并起来变成[3,4]
维度变换
Outline
- shape, ndim
举例:[b,28,28,1],每个都是axis(轴)。
[batch, height(row), width(column), channel]
它是一个4维的Tensor,它们的长度分别是b,28,28,28,1
View
一个content可以有多种理解方式(view)
只是增加或减少概念,1.对原来的数据没有改变,2.把原来的数据全部利用完
比如
view1 [b,28,28](保留行和列概念)
view2 [[b,28*28](缺失空间维度概念,只考虑RGB)
view3 [b,2,14*28](把图片分成上下部分,没有改变图片的数据)
view4 [b,28,28,1](多了一个channel的概念,还是没有改变content)
Reshape
我们可以对一个数据做等价变换,它不改变数据的内容,只是改变理解方式。
第三部分 可以理解为[b, pixel, c]
第四部分是第三部分的简略写法
第五部分的含义是data point
第六部分是第五部分的简略写法
Reshape is flexible
reshape提供了很多种可能性,但是我们需要选择有物理意义的操作
Reshape could lead to potential bugs
如果[4,784,3]要恢复成[4,28,28,3],需要提供额外的信息(原来content的信息,h维度在前,w维度在后(行优先);h维度是28,w维度是28)(明白物理含义)
w维度和h维度顺序弄反了也会导致错误
tf.transpose
转置,[h,w]->[w,h]
如果要改变content的顺序(倒置,旋转一个角度):
[b,h,w,c]->[b,w,h,c]
改变了数据本身
tf.transpose(a) #全部转置
tf.transpose(a,perm=[0,1,3,2]) #表示该位置放原来哪个轴度
第四个才成功->[b,3,h,w]
(Tensorflow->pytorch的数据格式)
增加一个维度和减少一个维度,不改变内容
Squeeze(挤压,减少) VS Expand_dims(展开)
Expand dim
增加学校的维度,让两个[1,4,35,8]变成[2,4,35,8]
tf.expand_dims(a,axis=0)
axis
- 如果给的轴是正数,在轴的前面增加,空白则直接增加
- 如果给的轴使负数,在轴的后面增加,空白则直接增加
Squeeze dim(减少维度)
只减少当前shape等于1的维度
1个学校,1个门课
tf.squeeze(a,axis=0)