『PyTorch』第五弹_深入理解Tensor对象_中上:索引

一、普通索引

示例

a = t.Tensor(4,5)
print(a)
print(a[0:1,:2])
print(a[0,:2])  # 注意和前一种索引出来的值相同,shape不同
print(a[[1,2]])  # 容器索引
 3.3845e+15  0.0000e+00  3.3846e+15  0.0000e+00  3.3845e+15
 0.0000e+00  3.3845e+15  0.0000e+00  3.3418e+15  0.0000e+00
 3.3845e+15  0.0000e+00  3.3846e+15  0.0000e+00  0.0000e+00
 0.0000e+00  1.5035e+38  8.5479e-43  1.5134e-43  1.2612e-41
[torch.FloatTensor of size 4x5]

 3.3845e+15  0.0000e+00
[torch.FloatTensor of size 1x2]

 3.3845e+15
 0.0000e+00
[torch.FloatTensor of size 2]

 0.0000e+00  3.3845e+15  0.0000e+00  3.3418e+15  0.0000e+00
 3.3845e+15  0.0000e+00  3.3846e+15  0.0000e+00  0.0000e+00
[torch.FloatTensor of size 2x5]

普通索引内存分析

普通索引后的结果和原Tensor的内存共享

print(a[a>1])
import copy
b = copy.deepcopy(a)
a[a>1]=10
print(a,b)
 3.3845e+15
 3.3846e+15
 3.3845e+15
 3.3845e+15
 3.3418e+15
 3.3845e+15
 3.3846e+15
 1.5035e+38
[torch.FloatTensor of size 8]

 10.0000   0.0000  10.0000   0.0000  10.0000
  0.0000  10.0000   0.0000  10.0000   0.0000
 10.0000   0.0000  10.0000   0.0000   0.0000
  0.0000  10.0000   0.0000   0.0000   0.0000
[torch.FloatTensor of size 4x5]

 3.3845e+15  0.0000e+00  3.3846e+15  0.0000e+00  3.3845e+15
 0.0000e+00  3.3845e+15  0.0000e+00  3.3418e+15  0.0000e+00
 3.3845e+15  0.0000e+00  3.3846e+15  0.0000e+00  0.0000e+00
 0.0000e+00  1.5035e+38  8.5479e-43  1.5134e-43  1.2612e-41
[torch.FloatTensor of size 4x5]
array([[  1.00000000e+01,   0.00000000e+00,   1.00000000e+01,
          0.00000000e+00,   1.00000000e+01],
       [  0.00000000e+00,   1.00000000e+01,   0.00000000e+00,
          1.00000000e+01,   0.00000000e+00],
       [  1.00000000e+01,   0.00000000e+00,   1.00000000e+01,
          0.00000000e+00,   0.00000000e+00],
       [  0.00000000e+00,   1.00000000e+01,   8.54792063e-43,
          1.51340234e-43,   1.26116862e-41]], dtype=float32)

索引函数gather介绍

方的介绍:

如果input是一个n维的tensor,size为
(x0,x1…,xi?1,xi,xi+1,…,xn?1),dim为i,然后index必须也为n维tensor,size为
(x0,x1,…,xi?1,y,xi+1,…,xn?1),其中y >= 1,最后输出的out与index的size是一样的。

意思就是按照一个指定的轴(维数)收集值

对于一个三维向量来说:

out[i][j][k] = input[index[i][j][k]][j][k]  # if dim == 0
out[i][j][k] = input[i][index[i][j][k]][k]  # if dim == 1
out[i][j][k] = input[i][j][index[i][j][k]]  # if dim == 2

参数:

input (Tensor) – 源tensor

dim (int) – 指定的轴数(维数)

index (LongTensor) – 需要聚集起来的数据的索引

out (Tensor, optional) – 目标tensor

简单来说,就是在Tensor(input)的众多维度中针对某一维度(dim参数),使用一维Tensor(index)进行索引,并对其他维度进行遍历。

a = t.arange(16).view(4,4)
index = t.LongTensor([[0,1,2,3]])
print(a)
print(index)
print(a.gather(0,index))

# 逆操作scatter_,注意是inplace的
b = t.zeros(4,4)
b.scatter_(0,index,a.gather(0,index))
print(b)
  0   1   2   3
  4   5   6   7
  8   9  10  11
 12  13  14  15
[torch.FloatTensor of size 4x4]

 0  1  2  3
[torch.LongTensor of size 1x4]

  0   5  10  15
[torch.FloatTensor of size 1x4]

  0   0   0   0
  0   5   0   0
  0   0  10   0
  0   0   0  15
[torch.FloatTensor of size 4x4]

二、高阶索引

和普通索引不同,高阶索引前后一般不会共享内存,后面介绍Tensor内存结构时会提到。

x = t.arange(0,27).view(3,3,3)
print(x)
print(x[[1,2],[1,2],[2,0]])  # x[1,1,2]和x[2,2,0]
print(x[[2,1,0],[0],[0]])  # x[2,0,0]和x[1,0,0]和x[0,0,0]
(0 ,.,.) =
   0   1   2
   3   4   5
   6   7   8

