• Pytorch_2.2_数据结构


    2.2 数据结构

    • torch.Tensor 是存储和变换数据的主要工具

    2.2.1 创建TENSOR

    首先导入PyTorch

    import torch
    

    创建一个5x3的未初始化的Tensor

    x = torch.empty(5,3)
    print(x)
    
    tensor([[9.2755e-39, 1.0561e-38, 1.0929e-38],
            [1.0102e-38, 9.7347e-39, 4.2246e-39],
            [1.0286e-38, 1.0653e-38, 1.0194e-38],
            [8.4490e-39, 1.0469e-38, 9.3674e-39],
            [9.9184e-39, 8.7245e-39, 9.2755e-39]])
    

    创建一个5x3的随机初始化Tencor

    x  = torch.rand(5,3)
    print(x)
    
    tensor([[0.8809, 0.5242, 0.8139],
            [0.1677, 0.4035, 0.3680],
            [0.4707, 0.9393, 0.5377],
            [0.7676, 0.7518, 0.4257],
            [0.7233, 0.4705, 0.3036]])
    

    创建一个全0的long型Tensor

    x = torch.zeros(5,3,dtype = torch.long)
    print(x)
    print(x[1][1])
    print(type(x[1][1]))
    
    tensor([[0, 0, 0],
            [0, 0, 0],
            [0, 0, 0],
            [0, 0, 0],
            [0, 0, 0]])
    tensor(0)
    <class 'torch.Tensor'>
    

    还可以根据数据直接创建Tensor

    x = torch.tensor([6.6,8])
    print(x)
    
    tensor([6.6000, 8.0000])
    

    通过现有的Tensor 来创建新的数据

    y =x.new_ones(5,3,dtype = torch.float64)
    print(y)
    z = torch.randn_like(y,dtype = torch.float)
    print(z)
    
    tensor([[1., 1., 1.],
            [1., 1., 1.],
            [1., 1., 1.],
            [1., 1., 1.],
            [1., 1., 1.]], dtype=torch.float64)
    tensor([[ 0.3913,  1.5179,  1.6415],
            [ 1.2150, -0.1650, -0.7815],
            [-0.2489,  0.5252, -1.2605],
            [ 0.5305,  0.1410, -0.6449],
            [-1.4771,  0.1270,  0.6471]])
    

    可以通过shape 或者 size() 来获取Tensor 的数据形状

    print(y.size())
    print(y.shape)
    # torch.size 的类型是 tuple
    
    torch.Size([5, 3])
    torch.Size([5, 3])
    
    函数 功能
    Tensor(*sizes) 基础构造函数
    tensor(data,) 类似np.array的构造函数
    ones(*sizes) 全1Tensor
    zeros(*sizes) 全0Tensor
    eye(*sizes) 对⻆线为1,其他为0
    arange(s,e,step) 从s到e,步⻓为step
    linspace(s,e,steps) 从s到e,均匀切分成steps份
    rand/randn(*sizes) 均匀/标准分布
    normal(mean,std)/uniform(from,to) 正态分布/均匀分布
    randperm(m) 随机排列

    2.2.2 操作

    算数操作

    • 加法 直接利用加号
    x  = torch.rand(5,3)
    y = torch.rand(5,3)
    print(x + y)
    
    tensor([[1.4692, 0.7374, 0.7234],
            [0.8925, 0.7805, 1.3061],
            [0.8631, 1.8786, 1.5237],
            [0.9812, 0.9703, 1.0981],
            [1.1590, 0.7849, 1.1890]])
    
    print(torch.add(x,y))
    
    tensor([[1.4692, 0.7374, 0.7234],
            [0.8925, 0.7805, 1.3061],
            [0.8631, 1.8786, 1.5237],
            [0.9812, 0.9703, 1.0981],
            [1.1590, 0.7849, 1.1890]])
    
    • 还可以指定输出
    result = torch.empty(5,3)
    torch.add(x,y,out = result)
    print(result)
    # 可以直接指定
    result = torch.add(x,y)
    print(result)
    
    tensor([[1.4692, 0.7374, 0.7234],
            [0.8925, 0.7805, 1.3061],
            [0.8631, 1.8786, 1.5237],
            [0.9812, 0.9703, 1.0981],
            [1.1590, 0.7849, 1.1890]])
    tensor([[1.4692, 0.7374, 0.7234],
            [0.8925, 0.7805, 1.3061],
            [0.8631, 1.8786, 1.5237],
            [0.9812, 0.9703, 1.0981],
            [1.1590, 0.7849, 1.1890]])
    
    • 另一种加法
    y.add(x)
    print(y)
    
    tensor([[0.5895, 0.4489, 0.3473],
            [0.0495, 0.6829, 0.5846],
            [0.2628, 0.9495, 0.9024],
            [0.3175, 0.9222, 0.5868],
            [0.1993, 0.7389, 0.7718]])
    

    索引

    可以利用类似NumPy的索引方式访问Tensor的一部分。索引的结果和原数据共享一个内存

    y = x[0,:]
    y += 1
    print(y)
    print(x[0,:])
    # 索引的数据修改后也改变了原数据
    
    tensor([1.8798, 1.2886, 1.3761])
    tensor([1.8798, 1.2886, 1.3761])
    

    其他一些函数

    函数 功能
    index_select(input,dim,index) 指定维度dim上选取,某行或某列
    masked_select(input, mask) 例⼦如上, a[a>0],使⽤ByteTensor进⾏选取
    non_zero(input) ⾮0元素的下标
    gather(input, dim, index) 根据index,在dim维度上选取数据,输出的size与index⼀样

    改变Tensor的形状

    可以用view()来改变Tensor的形状,就是改变矩阵的行列

    y = x.view(15) # 将5行3列的矩阵改变为一维行向量
    z = x.view(-1,5) # -1 表示该位置自动识别,后面是5列 所以-1位置应该为3
    print(x.size(),y.size(),z.size())
    
    torch.Size([5, 3]) torch.Size([15]) torch.Size([3, 5])
    

    这里的新tensor与原tensor共享内存,一改则都改

    如果需要复制可以使用clone再使用view

    x_cp = x.clone().view(15)
    x -= 1
    print(x)
    print(x_cp)
    
    tensor([[ 0.8798,  0.2886,  0.3761],
            [-0.1569, -0.9025, -0.2784],
            [-0.3997, -0.0710, -0.3788],
            [-0.3363, -0.9519, -0.4887],
            [-0.0403, -0.9539, -0.5827]])
    tensor([1.8798, 1.2886, 1.3761, 0.8431, 0.0975, 0.7216, 0.6003, 0.9290, 0.6212,
            0.6637, 0.0481, 0.5113, 0.9597, 0.0461, 0.4173])
    

    item() 可以将标量的Tensor转换成Python number

    x = torch.randn(1)
    print(x)
    print(x.item())
    
    tensor([-0.5851])
    -0.585087776184082
    
    • torch.rand() 与 torch.randn()

    torch.rand() 是均匀分布([0,1]之间随机抽取)
    torch.randn() 是标准正态分布(均值为0 方差为1)

    线性代数

    函数 功能
    trace 对⻆线元素之和(矩阵的迹)
    diag 对⻆线元素
    triu/tril 矩阵的上三⻆/下三⻆,可指定偏移量
    mm/bmm 矩阵乘法, batch的矩阵乘法
    addmm/addbmm/addmv/addr/badbmm.. 矩阵运算
    t 转置
    dot/cross 内积/外积
    inverse 求逆矩阵
    svd 奇异值分解
    x = torch.rand(3,3)
    print(x)
    print('x的对角元素之和为:{}'.format(x.trace()))
    print('x的对角元素为:{}'.format(x.diag()))
    print('x的上三角:{}'.format(x.triu()))
    print('x的转置:{}'.format(x.t()))
    
    
    tensor([[0.8447, 0.7846, 0.1641],
            [0.5459, 0.4649, 0.9806],
            [0.1267, 0.0251, 0.9043]])
    x的对角元素之和为:2.2139716148376465
    x的对角元素为:tensor([0.8447, 0.4649, 0.9043])
    x的上三角:tensor([[0.8447, 0.7846, 0.1641],
            [0.0000, 0.4649, 0.9806],
            [0.0000, 0.0000, 0.9043]])
    x的转置:tensor([[0.8447, 0.5459, 0.1267],
            [0.7846, 0.4649, 0.0251],
            [0.1641, 0.9806, 0.9043]])
    

    2.2.3 广播机制

    所谓广播机制,就是在处理数据维度不相等的数据时,会自动将数据补全成相同大小

    例如:

    x = torch.arange(1,3).view(1,2)
    print(x)
    y = torch.arange(1,4).view(3,1)
    print(y)
    print(x + y)
    
    
    tensor([[1, 2]])
    tensor([[1],
            [2],
            [3]])
    tensor([[2, 3],
            [3, 4],
            [4, 5]])
    

    2.2.4 运算的内存开销

    利用Python中自带的id函数 验证前面的内存地址差异

    x = torch.tensor([1,2])
    y = torch.tensor([3,4])
    print(id(y))
    y = y + x  # 赋值运算 所以开辟新内存
    print(id(y))
    y += x  # 不开辟新内存  也可以使用.add()
    print(id(y))
    print(y)
    torch.add(x,y,out = y)
    # y.add_(x)
    print(id(y))
    print(y)
    
    
    1714379452136
    1714379449544
    1714379449544
    tensor([5, 8])
    1714379449544
    tensor([ 6, 10])
    

    区分一下add(x,y,out = y) 和 .add()
    前者在torch下

    2.2.5 Tensor和Numpy 互相转换

    利用 numpy() 和 from_numpy() 可以实现Tensor 和 Numpy的数组互相转换

    转换后数据共享内存

    • Tensor转为Numpy
    a = torch.ones(5)
    b = a.numpy()
    print(a,b)
    
    a += 1
    print(a,b)
    b += 1
    print(a,b)
    
    tensor([1., 1., 1., 1., 1.]) [1. 1. 1. 1. 1.]
    tensor([2., 2., 2., 2., 2.]) [2. 2. 2. 2. 2.]
    tensor([3., 3., 3., 3., 3.]) [3. 3. 3. 3. 3.]
    
    • Numpy 转为 Tensor
    import numpy as np
    a = np.ones(5)
    b = torch.from_numpy(a)
    print(a,b)
    
    a += 1
    print(a,b)
    b += 1
    print(a,b)
    
    
    [1. 1. 1. 1. 1.] tensor([1., 1., 1., 1., 1.], dtype=torch.float64)
    [2. 2. 2. 2. 2.] tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
    [3. 3. 3. 3. 3.] tensor([3., 3., 3., 3., 3.], dtype=torch.float64)
    

    【总结】
    主要介绍了Tensor 的创建于使用

  • 相关阅读:
    一则浏览器兼容性解决案例(搜狗)
    使用sass命令行,包含bourbon,neat包的项目
    指针例1
    数学建模四0-1规划
    数学建模3
    数学建模2.生产计划
    复数的实现1.3
    多文件操作1.2.5
    函数及参数类型1.2.4
    指针类型1.2.3
  • 原文地址:https://www.cnblogs.com/wangxiaobei2019/p/12243069.html
Copyright © 2020-2023  润新知