PyTorch学习笔记

Pytorch: 人工智能开发库

文章目录

      • 初识张量
        • 张量的数学定义
        • Pytorch里的张量
      • torch.Tensor实例
        • 构造含有特定数据的张量
        • 构造特定大小的张量
        • 构造等比数列和等差数列
        • 构造随机张量
      • 组织张量的元素
        • 重排张量元素
        • 选取部分张量
        • 张量的扩展与拼接

初识张量

张量的数学定义

张量可看作是多维数组。维度(dimension),大小(size),元素个数是张量的属性。
标量可看作是零维张量,向量可看作是一维张量,矩阵可看作是二维张量

Pytorch里的张量

pythoch里面的张量是运算的基本数据类型,用类torch.Tensor实现。

    import torch
    
    t2 = torch.tensor( [[0, 1, 2], [3, 4, 5]])
    print(t2)
    print('数据 = {}'.format(t2))
    print(t2.reshape(3, 2))         # 重新组织元素
    print(t2 + 1)                   # 逐元素计算

另外类torch.Tensor类实例成员,可以获取张量大小,维度,和元素个数的方法。

  • 成员size(): 返回张量的大小
  • 成员dim() : 返回张量的维数
  • 成员numel() : 张量中元素的个数
print( '数据 = {}'.format(t2))
print( '大小 = {}'.format(t2.size()))
print( '维度 = {}'.format(t2.dim()))
print( '元素个数 = {}'.format(t2.numel()))
print( '元素类型 = {}'.format(t2.dtype))
数据 = tensor([[0, 1, 2],
        [3, 4, 5]])
大小 = torch.Size([2, 3])
维度 = 2
元素个数 = 6
元素类型 = torch.int64

每个张量类实例还会有元素类型(dtype).
pytorch提供了以下几种数据类型

浮点类型 特点
torch.float16 浮点类型
torch.float32 浮点类型
torch.float64 浮点类型

其中位数越大精度越高,通常使用torch.float32

整数类型 特点
torch.unit8 逻辑类型(即‘是’或‘否’)
torch.int8 有符号整数类型
torch.int16 有符号整数类型
torch.int32 有符号整数类型
torch.int64 有符号整数类型

常用的是torch.int64.构建张量时,如果列表为整数类型则张量类型默认为torch.int64型。如果列表为浮点类型则张量类型默认为torch.float32型。

torch.Tensor实例

构造含有特定数据的张量

使用torch.tensor()构造含有特定数据的张量。

t0 = torch.tensor(0)
t1 = torch.tensor([0., 1., 2.,])
t2 = torch.tensor([[0., 1., 2.,],[3., 4., 5.,]])
t3 = torch.tensor([[[0., 1., 2.,],[3., 4., 5.,],[6., 7., 8.,]],[[9., 10., 11.,],[12., 13., 14.,],[15., 16., 17.,]]])
print( '元素类型 = {}'.format(t3.dtype))

使用torch.tensor()也可构造出不同类型的张量。

t_int8 = torch.tensor([1, 2], dtype=torch.int8)
t_float16 = torch.tensor([1, 2], dtype=torch.float16)

构造特定大小的张量

使用 torch.zeros(),torch.zeros_like(),torch.ones(),torch.ones_like(),torch.full(),torch.full_like(),torch.empty(),torch.empty_like(),**torch.eye()**这些函数构造给定大小的张量。

t1 = torch.empty(2)     # 未初始化 一维张量,大小为2
t2 = torch.zeros(2, 2)  # 各元素值为0,二维张量,大小为2x2
t3 = torch.ones(2, 2, 2)# 各元素值为1,三维张量,大小为2x2x2
t4 = torch.full((2, 2, 2), 3.) # 各元素值为3,四维张量,大小为2x2x2x2

构造等比数列和等差数列

使用torch.arange(start, stop, step)torch。linspace(start, stop, steps) 构建等差数列,使用 torch.logspace(start , stop, steps) 构造等比数列。

