Tensorflow2.x:tensor切片

本文介绍了如何使用Tensorflow 2.x API进行张量切片和数据插入。包括一维和高维张量的切片方法,如tf.strided_slice和tf.gather系列函数。同时讲解了在张量特定位置插入数据的技巧,如使用tf.scatter_nd,以及通过tf.tensor_scatter_nd_add/sub、tf.tensor_scatter_nd_min、tf.tensor_scatter_nd_max修改张量中的数据。


目标

利用Tensorflow 2.x API 实现以下两个目标:

  1. 对张量(tensor)切片。
  2. 在张量(tensor)的指定索引处插入数据。

提取张量切片

一维张量

t1 = tf.constant([0,1,2,3,4,5,6,7])

tf.slice(t1, begin=[1], size=[3])  # 利用tf.slice()切片    
t1[0:4]                            # 利用索引切片
t1[-3:]

高维张量

t2 = tf.constant([[0,1,2,3,4],
                 [5,6,7,8,9],
                 [10,11,12,13,14],
                 [15,16,17,18,19]])

tf.slice(t2, begin=[1,1], size=[1,2])
t2[:-1, 0:3]

tf.strided_slice :通过设定步长来提取张量切片

tf.gather :从张量的单个轴中提取特定索引

# 两种方式等价
tf.gather(t1,indices=[0,3,6]) 
t1[::3]

字符串tensor也适用:

alphabet = tf.constant(list('abcdefghijklmnopqrstuvwxyz'))

print(tf.gather(alphabet,
                indices=[2, 0, 19, 18]))

tf.Tensor([b’c’ b’a’ b’t’ b’s’], shape=(4,), dtype=string)

tf.gather_nd :从张量的多个轴中提取切片

当您想要收集矩阵的元素而不是仅收集行或列时,这很有用。

t4 = tf.constant([[0,5],
                 [1,6],
                 [2,7],
                 [3,8],
                 [4,9]])

tf.gather_nd(t4, indices=[[2],[3],[0]])

<tf.Tensor: shape=(3, 2), dtype=int32, numpy=
array([[2, 7],
[3, 8],
[0, 5]])>

在这里插入图片描述

t5 = np.reshape(np.arange(18), [2,3,3])   # 创建两个3x3的矩阵

tf.gather_nd(t5, indices=[[0,0,0],[1,2,1]])  # 返回指定元素
tf.gather_nd(t5, indices=[[[0,0], [0,2]],    # 返回两个矩阵的列表
                         [[1,0],[1,2]]])
tf.gather_nd(t5, indices=[[0,0],[0,2],[1,0],[1,2]])  # 返回一个矩阵

在张量中插入数据

tf.scatter_nd :在张量的特定索引处插入数据,插入的张量初始为0

t6 = tf.constant([10])
indices = tf.constant([[1],[3],[5],[7],[9]])
data = tf.constant([2,4,6,8,10])

tf.scatter_nd(indices=indices,
                    updates=data,
                    shape=t6)

<tf.Tensor: shape=(10,), dtype=int32, numpy=array([ 0, 2, 0, 4, 0, 6, 0, 8, 0, 10])>

tf.gather_nd 在索引外插入数据

t7 = tf.constant([2,11,18])
tf.scatter_nd(indices = tf.constant([[0,2],[2,1],[3,3]]),
             updates = t7,
             shape = tf.constant([4,5]))

<tf.Tensor: shape=(4, 5), dtype=int32, numpy=
array([[ 0, 0, 2, 0, 0],
[ 0, 0, 0, 0, 0],
[ 0, 11, 0, 0, 0],
[ 0, 0, 0, 18, 0]])>

此种插入数据的方式,等同于创建稀疏张量,不过还需将稀疏张量转换为稠密张量。

# 等同上面---利用稀疏张量创建
t8 = tf.SparseTensor(indices=[[0,2],[2,1],[3,3]],
                     values = [2,11,18],
                     dense_shape = [4,5])
print(t8)
# 将稀疏张量转换为稠密张量
t9 = tf.sparse.to_dense(t8)

SparseTensor(indices=tf.Tensor(
[[0 2]
[2 1]
[3 3]], shape=(3, 2), dtype=int64), values=tf.Tensor([ 2 11 18], shape=(3,), dtype=int32), dense_shape=tf.Tensor([4 5], shape=(2,), dtype=int64))

tf.tensor_scatter_nd_add/sub 修改tensor中的数据

tf.tensor_scatter_nd_add 将数据插入到预先存在的tensor中:

t10 = tf.constant([[2,7,0],
                   [9,0,1],
                   [0,3,8]])

t11 = tf.tensor_scatter_nd_add(t10,
                               indices=[[0,2],[1,1],[2,0]],
                               updates=[6,5,4])
print(t11)

tf.Tensor(
[[2 7 6]
[9 5 1]
[4 3 8]], shape=(3, 3), dtype=int32)

tf.tensor_scatter_nd_sub 将数据从预先存在的tensor中删减:

t12 = tf.tensor_scatter_nd_sub(t11,
                              indices=[[0,0],[0,1],[0,2]],
                              updates=[2,2,2])           # 第一行都减2
print(t12)

tf.Tensor(
[[0 5 4]
[9 5 1]
[4 3 8]], shape=(3, 3), dtype=int32)

tf.tensor_scatter_nd_min 将元素最小值从一个张量复制到另一个张量

该操作只能复制负值元素,如果将updates 改为正值,传入的会自动变为0。

t13 = tf.constant([[-2,-7,0],
                   [-9,0,1],
                   [0,-3,-8]])

t14 = tf.tensor_scatter_nd_min(t13,
                               indices=[[0,0],[0,1],[0,2]],
                               updates=[-6,-5,-4])
print(t14)

tf.Tensor(
[[-6 -7 -4]
[-9 0 1]
[ 0 -3 -8]], shape=(3, 3), dtype=int32)

tf.tensor_scatter_nd_max 将元素最大值从一个张量复制到另一个

t15 = tf.tensor_scatter_nd_max(t14
                               indices=[[0,2],[1,1],[2,0]],
                               updates=[6,5,4])
print(t15)

tf.Tensor(
[[-6 -7 6]
[-9 5 1]
[ 4 -3 -8]], shape=(3, 3), dtype=int32)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值