TensorFlow深度学习:4.1.张量的结构操作

1.创建张量

常数张量:

a = tf.constant([1,2,3],dtype = tf.float32)

区间内恒定步长的张量:

b = tf.range(1,10,delta = 2)
tf.print(b)  ==>[1 3 5 7 9]

区间内以总长度的n分之一为步长的张量

c = tf.linspace(0.0,2*3.14,100)
tf.print(c)   ==>  [0 0.0634343475 0.126868695 ... 6.15313148 6.21656609 6.28]

全零张量以及与某一张量结构相等的张量

d = tf.zeros([3,3])
b = tf.zeros_like(,dtype= tf.float32)

全1张量

a = tf.ones([3,3])

以某一数填充指定形状的张量

b = tf.fill([3,2],5)

均匀分布随机张量

tf.random.set_seed(1.0)
a = tf.random.uniform([5],minval=0,maxval=10)
tf.print(a)  ===>   [1.65130854 9.01481247 6.30974197 4.34546089 2.9193902]

正态分布随机张量

b = tf.random.normal([3,3],mean=0.0,stddev=1.0)

正态分布随机,剔除2倍方差以外数据重新生成

c = tf.random.truncated_normal((5,5), mean=0.0, stddev=1.0, dtype=tf.float32)

单位矩阵

I = tf.eye(3,3) 

对角阵

t = tf.linalg.diag([1,2,3]) 

2.索引切片

提取张量的连续子区域:tf.slice.
不规则的切片提取:tf.gather,tf.gather_nd,tf.boolean_mask。

2.2.tf.slice.

tf.slice(input_, begin, size, name=None)
  • size:切片的尺寸
  • begin:开始位置,相当于相对输入数据
  • input_的每一个偏移量

2.3.tf.gather

只能取某一维的不连续索引数据

tf.gather(
    params, indices, validate_indices=None, axis=None, batch_dims=0, name=None
    )
  • params:输入
  • indices:想要获取维度上的索引值
  • axis:进行操作的维度

2.3.tf.gather_nd

tf.gather只能对低维度进行操作,gather_nd可以进行高维度的操作,允许在多维上进行索引,直接通过坐标取数(索引维度与tensor维度相同)

tf.gather_nd(
    params, indices, batch_dims=0, name=None)

示例:

scores = tf.random.uniform((4,10,7),minval=0,maxval=100,dtype=tf.int32)
#抽取每个班级第0个学生,第5个学生,第9个学生的全部成绩
p = tf.gather(scores,[0,5,9],axis=1)
#抽取每个班级第0个学生,第5个学生,第9个学生的第1门课程,第3门课程,第6门课程成绩
q = tf.gather(tf.gather(scores,[0,5,9],axis=1),[1,3,6],axis=2)
# 抽取第0个班级第0个学生,第2个班级的第4个学生,第3个班级的第6个学生的全部成绩
#indices的长度为采样样本的个数,每个元素为采样位置的坐标
s = tf.gather_nd(scores,indices = [(0,0),(2,4),(3,6)])

2.4.tf.boolean_mask

tf.boolean_mask(tensor,mask,name='boolean_mask',axis=None)

tf.gather和tf.gather_nd的功能也可以用tf.boolean_mask来实现。

#抽取每个班级第0个学生,第5个学生,第9个学生的全部成绩
p = tf.boolean_mask(scores,[True,False,False,False,False,
                            True,False,False,False,True],axis=1)

#利用tf.boolean_mask可以实现布尔索引
#找到矩阵中小于0的元素
c = tf.constant([[-1,1,-1],[2,2,-2],[3,-3,3]],dtype=tf.float32)
tf.print(c,"\n")
tf.print(tf.boolean_mask(c,c<0),"\n") 
tf.print(c[c<0]) #等价

3.修改张量的某些元素

如果要通过修改张量的部分元素值得到新的张量,可以使用tf.where和tf.scatter_nd
tf.where可以理解为if的张量版本,此外它还可以用于找到满足条件的所有元素的位置坐标。
tf.scatter_nd可以将某些值插入到一个给定shape的全0的张量的指定位置处。

3.1.tf.where

#将返回所有满足条件的位置坐标
tf.where(input, name=None)
#将a中对应input中true的位置的元素值不变
#其余元素进行替换,替换成b中对应位置的元素值。
tf.where(input, a,b)

3.2.tf.scatter_nd

tf.scatter_nd(indices,updates,shape,name=None)

示例

indices = tf.constant([[4], [3], [1], [7]])
updates = tf.constant([9, 10, 11, 12])
shape = tf.constant([8])
scatter = tf.scatter_nd(indices, updates, shape)
with tf.Session() as sess:
  print(sess.run(scatter))

将全零张量[4][3][1][7]对应位置的元素变为

9101112
》》[0, 11, 0, 10, 9, 0, 0, 12]

相当于先生成一个形状为shape的全零张量,然后根据按照indices顺序下来的数字,将全零张量对应位置的元素变为updates顺序下来的数字

4.维度变换

维度变换相关函数主要有 tf.reshape, tf.squeeze, tf.expand_dims, tf.transpose.

4.1.tf.reshape ——改变张量的形状。

a = tf.random.uniform(shape=[1,3,3,2],
                      minval=0,maxval=255,dtype=tf.int32)
