PyTorch系列1 ---Tensor和Variable

参考:

  • torch.Tensor

torch.Tensor是一种包含单一数据的多维矩阵。
Torch定义了七种CPU张量和八种GPU张量类型:
PyTorch系列1 ---Tensor和Variable_第1张图片图片转自https://ptorch.com/docs/8/torch-tensor
torch.Tensor是默认的tensor类型(torch.FloatTensor)的简称。

# torch.Tensor   https://ptorch.com/docs/8/torch-tensor
#张量可以从Python的list或者序列构成
t1 = torch.FloatTensor([[1,2,3],[4,5,6]])
print("torch.FloatTensor([[1,2,3],[4,5,6]]): \n",t1)
#可以通过指定它的大小来构建一个空的张量
t2 = torch.IntTensor(2,4).zero_()
print("torch.FloatTensor([[1,2,3],[4,5,6]]): \n",t2)

运行结果:
PyTorch系列1 ---Tensor和Variable_第2张图片

#可以使用Python的索引和切片符号来访问和修改张量的内容:
x = torch.FloatTensor([[1,2,3],[4,5,6]])
print("x: \n",x)
x[0][1] = 8
print("x[0][1] = 8:\n",x)

运行结果:
PyTorch系列1 ---Tensor和Variable_第3张图片

#element_size()  ---> int 返回单个元素的字节大小。
y1 = torch.FloatTensor().element_size()
print("torch.FloatTensor().element_size():\n",y1)
y2 = torch.FloatTensor(3,4).element_size()
print("torch.FloatTensor(3,4).element_size():\n",y2)
y3 = torch.ByteTensor().element_size()
print("torch.ByteTensor().element_size():\n",y3)

运行结果:
PyTorch系列1 ---Tensor和Variable_第4张图片

### expand(*sizes) 返回tensor的一个新视图,,单个维度扩大为更大的尺寸。tensor也可以扩大为更高维,新增加的维度将附在前面。
# 扩大tensor不需要分配新内存,,只是仅仅新建一个tensor的视图,其中通过将stride设为0,一维将会扩展为更高维。任何一个一维的在不分配新内存情况下可扩展为任意的数值。
# 参数 sizes(torch.Size or int...)---需要扩展的大小
x = torch.Tensor([[1],[2],[3]])
print("x = torch.Tensor([[1],[2],[3]]):\n",x.size())
print("x.expand(3,4):\n",x.expand(3,4))

运行结果:
PyTorch系列1 ---Tensor和Variable_第5张图片

### expand_as(tensor)  将tensor扩展为参数tensor的大小。该操作等效于:self.expand(tensor.size())
z1 = torch.Tensor([[1],[2],[3]])
z2 = torch.Tensor([[1,2,3,4],[2,3,4,5],[3,4,5,6]])
z3 = z1.expand_as(z2) #此时z1并没有任何变化,,而是生成了一个新向量z3
print("z1 = torch.Tensor([[1],[2],[3]]):\n",z1)
print("z2 = torch.Tensor([[1,2,3,4],[2,3,4,5],[3,4,5,6]]):\n",z2)
print("z3 = z1.expand_as(z2):\n",z3)

运行结果:
PyTorch系列1 ---Tensor和Variable_第6张图片

### index(m)  用一个二进制的掩码或者沿着一个给定的维度 从tensor中选取元素。。tensor.index(m)与 tensor[m] 完全相同
# 参数 m(int or Byte Tensor or slice)------用来选取元素的维度或者掩码
## index_add_(dim, index, tensor) 按索引求和。按参数index中的索引数确定的顺序,,将参数tensor中的元素加到原来的tensor中。。参数tensor的尺寸必须严格地与原tensor匹配,,否则会发生错误。
# 参数 dim(int)---索引index所指向的维度。。。。。。并未返回新向量,,原来的tensor被更新为加上参数tensor中指定的数值之后的结果
#      index(LongTensor)--- 需要从tensor中选取的指数。包含索引数的张量
#      tensor(Tensor)---含有相加元素的tensor
x = torch.Tensor([[1,1,1],[1,1,1],[1,1,1]])
t = torch.Tensor([[1,2,3],[4,5,6],[7,8,9]])
index = torch.LongTensor([0,1,2])
x.index_add_(0,index,t)
print("x.index_add_(0,index,t):\n",x)
x.index_add_(1,index,t)
print("x.index_add_(1,index,t):\n",x)
x.index_add_(-1,index,t)
print("x.index_add_(-1,index,t):\n",x)
x.index_add_(-2,index,t)
print("x.index_add_(-2,index,t):\n",x)

