深度学习PyTorch笔记(1):创建Tensor

这是《动手学深度学习》(PyTorch版)(Dive-into-DL-PyTorch)的学习笔记,里面有一些代码是我自己拓展的。

其他笔记在专栏 深度学习 中。

1. Tensor预备知识

1.1 创建Tensor

Tensor即张量,更适合深度学习,可以看作一个多维数组。

标量:0维张量
向量:1维张量
矩阵:2维张量

1.1.1 创建未初始化的Tensor

import torch
x = torch.empty(5, 3)  #创建一个5行3列未初始化的Tensor
print(x)
tensor([[5.2839e-11, 1.8617e+25, 1.1835e+22],
        [4.3066e+21, 7.3867e+20, 2.0027e-19],
        [1.7179e+19, 7.3471e+28, 1.4609e-19],
        [1.1578e+27, 1.1362e+30, 7.1547e+22],
        [4.5828e+30, 9.2516e+18, 7.3471e+28]])
a = torch.IntTensor(2, 3)
b = torch.FloatTensor(2, 3)

print(a)
print(b)
tensor([[ 926428514,  908931682,  808608560],
       [1630889059,  778254384, 1667594341]], dtype=torch.int32)
tensor([[1.0978e-05, 2.5808e-06, 6.4897e-10],
       [2.0913e+20, 5.1664e-11, 7.1450e+31]])

1.1.2 生成随机数

(1)均匀分布
torch.rand(sizes):返回从区间 [0, 1)的均匀分布中抽取的一组随机数;
torch.randint(low=0, high, size, out=None, dtype=None):返回在[low , high)之间均匀生成的随机整数填充的张量,张量的形状由变量的参数大小来定义;
torch.randint_like(input, low=0, high, dtype=None):返回与张量输入相同形状的张量,该张量由在 [low , high) 之间均匀生成的随机整数填充。

print(torch.rand(2, 3))  
x = torch.randint(1, 10, (2, 3))
print(x)
print(torch.randint_like(x, 11, 20))
#注意只有第一个是小数
tensor([[0.8216, 0.4305, 0.4622],
        [0.7264, 0.9784, 0.4676]])
tensor([[2, 3, 3],
        [1, 3, 2]])
tensor([[15, 13, 12],
        [18, 15, 15]])

(2)标准正态分布
torch.randn(siezs):返回从标准正态分布(均值为0,方差为1,即高斯白噪声) 中抽取的一组随机数;
torch.randn_like(input, *, dtype=None):返回与输入相同大小的张量,该张量由均值为0和方差为1的正态分布中的随机数填充。

x = torch.randn(2, 3)
print(x)
print(torch.randn_like(x))
tensor([[-0.2055, -0.7607,  2.1332],
        [ 0.0305,  0.5232, -0.8515]])
tensor([[ 1.7027, -0.6385, -0.8616],
        [-0.5147, -0.0495, -0.4854]])

(3)随机排列
torch.randperm(n):返回一个从 0 到 n-1 的随机整数排列,不包含上边界。

print(torch.randperm(6)) 
tensor([3, 2, 4, 0, 1, 5])

(4)线性间距向量
torch.linespace(s,e,steps):从s到e(左闭右闭,类似[s,e]),均匀切成steps份。

#torch.linspace(s,e,steps):从s到e(左闭右闭,类似[s,e]),均匀切成steps份
print(torch.linspace(1, 9, 2))
print(torch.linspace(1, 9, 2).type())  #类型是浮点型
print(torch.linspace(1, 9, 3))
print(torch.linspace(1, 9, 4))
print(torch.linspace(1, 9, 5))
print(torch.linspace(1, 9, 6))
tensor([1., 9.])
torch.FloatTensor
tensor([1., 5., 9.])
tensor([1.0000, 3.6667, 6.3333, 9.0000])
tensor([1., 3., 5., 7., 9.])
tensor([1.0000, 2.6000, 4.2000, 5.8000, 7.4000, 9.0000])

(5)泊松分布
torch.poisson(input *, generator=None):返回与输入相同大小的张量,从泊松分布中取样的每个元素都具有相应元素在输入中给定的速率参数。

#泊松分布:返回与输入相同大小的张量,从泊松分布中取样的每个元素都具有相应元素在输入中给定的速率参数
rates = torch.rand(3, 4) * 5  # rate parameter between 0 and 5
print(rates)
#rates为[0, 1)均匀分布的3×4矩阵,数值再×5,所以是在[0, 5)直接分布
print(torch.poisson(rates))
tensor([[3.4525, 3.6921, 2.9402, 4.2594],
        [2.1693, 1.0008, 1.7633, 2.1955],
        [0.3869, 0.8351, 2.7825, 3.6581]])