print(torch.arange(0, 4, step=1))
print(torch.linspace(0, 3, steps=4))
print(torch.logspace(0, 3, steps=4))
tensor([0, 1, 2, 3])
tensor([0., 1., 2., 3.])
tensor([   1.,   10.,  100., 1000.])

构造随机张量

随机样本是根据概率分布生成的。概率分布可以分为离散概率分布和连续概率分布。离散概率分布得到的样本一般是0,1这样的整数值,由连续概率分布得到的样本一般是浮点数。

  • 离散随机张量的构造
    • torch.bernoulli(概率张量)
    • torch.multinomial()
    • torch.randperm(n) 随机生成一个0~n-1的排列
    • torch.randint(low, high, size)
  • 连续随机样本的生成
    • torch.rand() 传入生成张量的大小 (标准均匀分布)
    • torch.rand_like()
    • torch.randn() (标准正态分布)
    • torch.randn_like()
    • torch.normal(mean, std)(标准正态分布)可指定分布的均值和方差。

组织张量的元素

重排张量元素

torch.Tensor类两类成员方法

  1. reshape(),squeeze(), unsqueeze() :不会改变元素的实际位置。
  2. permute(),transpose() 和t(): 可能会改变元素实际位置
    第一类方法:在reshape参数中一个维度的大小可以用-1代替,如果某个维度的大小用-1代替,那么该函数会根据元素个数和其他维度的参数自动计算这个维度的大小,所以参数中最多只能有一个维度的大小可以用-1代替。squeeze函数是消除张量中维度大小为1的维度。unsqueeze函数则相反,根据传入参数的大小,在指定位置增加大小为零的维度。