运行结果:
PyTorch系列1 ---Tensor和Variable_第7张图片

### index(m)  用一个二进制的掩码或者沿着一个给定的维度 从tensor中选取元素。。tensor.index(m)与 tensor[m] 完全相同
# 参数 m(int or Byte Tensor or slice)------用来选取元素的维度或者掩码
## indexadd(dim, index, tensor) 按索引求和。按参数index中的索引数确定的顺序,,将参数tensor中的元素加到原来的tensor中。。参数tensor的尺寸必须严格地与原tensor匹配,,否则会发生错误。
# 参数 dim(int)---索引index所指向的维度
#      index(LongTensor)--- 需要从tensor中选取的指数。包含索引数的张量
#      tensor(Tensor)---含有相加元素的tensor
x1 = torch.Tensor([[1,4,7],[2,5,8],[3,6,9]])
t1 = torch.Tensor([[1,2,3],[4,5,6],[7,8,9]])
index = torch.LongTensor([0,1,2])
x1.index_add_(0,index,t1)
print("x1.index_add_(0,index,t):\n",x1)
x2 = torch.Tensor([[1,1,1],[1,1,1],[1,1,1]])
t2 = torch.Tensor([[1,2,3],[4,5,6],[7,8,9]])
index = torch.LongTensor([0,1,2])
x2.index_add_(1,index,t2)
print("x2.index_add_(1,index,t):\n",x2)
x3 = torch.Tensor([[1,1,1],[1,1,1],[1,1,1]])
t3 = torch.Tensor([[1,2,3],[4,5,6],[7,8,9]])
index = torch.LongTensor([0,1,2])
x3.index_add_(-1,index,t3)
print("x3.index_add_(-1,index,t):\n",x3)
x4 = torch.Tensor([[1,1,1],[1,1,1],[1,1,1]])
t4 = torch.Tensor([[1,2,3],[4,5,6],[7,8,9]])
index = torch.LongTensor([0,1,2])
x4.index_add_(-2,index,t4)
print("x4.index_add_(-2,index,t):\n",x4)

运行结果:
PyTorch系列1 ---Tensor和Variable_第8张图片

###如何像使用Numpy一样使用PyTorch,了解PyTorch中的基本元素Tensor和Variable及其操作方式。
import torch
import numpy as np
import tensorflow as tf
##把PyTorch当NumPy用
#创建一个numpy ndarray
numpy_tensor = np.random.randn(10,20)
#下面的两种方法,会直接将Numpy ndarray 的数据类型转换为对应的PyTorch Tensor数据类型
pytorch_tensor1 = torch.Tensor(numpy_tensor) #torch.Tensor是默认的tensor类型(torch.FloatTensor)的简称。
# print("pytorch_tensor1: ",pytorch_tensor1)
pytorch_tensor2 = torch.from_numpy(numpy_tensor)
# print("pytorch_tensor2: ",pytorch_tensor2)

#也可以使用下面的方法将pytorch tensor 转换为 numpy ndarray
#注意,GPU上的Tensor不能直接转换为NumPy ndarray, 需要使用.cpu()先将GPU上的Tensor转到CPU上
numpy_array1 = pytorch_tensor1.numpy() #如果pytorch tensor在CPU上
# print("numpy_array1: ",numpy_array1)
numpy_array2 = pytorch_tensor1.cpu().numpy() #如果pytorch tensor 在GPU上
# print("numpy_array2: ",numpy_array2)

