测试环境版本:
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]])