tensor([[2., 4., 2., 1.],
        [4., 2., 3., 1.],
        [1., 1., 4., 2.]])

1.1.3 torch.Tensor()与torch.tensor()

x = torch.Tensor(5, 3)  #这里是torch.Tensor(*size)
print(x)
tensor([[0.0000e+00, 0.0000e+00, 0.0000e+00],
        [0.0000e+00, 0.0000e+00, 0.0000e+00],
        [0.0000e+00, 0.0000e+00, 0.0000e+00],
        [0.0000e+00, 0.0000e+00, 0.0000e+00],
        [0.0000e+00, 0.0000e+00, 5.2591e-20]])
x = torch.tensor([[1,2,3], [4,5,6]])  #直接根据数值创建,这里是torch.Tensor(*data)
print(x)
print(x.type())  #注意不能用type(x),否则出来的只会是<class 'torch.Tensor'>
tensor([[1, 2, 3],
        [4, 5, 6]])
torch.LongTensor
x = torch.Tensor([[1,2,3], [4,5,6]])
print(x)
print(x.type())
tensor([[1., 2., 3.],
        [4., 5., 6.]])
torch.FloatTensor

注意 torch.Tensor()和torch.tensor() 之间的区别:

(1)torch.Tensor()是Python类,更明确的说,是默认张量类型torch.FloatTensor()的别名,上面会调用Tensor类的构造函数init,生成单精度浮点类型的张量

(2)torch.tensor()仅仅是Python的函数,函数原型是:

torch.tensor(data, dtype=None, device=None, requires_grad=False)

其中data可以是:list, tuple, NumPy ndarray, scalar和其他类型。
torch.tensor会从data中的数据部分做拷贝(而不是直接引用),根据原始数据类型生成相应的torch.LongTensor、torch.FloatTensor和torch.DoubleTensor。

1.1.4 一些特殊值矩阵

x = torch.zeros(5, 3)  #创建一个5行3列、值为0的Tensor
print(x)
tensor([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]])
x = torch.zeros(5, 3, dtype=torch.long)  #创建一个5行3列长整型、值为0的Tensor
print(x)
tensor([[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]])

dtype=torch.long表示创建的是长整型,同理,后面出现的dtype=torch.float就是类型改为浮点数
dtype=torch.double与后面的dtype=torch.float64相同

x = x.new_ones(5, 3, dtype=torch.float64)  
#通过现有的Tensor创建,此时返回的Tensor默认具有相同的数据类型,新的张量将会重用已有张量的属性(此处还没怎么弄懂)
print(x)
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]], dtype=torch.float64)
x = torch.zeros(5, 3, dtype=torch.double)  #上面的值为0的
print(x)
tensor([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]], dtype=torch.float64)
print(torch.ones(5, 3))  #全1
tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]])
print(torch.eye(5, 3))  #对角线为1
tensor([[1., 0., 0.],
        [0., 1., 0.],
        [0., 0., 1.],
        [0., 0., 0.],
        [0., 0., 0.]])
#torch.arange(s,e,step):从s到e(左闭右开,类似[s,e)),步长为step
print(torch.arange(1, 9))
print(torch.arange(1, 9).type())  #类型是长整型
print(torch.arange(1, 9, 2))
print(torch.arange(1, 10, 2))
tensor([1, 2, 3, 4, 5, 6, 7, 8])
torch.LongTensor
tensor([1, 3, 5, 7])
tensor([1, 3, 5, 7, 9])
#normal(mean,std):正态分布,(均值,标准差)
mean = torch.arange(1., 11.)
std = torch.arange(1, 0, -0.1)
x = torch.normal(mean, std)
print(mean)
print(std)
print(x)  #每一次编译,x的值都会发生变化
tensor([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])
tensor([1.0000, 0.9000, 0.8000, 0.7000, 0.6000, 0.5000, 0.4000, 0.3000, 0.2000,
        0.1000])
tensor([ 0.7446,  1.3406,  1.6261,  3.3972,  5.5543,  5.4342,  7.0130,  8.4505,
         9.1829, 10.0209])
#获取Tensor形状:
print(x.size())
print(x.shape)
print(x.numel())  #张量中元素的总数
torch.Size([10])
torch.Size([10])
10