#PyTorch Tensor使用GPU加速
# 我们可以使用以下两种方式将Tensor放到GPU上
# 方式1:定义cuda的数据类型
dtype = torch.cuda.FloatTensor #定义默认 GPU 的 数据类型
gpu_tensor = torch.randn(10,20).type(dtype)
#方式2:更简单,推荐使用
# 注:使用方式1 将tensor 放到GPU上的时候会将数据类型转换成定义的数据类型;;使用方式2 能够直接将tensor 放到GPU上,类型跟之前保持一致
# 推荐在定义Tensor 时就明确数据类型,然后直接使用第二种方法将Tensor 放到GPU上
gpu_tensor1 = torch.randn(10,20).cuda(0)#将 tensor 放到第一个GPU上
# gpu_tensor2 = torch.randn(10,20).cuda(1)#将 tensor 放到第二个GPU上

## 将tensor 放回CPU的操作非常简单
cpu_tensor = gpu_tensor1.cpu()

### 我们也能够访问到Tensor的一些属性
# 通过下面两种方式得到tensor的大小
print("tensor的大小pytorch_tensor1.shape",pytorch_tensor1.shape) #torch.Size([10, 20])
print("tensor的大小pytorch_tensor1.size()",pytorch_tensor1.size()) #torch.Size([10, 20])
# 得到 tensor 的数据类型
print("tensor 的数据类型pytorch_tensor1.type():",pytorch_tensor1.type()) #torch.FloatTensor
#得到 tensor 的维度
print("tensor 的维度pytorch_tensor1.dim():",pytorch_tensor1.dim()) #2
#得到 tensor 的所有元素的个数
print("tensor 的所有元素的个数pytorch_tensor1.numel():",pytorch_tensor1.numel())#200

#小练习:查阅文档,了解tensor的数据类型,创建一个float64,大小是3 X 2 、 随机初始化的tensor,将其转化为numpy的ndarray,输出其数据类型
x = torch.randn(3,2)
x = x.type(torch.DoubleTensor)
x_array = x.numpy()
print("x_array.dtype:\n",x_array.dtype)

运行结果:
PyTorch系列1 ---Tensor和Variable_第9张图片

常见的张量数学运算

# 元素求和 torch.sum(input) -->  float    返回输入向量input中所有元素的和
# 参数: input(Tensor) ---输入张量
a = torch.randn(1,3)
print("a:  ",a)
print("Sum(a):  ",torch.sum(a))

运行结果:
在这里插入图片描述

## torch.sum(input,dim,keepdim,out=None)  -->  Tensor
# 返回新的张量,其中包括输入张量input中指定维度dim中每行的和
# 若keepdim值为True,则在输出张量中,除了被操作的dim的维度值降为1,,其它维度与输入张量input相同。否则,dim维度相当于被执行torch.squeeze()维度压缩操作,导致此维度消失,最终输出张量会比输入张量少一个维度。
# 参数:input(Tensor) -- 输入Tensor
#       dim(int) -- 指定维度
#       keepdim(bool) -- 输出张量是否保持与输入张量有相同数量的维度
#       out(Tensor,optional) -- 结果张量
a = torch.rand(4,5)
print("a:  ",a)
print("torch.sum(a,1,True):  ",torch.sum(a,1,True))
print("torch.sum(a,1,False):  ",torch.sum(a,1,False))
print("torch.sum(a,0,True):  ",torch.sum(a,0,True))
print("torch.sum(a,0,False):  ",torch.sum(a,0,False))
print("torch.sum(a,-1,True):  ",torch.sum(a,-1,True))
print("torch.sum(a,-2,True):  ",torch.sum(a,-2,True))

运行结果:
PyTorch系列1 ---Tensor和Variable_第10张图片
参考:

  • Pytorch中tensor常用语法
  • PyTorch 常用方法总结1:生成随机数Tensor的方法汇总(标准分布、正态分布……)

你可能感兴趣的:(PyTorch)