测试环境版本:
torch1.7.1 + CPU

python 3.6

Tensor是pytorch中的“张量”,可以看作是类似numpy的矩阵
本文介绍如何创建与调整Tensor

参考书目: 《深度学习框架pytorch: 入门与实践》陈云著

首先引用torch:

import torch as t

1、创建tensor

1)使用Tensor函数创建tensor

# 1 指定形状
a = t.Tensor(2,3)
a # 数值取决于内存空间的状态
tensor([[0., 0., 0.],
        [0., 0., 0.]])

2) torch.tensor()创建Tensor

本部分内容来自于pytorch官方文档:torch.tensor()

注意与torch.Tensor相区分,后者为构造函数。

torch.tensor(data, *, dtype=None, device=None, requires_grad=False, pin_memory=False) → Tensor
参数说明:

  • data (类似数组的数据) – 该数据用于对Tensor进行初始化. 可以是list(列表), tuple(元组), NumPy ndarray(numpy多维数组), scalar(标量), 以及其他很多类型的数据
  • dtype (生成的张量类型) 若该参数缺省,则与data的类型保持一致。
  • device 标识张量在哪种CPU/CUDA设备上运算的标识
  • requires_grad (bool类型) – 若为True,张量会记录其进行的操作。
import torch as t

arr1 = [1.0,2.0]
a = t.tensor(arr1,requires_grad=True)

note: 这里的arr1必须是浮点数,否则会报错。(想想为什么?)

print(a)
arr1[0] = 2
print(a)
tensor([1., 2.], requires_grad=True)
tensor([1., 2.], requires_grad=True)

torch.tensor()创建的张量时为深度拷贝,与原对象不共用内存。

复杂的参数可以这样写:

t.tensor([[ 0.1111, 0.2222, 0.3333]], dtype=torch.float64, device=‘cuda:0’)

2)用list列表为参数创建

b = t.Tensor([[1,2],[3,4]])
b
tensor([[1., 2.],
        [3., 4.]])

`tensor也可以转化为list

ls = b.tolist()
ls
[[1.0, 2.0], [3.0, 4.0]]

3)用torch.size为参数

首先torch.Size是Tensor的参数

b_size = b.size()
b
tensor([[1., 2.],
        [3., 4.]])
b_size
torch.Size([2, 2])
type(b_size)
torch.Size
c = t.Tensor(b_size)
c
tensor([[ 4.0000e+00,  0.0000e+00],
        [-1.2593e+13,  4.5911e-41]])

Tensor.shape等价于Tensor.size()

c.shape
torch.Size([2, 2])

需要注意:使用Tensor(*sizes)创建Tensor时系统仅会检查剩余空间是否够用,但不会真的分配空间
只有创建的tensor被使用时才分配空间

2、其他常用创建方法

1)只含1的tensor

t.ones(2,3)
tensor([[1., 1., 1.],
        [1., 1., 1.]])

2)只含0的tensor

t.zeros(2,3)
tensor([[0., 0., 0.],
        [0., 0., 0.]])

3) 递增数列

t.arange(0,10,2)
tensor([0, 2, 4, 6, 8])
t.linspace(0,15,3) # 0到15均匀分割成3份
tensor([ 0.0000,  7.5000, 15.0000])
t.linspace(20,-5,5)
tensor([20.0000, 13.7500,  7.5000,  1.2500, -5.0000])

4) 均匀分布随机数

t.rand(2,3,4)
tensor([[[0.0350, 0.1746, 0.5931, 0.9241],
         [0.1791, 0.2205, 0.1145, 0.1942],
         [0.4908, 0.3410, 0.2910, 0.5894]],

        [[0.3705, 0.1012, 0.6324, 0.6196],
         [0.3016, 0.7018, 0.1615, 0.2207],
         [0.4301, 0.2420, 0.2793, 0.2108]]])

5) 正态分布随机数

t.randn(2,3)
tensor([[ 0.1970,  0.7628,  1.0303],
        [ 0.6061, -2.3474, -0.1140]])

6)随机排列

t.randperm(10)
tensor([0, 9, 6, 8, 1, 4, 3, 7, 5, 2])

7) 对角线为1的矩阵

t.eye(3,4)
tensor([[1., 0., 0., 0.],
        [0., 1., 0., 0.],
        [0., 0., 1., 0.]])

不要求为方阵

2、调整tensor形状

1) tensor.view

tensor.view可以修改tensor的形状,但是

  • 新tensor与原tensor共享内存
  • 新tensor与原tensor必须保证元素个数相同
a = t.ones(2,3)
b = a.view(1,6)
print("a为:")
print(a)
print("b为:")
print(b)
a为:
tensor([[1., 1., 1.],
        [1., 1., 1.]])
b为:
tensor([[1., 1., 1., 1., 1., 1.]])

由共享内存可知,一个tensor的改变也会改变另一个tensor

a[0][0] = 0
b
tensor([[0., 1., 1., 1., 1., 1.]])

2)tensor.squeeze() 删除维度

将元素个数为1的维度删去

object.squeeze()以及t.squeeze()会将长度为1的维度抹去(或者称为“降维?”)

c = t.randn(1,3,4,1)
c.shape
torch.Size([1, 3, 4, 1])
d = c.squeeze()
d.shape
torch.Size([3, 4])
d = t.squeeze(c)
print("原矩阵形状")
print(c.shape)
print("压缩后形状")
print(d.shape)
原矩阵形状
torch.Size([1, 3, 4, 1])
压缩后形状
torch.Size([3, 4])

object.squeeze(n)会将第n维删去
但如果第n维不止一个元素操作无效

print("删去第2维:")
print(c.squeeze(2).shape)
print("删去第3维:")
print(c.squeeze(3).shape)
删去第2维:
torch.Size([1, 3, 4, 1])
删去第3维:
torch.Size([1, 3, 4])

3)tensor.unsqueeze()

object.squeeze(n)在第n维上插入一个
这里的n不可省略

print("原矩阵形状:")
c.shape
原矩阵形状:





torch.Size([1, 3, 4, 1])
print("增加第1维:")
c.unsqueeze(1).shape
增加第1维:





torch.Size([1, 1, 3, 4, 1])
print("原矩阵形状:")
c.shape
原矩阵形状:





torch.Size([1, 3, 4, 1])
print("增加第2维:")
c.unsqueeze(2).shape
增加第2维:





torch.Size([1, 3, 1, 4, 1])
c = t.Tensor([[[2]]])

squeeze()与unsqueeze()后的对象与原对象共享内存

d = c.squeeze()
e = c.unsqueeze(2)
c[0][0][0] = 1
print(d)
print(e)
tensor(1.)
tensor([[[[1.]]]])

4) tensor.resize()

c = t.arange(1,10)
c
tensor([1, 2, 3, 4, 5, 6, 7, 8, 9])

数据量不变的话,和view没有什么区别
resize()会有弃用提醒,所以这里使用resize_()

c.resize_(3,3)
tensor([[0, 2, 3],
        [4, 5, 6],
        [7, 8, 9]])

如果元素个数改变,填充和删除都是按“Z”字形

c.resize_(2,2)
tensor([[0, 2],
        [3, 4]])
c.resize_(4,4)
tensor([[                0,                 2,                 3,
                         4],
        [                5,                 6,                 7,
                         8],
        [                9, 32651548277538908, 27303553780220005,
         28992339220037731],
        [32651492442964069, 29273822787141743, 29555280582738012,
         26740621010600046]])