Tensorflow2.x:tensor切片

目录

  • 目标
  • 提取张量切片
    • 一维张量
    • 高维张量
    • tf.strided_slice :通过设定步长来提取张量切片
    • tf.gather :从张量的单个轴中提取特定索引
    • tf.gather_nd :从张量的多个轴中提取切片
  • 在张量中插入数据
    • tf.scatter_nd :在张量的特定索引处插入数据,插入的张量初始为0
  • tf.gather_nd 在索引外插入数据
    • tf.tensor_scatter_nd_add/sub 修改tensor中的数据
    • 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]])

array([[2, 7],
[3, 8],
[0, 5]])>

Tensorflow2.x:tensor切片_第1张图片

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.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]))

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)

你可能感兴趣的:(深度学习,tensorflow)