zoukankan      html  css  js  c++  java
  • pytorch(一)张量基础及通用操作

    1.pytorch主要的包:

    • torch: 最顶层包及张量库
    • torch.nn: 子包,包括模型及建立神经网络的可拓展类
    • torch.autograd: 支持所有微分操作的函数子包
    • torch.nn.functional: 其他所有函数功能,包括激活函数,卷积操作,构建损失函数等
    • torch.optim: 所有的优化器包,包括adam,sgd等
    • torch.utils.data: 子包,包括所有处理数据更简便的功能类,如datasets,dataloader等
    • torchvision: 与torch同level的包,包含一些流行的数据集,模型和图片变换处理方法。

    2.检测安装环境

    torch.cuda.is_available()
    True
    
    torch.version.cuda
    '10.0'
    

    3.深度学习及神经网络利用GPU的原因

    神经网络是一个高度并行的计算任务an embarrassingly parallel task :子任务之间互相独立

    4.tensor是什么

    tensor就是n维数组,是神经网络的基本数据结构
    scalar/0--->vector/1--->matrix/2--->tensor/n
    只有在二阶的数据中才存在row-行和collum-列的概念

    5.tensor的阶(维度),轴及shape

    • 维度(阶,rank):索引到tensor中一个特定的元素需要的index的数目

    • 轴:指tesor特定的某一个维度,如第2维(shape的每个数字代表一个轴)

    假设张量t的第一维(轴)长度为3,第二维(轴)长度为4:

    • 表明沿着第一轴可以索引到3个位置(每个位置是(3,)),t[0],t[1],t[2];

    • 沿第二周轴可以索引到3*4=12个位置(每个位置是(1,)---最后一个轴索引出的是一个元素),t[0][0],t[0][1],t[0][2],t[0][3],......

    • shape: 每个轴的长度,因此shape可以表达张量的元素总数。shape至关重要:编码了张量所有相关的信息,包括维度,轴,索引。
      shape: (3,4)--->第一轴长度为3,第二周长度为4,共 3*4 = 12 元素

    张量shape的内涵:(Numbers of one Batch, Channel, Heigh, Width)

    • N-C-H-W-----Pytorch
    • N-H-W-C-----Tesorflow、Keras
    tensor.reshape(a,b)#改变shape不改变数据
    

    6.featuremap

    特征图:指神经网络中间层的输出
    之所以称特征图:因为这些输出表示图像一些特征,比如边缘,纹理等,且这些特征随着网络的加深变得更复杂。

    7.pytorch的torch的创建

    t = torch.Tesnor()
    type(t)#torch.Tensor
    

    torch.Tensor有3个属性

    • torch.deveice :cuda:0, cpu。张量计算必须是在相同device上的数据
    • torch.dtype : float-32,double-64,Half-16
    • torch.layout :数据的存储方式,涉及到空间局部性。

    混合精度计算

    1.3及以后版本支持混合精度计算

    通过numpy数组创建tensor

    data = np.array([1,2,3])
    o1 = torch.Tensor(data) #tensor([1.,2.,3.]),float类型
    o2 = torch.tensor(data) #tensor([1, 2, 3], dtype=torch.int32)
    o3 = torch.as_tensor(data) #tensor([1, 2, 3], dtype=torch.int32)
    o4 = torch.from_numpy(data) #tensor([1, 2, 3], dtype=torch.int32)
    
    1. Copy Data(建模训练)
    • torch.Tensor(data) 劣势:创建时无dtype配置选项,强制为float32类型。
    • torch.tensor(data) 优势:创建时具有dtype配置选项,torch.tensor(data, dtype=torch.float32)。
    1. Share Data(可用于优化代码性能,这里的共享内存必须满足相同的device前提)
    • torch.as_tensor(data) 优势:可以接受多种data输入方式,如tensor等。(共享对于python内建数据类型如list无效,对于代码性能影响是模型中有大量的tensor和nunmy数据的来回操作)
    • torch.from_numpy(data) 劣势:只接受numpy的data输入

    不通过data创建特殊张量类型

    torch.eyes([2,2]) #单位阵i
    torch.zeros()
    torch.ones()
    torch.rand() #从[0,1]间的 均匀分布 采样
    

    8.张量操作(一)之变形reshape/view/squeeze/unsqueeze

    .shape == .size() #后者要带括号

    reshape/view: 改变tensor的shape

    区别:view接受的必须是data底层存储连续的tensor,因此前面经常跟一个contiguous(),且数据还是原来的数据。reshape则不需要,且reshape()没那么可控,执行结果可能是源数据的一个copy,也可能不是。
    因此 如果需要copy,用clone();如果需要源数据,用view();reshape()这玩意不好控制,最好少用。

    t = torch.tensor([[
        [1,1,1,1],
        [2,2,2,2],
        [3,3,3,3]
    ], dtype=torch.float32])
    t.reshape(1,-1).shape    # (1,12),-1表示按元素个数自动推理 t.numel() = 3*4 = 1*x
    t.view(1,-1).size()     # (1,12)
    t.view(t.numel())
    t.flatten()
    t.reshape(-1)  # 以上操作结果相同
    
    
    def flatten(t):
          t = t.reshape(1,-1)
          return t
    

    Squeeze 和 unsqueeze

    print(t.reshape([1,12]))
    print(t.reshape([1,12]).shape)
    # tensor([[1., 1., 1., 1., 2., 2., 2., 2., 3., 3., 3., 3.]])
    # torch.Size([1, 12])
    
    t.reshape([1,12]).suqueeze()   #无法指定压缩维度的位置,只能在第0维
    t.reshape([1,12]).squeeze().shape
    # tensor([1., 1., 1., 1., 2., 2., 2., 2., 3., 3., 3., 3.])
    # torch.Size([12])
    
    t.reshape([1,12]).squeeze().unsqueeze(dim=0)   #可以指定升维的位置
    t.reshape([1,12]).squeeze().unsqueeze(dim=0).shape
    # tensor([[1., 1., 1., 1., 2., 2., 2., 2., 3., 3., 3., 3.]])
    # torch.Size([1, 12])
    

    张量的拼接cat

    t1 = torch.tensor([
        [1,2],
        [3,4]])
    
    t2 = torch.tensor([
        [5,6],
        [7,8]])
    t = torch.cat((t1,t2),dim = 0)  #在第0轴拼接
    # tensor([
        [1,2],
        [3,4],
        [5,6],
        [7,8]
      ])
    t = torch.cat((t1,t2),dim = 1) #在第1轴拼接
    # tensor([[1, 2, 5, 6],
            [3, 4, 7, 8]])
    

    张量堆叠-stack

    #stack与cat的区别:stack堆叠会在**指定位置增加一维**,不指定默认位置是0轴。
    
    a=torch.randn((1,3,4,4)) #[N,c,w,h]
    b=torch.stack((a,a))
    b.shape
    # (2, 1, 3, 4, 4)
    
    c=torch.stack((a,a),1)
    c.shape
    # (1, 2, 3, 4, 4)
    
    d=torch.stack((a,a),2)
    d.shape
    # (1, 3, 2, 4, 4)
    
    

    张量沿特定轴展开,参数 start_dim

    
    t = tensor(
    [
        [
            [
                [1, 1, 1, 1],
                [1, 1, 1, 1],
                [1, 1, 1, 1],
                [1, 1, 1, 1]
            ]
        ],
        [
            [
                [2, 2, 2, 2],
                [2, 2, 2, 2],
                [2, 2, 2, 2],
                [2, 2, 2, 2]
            ]
        ],
        [
            [
                [3, 3, 3, 3],
                [3, 3, 3, 3],
                [3, 3, 3, 3],
                [3, 3, 3, 3]
            ]
        ]
    ])
    t.shape #(3,1,4,4)
    
    t.flatten(start_dim = 1).shape
    #tensor(3,16) #看它的沿第几个轴展开,那么之后的轴(axis = 2, 及 axis = 3)都被展开而消失,张量的阶由4降低到4-2=2
    
    t.flatten(start_dim=1)
    # tensor(
    [
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
        [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
    ]
    )
    
    

    9.张量操作(二)之算术运算(即逐元素操作 element-wise ops ,也称point-wise.张量的所有代数操作都是逐元素的)

    t1 = torch.tensor([
        [1,2],
        [3,4]
    ], dtype=torch.float32)
    
    t2 = torch.tensor([
        [9,8],
        [7,6]
    ], dtype=torch.float32)
    
    t1+t2
    t1+2
    t1 * 2
    t1 / 2
    

    逐点操作的基础----广播

    t1 = torch.tensor([
        [1,1],
        [1,1]
    ], dtype=torch.float32)
    #shape = (2,2)
    
    t2 = torch.tensor([2,4], dtype=torch.float32)  #shape = (2,)
    
    
    
    # t1+t2 ??
    np.broadcast_to(t2.numpy(), t1.shape)    # 广播:第1个参数data,第2个参数shape
    # array([[2., 4.],[2., 4.]], dtype=float32)
    
    t1 + t2
    tensor([[3., 5.],
            [3., 5.]])
    
    
    
    #一些利用广播的函数举例
    t.abs()
    t.sqrt()
    t.neg()
    

    10.张量操作(三)之 单个tensor的减少reduction(元素)操作

    #普通的张量减少(元素)操作
    t.sum() #元素求和
    t.numel() #元素总数
    t.prod()
    t.mean()
    t.std()  #标准差
    
    #沿轴减少操作
    t = torch.tensor([
        [1,1,1,1],
        [2,2,2,2],
        [3,3,3,3]
    ], dtype=torch.float32)
    
    t.sum(dim = 0) #tensor([6., 6., 6., 6.])
    
    t.sum(dim = 1) #tensor([4., 8., 12.])
    
    #张量最大值的下标索引 argmax
    t = torch.tensor([
        [1,0,0,2],
        [0,3,3,0],
        [4,0,0,5]
    ], dtype=torch.float32)
    
    t.max() #tensor(5.)
    
    #如果不指定轴argmax索引,会默认是从flatten完全展开后得到的索引下标
    t.argmax() #tensor(11)
    
    #指定轴argmax索引时
    t.max(dim=0)
    # tensor([4., 3., 3., 5.])
    
    t.argmax(dim=0)
    # tensor([2, 1, 1, 2])
    
    t.max(dim=1)
    # tensor([2., 3., 5.])
    
    t.argmax(dim=1)
    # tensor([3, 1, 3])
    
    #获取张量内的元素
    t = torch.tensor([
        [1,2,3],
        [4,5,6],
        [7,8,9]
    ], dtype=torch.float32)
    
    t.mean()
    # tensor(5.)
    
    t.mean().item()  # .item()获取元素作为scalar
    # 5.0
    
    t.mean(dim=0).tolist()  # .tolist()转变为list
    # [4.0, 5.0, 6.0]
    
    t.mean(dim=0).numpy() # tensor--->numpy数组
    # array([4., 5., 6.], dtype=float32)
    
    
  • 相关阅读:
    网友谈:Dictionary.ContainsKey和List.BinarySearch哪个效率高
    C# WinForm 中在窗口标题栏上加按钮
    将Txt文件转换成dataset[原创]
    四个常见的排序算法[原创]
    改版后的groupbox[原创]
    转 五种提高 SQL 性能的方法
    转 牢记!SQL Server数据库开发的二十一条军规(SQL收藏)
    源码详解Java的反射机制
    java多线程采集+线程同步
    jQgrid API
  • 原文地址:https://www.cnblogs.com/Henry-ZHAO/p/13064092.html
Copyright © 2011-2022 走看看