tf.print(a.shape)
tf.print(a)
# 改成 (3,6)形状的张量
b = tf.reshape(a,[3,6])
tf.print(b.shape)
tf.print(b)

运行结果对比:

TensorShape([1, 3, 3, 2])
[[[[135 178]
   [26 116]
   [29 224]]
                                        TensorShape([3, 6])
  [[179 219]          ==========[[135 178 26 116 29 224]
   [153 209]                             [179 219 153 209 111 215]
   [111 215]]                             [39 7 138 129 59 205]]                      
 
  [[39 7]
   [138 129]
   [59 205]]]]

4.2.tf.squeeze ——减少维度。

如果张量在某个维上只有一个元素,利用tf.squeeze可以消除这个维度。
和tf.reshape相似,它本质上不会改变张量元素的存储顺序。
张量的各个元素在内存中是线性存储的,其一般规律是,同一层级中的相邻元素的物理地址也相邻。

s = tf.squeeze(a)
tf.print(s.shape)
tf.print(s)

运行结果

TensorShape([3, 3, 2])
[[[135 178]
  [26 116]
  [29 224]]

 [[179 219]
  [153 209]
  [111 215]]

 [[39 7]
  [138 129]
  [59 205]]]

4.3.tf.expand_dims ——增加维度。

tf.expand_dims(input, axis, name=None)

在第axis位置增加一个维度

d = tf.expand_dims(s,axis=0) #在第0维插入长度为1的一个维度
#运行后,d又变回了a一样的形状:shape=(1, 3, 3, 2)

4.4.tf.transpose ——交换维度。

tf.transpose可以交换张量的维度,与tf.reshape不同,它会改变张量元素的存储顺序。
tf.transpose常用于图片存储格式的变换上

tf.transpose(a, perm=None, conjugate=False, name='transpose')

置换 a,根据 perm 重新排列尺寸,返回的张量的维度 i 将对应于输入维度 perm[i].如果 perm 没有给出,它被设置为(n-1 … 0)

5.合并分割

tf.concat和tf.stack方法对多个张量进行合并,可以用tf.split方法把一个张量分割成多个张量。
tf.concat和tf.stack有略微的区别,tf.concat是连接,不会增加维度,而tf.stack是堆叠,会增加维度。

5.1.tf.concat

tf.concat([tensor1, tensor2, tensor3,...], axis)

示例

a = tf.constant([[1.0,2.0],[3.0,4.0]])
b = tf.constant([[5.0,6.0],[7.0,8.0]])
c = tf.constant([[9.0,10.0],[11.0,12.0]])

tf.concat([a,b,c],axis = 0)
tf.concat([a,b,c],axis = 1)

结果对比:

<tf.Tensor: shape=(6, 2), dtype=float32, numpy=
array([[ 1.,  2.],
       [ 3.,  4.],        <tf.Tensor: shape=(2, 6), dtype=float32, numpy=
       [ 5.,  6.],   ===》 array([[ 1.,  2.,  5.,  6.,  9., 10.],
       [ 7.,  8.],         [ 3.,  4.,  7.,  8., 11., 12.]], dtype=float32)>
       [ 9., 10.],
       [11., 12.]], dtype=float32)>

5.2.tf.stack

tf.stack(values, axis=0, name='stack')

示例:

tf.stack([a,b,c])
tf.stack([a,b,c],axis=1)

结果对比:

<tf.Tensor: shape=(3, 2, 2), dtype=float32, numpy=
tf.stack([a,b,c],axis=1)
array([[[ 1.,  2.],        <tf.Tensor: shape=(2, 3, 2), dtype=float32, numpy=
        [ 3.,  4.]],            array([[[ 1.,  2.],
                                        [ 5.,  6.],
       [[ 5.,  6.],  ========[ 9., 10.]],
        [ 7.,  8.]],
                                        [[ 3.,  4.],
       [[ 9., 10.],                      [ 7.,  8.],
        [11., 12.]]], dtype=float32)>   [11., 12.]]], dtype=float32)>

5.3.tf.split

tf.concat的逆运算,可以指定分割份数平均分割,也可以通过指定每份的记录数量进行分割。

tf.split( value, num_or_size_splits, axis=0, num=None, name='split')

如果num_or_size_splits是一个整数,则value是沿着维度axis成num_or_size_splits分裂较小张量。这要求value.shape[axis]是整除num_or_size_splits
如果num_or_size_splits是1 d张量(或列表),然后value被分成len(num_or_size_splits)个小张量,沿着维度axis每个小张量的大小为尺寸是value在axis维的长度/len(num_or_size_splits)

x = tf.Variable(tf.random.uniform([5, 30], -1, 1))

# Split `x` into 3 tensors along dimension 1
s0, s1, s2 = tf.split(x, num_or_size_splits=3, axis=1)
tf.shape(s0).numpy()
==》array([5,10],dtype=32)

# Split `x` into 3 tensors with sizes [4, 15, 11] along dimension 1
split0, split1, split2 = tf.split(x, [4, 15, 11], 1)
tf.shape(split0).numpy()
==》array([5,4],dtype=32)
tf.shape(split1).numpy()
==》array([5,15],dtype=32)
tf.shape(split2).numpy()
==》array([5,11],dtype=32)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值