(1 ,.,.) =
   9  10  11
  12  13  14
  15  16  17

(2 ,.,.) =
  18  19  20
  21  22  23
  24  25  26
[torch.FloatTensor of size 3x3x3]

 14
 24
[torch.FloatTensor of size 2]

 18
  9
  0
[torch.FloatTensor of size 3]

原文地址:https://www.cnblogs.com/hellcat/p/8445250.html

时间: 2024-10-04 15:17:02

『PyTorch』第五弹_深入理解Tensor对象_中上:索引的相关文章

『PyTorch』第五弹_深入理解autograd_下:Variable梯度探究

查看非叶节点梯度的两种方法 在反向传播过程中非叶子节点的导数计算完之后即被清空.若想查看这些变量的梯度,有两种方法: 使用autograd.grad函数 使用hook autograd.grad和hook方法都是很强大的工具,更详细的用法参考官方api文档,这里举例说明基础的使用.推荐使用hook方法,但是在实际使用中应尽量避免修改grad的值. 求z对y的导数 x = V(t.ones(3)) w = V(t.rand(3),requires_grad=True) y = w.mul(x) z

『PyTorch』第五弹_深入理解autograd_下:函数扩展&高阶导数

一.封装新的PyTorch函数 继承Function类 forward:输入Variable->中间计算Tensor->输出Variable backward:均使用Variable 线性映射 from torch.autograd import Function class MultiplyAdd(Function): # <----- 类需要继承Function类 @staticmethod # <-----forward和backward都是静态方法 def forward(

『PyTorch』第五弹_深入理解Tensor对象_中下:数学计算以及numpy比较

一.简单数学操作 1.逐元素操作 t.clamp(a,min=2,max=4)近似于tf.clip_by_value(A, min, max),修剪值域. a = t.arange(0,6).view(2,3) print("a:",a) print("t.cos(a):",t.cos(a)) print("a % 3:",a % 3) # t.fmod(a, 3) print("a ** 2:",a ** 2) # t.po

『PyTorch』第五弹_深入理解Tensor对象_下:从内存看Tensor

Tensor存储结构如下, 如图所示,实际上很可能多个信息区对应于同一个存储区,也就是上一节我们说到的,初始化或者普通索引时经常会有这种情况. 一.几种共享内存的情况 view a = t.arange(0,6) print(a.storage()) b = a.view(2,3) print(b.storage()) print(id(a.storage())==id(b.storage())) a[1] = 10 print(b) 上面代码,我们通过.storage()可以查询到Tensor

『PyTorch』第五弹_深入理解autograd_上:Variable

一.Variable类源码简介 class Variable(_C._VariableBase): """ Attributes: data: 任意类型的封装好的张量. grad: 保存与data类型和位置相匹配的梯度,此属性难以分配并且不能重新分配. requires_grad: 标记变量是否已经由一个需要调用到此变量的子图创建的bool值.只能在叶子变量上进行修改. volatile: 标记变量是否能在推理模式下应用(如不保存历史记录)的bool值.只能在叶变量上更改.

『PyTorch』第四弹_通过LeNet初识pytorch神经网络_下

『PyTorch』第四弹_通过LeNet初识pytorch神经网络_上 # Author : Hellcat # Time : 2018/2/11 import torch as t import torch.nn as nn import torch.nn.functional as F class LeNet(nn.Module): def __init__(self): super(LeNet,self).__init__() self.conv1 = nn.Conv2d(3, 6, 5)

『PyTorch』第十弹_循环神经网络

『cs231n』作业3问题1选讲_通过代码理解RNN&图像标注训练 对于torch中的RNN相关类,有原始和原始Cell之分,其中RNN和RNNCell层的区别在于前者一次能够处理整个序列,而后者一次只处理序列中一个时间点的数据,前者封装更完备更易于使用,后者更具灵活性.实际上RNN层的一种后端实现方式就是调用RNNCell来实现的. 一.nn.RNN import torch as t from torch import nn from torch.autograd import Variab

『PyTorch』第六弹_最小二乘法的不同实现手段(待续)

PyTorch的Variable import torch as t from torch.autograd import Variable as V import matplotlib.pyplot as plt from IPython import display # 指定随机数种子 t.manual_seed(1000) def get_fake_data(batch_size=8): x = t.rand(batch_size,1)*20 y = x * 2 + 3 + 3*t.ran

『PyTorch』第三弹_自动求导

torch.autograd 包提供Tensor所有操作的自动求导方法. 数据结构介绍 autograd.Variable 这是这个包中最核心的类. 它包装了一个Tensor,并且几乎支持所有的定义在其上的操作.一旦完成了你的运算,你可以调用 .backward()来自动计算出所有的梯度,Variable有三个属性: 访问原始的tensor使用属性.data: 关于这一Variable的梯度则集中于 .grad: .creator反映了创建者,标识了是否由用户使用.Variable直接创建(No