tc = torch.arange(12)  # 张量大小(12,)
print('tc = {}'.format(tc)) 
t322 = tc.reshape(3, 2, 2)  # 张量大小(3, 2 ,2)
print('t322 = {}'.format(t322))
t43 = t322.reshape(4, 3) # 张量大小(4, 3)
print('t43 = {}'.format(t43))
t = torch.arange(24).reshape(2, 1, 3, 1, 4)   # 大小 = (2, 1, 3, 1, 4)
t.squeeze()   # 大小 = (2,3, 4)
t = torch.arange(24).reshape(2, 3, 4)  # 大小 = (2, 3, 4)
t.unsqueeze(dim=2)   # 大小 = (2, 3, 1, 4)
tc = tensor([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
t322 = tensor([[[ 0,  1],
         [ 2,  3]],

        [[ 4,  5],
         [ 6,  7]],

        [[ 8,  9],
         [10, 11]]])
t43 = tensor([[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8],
        [ 9, 10, 11]])
        tensor([[[ 0,  1,  2,  3],
         [ 4,  5,  6,  7],
         [ 8,  9, 10, 11]],

        [[12, 13, 14, 15],
         [16, 17, 18, 19],
         [20, 21, 22, 23]]])
         tensor([[[[ 0,  1,  2,  3]],

         [[ 4,  5,  6,  7]],

         [[ 8,  9, 10, 11]]],


        [[[12, 13, 14, 15]],

         [[16, 17, 18, 19]],

         [[20, 21, 22, 23]]]])

第二类方法是:permute()张量的交换,张量的交换可以将两个位置的维度大小互换。
另外转置函数也可以进行张量的互换。作用和矩阵转置一样。

t = torch.arange(24).reshape(1, 2, 3, 4) # 大小 = (1, 2, 3, 4)
t.permute(dims = [2, 0, 1, 3])  # 大小 = (3, 1, 2, 4)

选取部分张量

很多时候我们只想对部分元素进行操作,不想对张量中的所有元素进行操作。那么pytorch也提供了相应的方法index_select(dim, index(张量类型),masked_select(张量(由0和1组成,大小和待选取张量一致,选取元素为1位置的对应元素),take(张量)take函数将张量中每个元素给唯一的索引进行寻找。参数张量的值就是带寻找的位置。
除了类成员方法以外,我们还可以使用’[]’,选取元素。和数组切片类似,选取方法如下:

t = torch.arange(12)
print('t = {}'.format(t))
print(t[3])   # 选取1个元素,大小(),值为3
print(t[-5])  # 选取1个元素,大小(),值为7
print(t[3:6]) # 选取3个元素,大小(3,)
print(t[:6])  # 选取连续元素,大小(6,)
print(t[3:])  # 选取连续元素,大小(9,)
print(t[-5:]) # 选取连续元素,大小(5,)
print(t[3:6:2]) # 选取不连续元素,大小(2,)
print(t[3::2]) # 选取不连续元素,大小(5,)
t = tensor([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
tensor(3)
tensor(7)
tensor([3, 4, 5])
tensor([0, 1, 2, 3, 4, 5])
tensor([ 3,  4,  5,  6,  7,  8,  9, 10, 11])
tensor([ 7,  8,  9, 10, 11])
tensor([3, 5])
tensor([ 3,  5,  7,  9, 11])

张量的扩展与拼接

有时我们需要将多个张量。扩展或者凭借。pytorch为我们提供了相应的类成员方法repeat(),和函数torch.repeat(),torch.cat()
repeat(): 根据参数扩展张量对应的的参数倍,多余的元素是原来张量元素的重复。

# 使用repeat()函数扩大张量
t12 = torch.tensor([[5., -9.], ])  
print('t12 = {}'.format(t12))
t34 = t12.repeat(3, 2)
print('t34 = {}'.format(t34))
t12 = tensor([[ 5., -9.]])
t34 = tensor([[ 5., -9.,  5., -9.],
        [ 5., -9.,  5., -9.],
        [ 5., -9.,  5., -9.]])

torch.cat():可以将多个张量拼接成一个张量,该函数有两个参数,第一个参数的是张量的列表或是元组,这个函数就是把参数或者元组里面的所有张量拼接起来,第二个参数d指示要将这些张量在哪个维度拼接起来。需要注意的是,如果需要进行拼接的话,被拼接的张量需要满足下面几个条件:

  • 所有张量的维度都要完全相同,并且大于第二个参数d
  • 所有张量除了在第d维的张量大小不同外,其他的维度,所有张量维度大小都要一样。拼接后第d维的大小是各张量第d维大小之和。
# 使用torch.cat()函数拼接多个张量
tp = torch.arange(12).reshape(3, 4)
tn = -tp
tc0 = torch.cat([tp, tn],0)
print('tc0 = {}'.format(tc0))
tc1 = torch.cat([tp, tp, tn, tn], 1)
print('tc1 = {}'.format(tc1))
tc0 = tensor([[  0,   1,   2,   3],
        [  4,   5,   6,   7],
        [  8,   9,  10,  11],
        [  0,  -1,  -2,  -3],
        [ -4,  -5,  -6,  -7],
        [ -8,  -9, -10, -11]])
tc1 = tensor([[  0,   1,   2,   3,   0,   1,   2,   3,   0,  -1,  -2,  -3,   0,  -1,
          -2,  -3],
        [  4,   5,   6,   7,   4,   5,   6,   7,  -4,  -5,  -6,  -7,  -4,  -5,
          -6,  -7],
        [  8,   9,  10,  11,   8,   9,  10,  11,  -8,  -9, -10, -11,  -8,  -9,
         -10, -11]])

张量还可以进行运算,运算法则和python运算法则类似,值得注意的是张量之间可以点乘

  • 一维张量和一维张量点积使用torch.dot()
  • 二维张量和一维张量点积使用torch.mv()
  • 二维张量和二维张量点积使用torch.mm()
    最后我们举个例子综合演示pytorch的科学计算。我们将使用pytorch,用蒙特卡洛算法计算圆周率Π的值,算法如下:
import torch
num_sample = 10000000
sample = torch.rand(num_sample, 2)
dist = sample.norm(p=2, dim=1)
ratio = (dist < 1).float().mean()
pi = ratio * 4
print('pi = {}'.format(pi))
pi = 3.141401529312134

目前就写到这里啦,很多东西学了,但是没有实践。自己也不知道为什么pytorch要这样设置,这样做的好处是什么?这些东西,以后再改吧。那就这样吧,告辞!
在这里插入图片描述
在这里插入图片描述

你可能感兴趣的:(python学习笔记)