美文网首页大数据,机器学习,人工智能PyTorch
Pytorch从0到1系列之(1)---Pytorch的基本数据

Pytorch从0到1系列之(1)---Pytorch的基本数据

作者: 东写西读1 | 来源:发表于2019-06-10 21:03 被阅读4次

    正如numpy包中的array,Pandas包中的Series和Dataframe一样,为了方便计算,Pytorch也在Python数据结构的基础上封装了几个基本的数据结构。

    一、张量(Tensor)

    没错,就是TensorFlow名字里的Tensor,本来谷歌给TensorFlow命名的时候就是给这个框架赋予了深度学习就是“张量流动”的深刻内涵。因为深度学习处理的数据量和维度都比较大,所以很多深度学习框架借用了张量这个概念作为基本的数据结构。

    其实张量虽然听起来非常高大上,数学上也有一些其他的物理世界抽象和运算法则。但是,张量其实就是一个多维的向量,二维张量就是三维向量、一维张量就是二维向量……所以,在深度学习里,我们直接把它看做一个多维的向量就好。

    1、创建张量

    1)基本创建语法

    在Pytorch中,创建张量的方式非常简单,只需要:a = torch.Tensor(参数)即可。
    在这里,如果我们需要创建固定维度大小的张量,那么参数可以写成:(n,m,……),如果需要指定每个元素的值,那么就参数就需要写成:([元素1,元素2,元素3,元素4,……])

    比如,以下是一个创建张量的例子:

    import torth
    A = torch.Tensor(2,3) #创建一个维度为(2,3)的张量
    
    b = [[1,2,],[3,4],[5,6]]
    B = torch.FloatTensor(b)#创建一个元素为b数组中的元素的张量
    
    print(A)
    print(A.type())
    print(B)
    print(B.type())
    

    输出结果如下:

    tensor([[ 9.5016e+21,  1.9249e-37,  1.7228e-34],
            [ 1.8311e-38, -3.7846e-37,  3.8074e+22]])
    torch.FloatTensor
    tensor([[1., 2.],
            [3., 4.],
            [5., 6.]])
    torch.FloatTensor
    

    这里可以看到,两种方式创建的张量都是Float类型。因为这种数据类型即保证了一定的精确度,又不是特别占用内存。

    当然,在使用过程中,根据自己的实际情况,可以创建指定元素数据类型的张量:

    • 元素为32位浮点型的张量(同上边效果是一样的):torch.FloatTensor()
    • 元素为64位浮点型的张量:torch.DoubleTensor()
    • 元素为整型的张量(32位):torch.IntTensor()
    • 元素为16位整型的张量:torch.ShortTensor()
    • 元素为64位整型的张量:torch.LongTensor()

    如果需要查看某一张量的维度,可以使用A.size()

    2)创建一些特殊的张量。

    创建全0张量:A = torch.zeros(n,m)

    创建全1张量:A = torch.ones(n,m)

    创建指定维度的随机数张量:(元素呈正态分布,均值为0,方差为1)A = torch.randn(n,m)

    创建指定维度的随机数张量:(元素在0到1之间均匀分布)A = torch.rand(n,m)

    创建元素以一定步长递变的张量:A = torch.range(起始值,结束值,步长)
    注意,这里生成的值是浮点型,步长也可以设置为浮点型。

    2、张量运算

    为了便于接下来的运算,我们首先生成几个Tensor变量。

    import torch
    A = torch.Tensor( [[-1,-2],[-3,-4],[-5,-6]]) 
    B = torch.Tensor( [[1,2],[3,4],[5,6]]) 
    C = 2
    
    
    1)对所有元素取绝对值:torch.abs(A)
    ab = torch.abs(A)
    print(ab)
    

    输出结果:

    tensor([[1., 2.],
            [3., 4.],
            [5., 6.]])
    
    2)两个张量对应元素相加:torch.add(A,B)
    ad1 = torch.add(A,B)
    print(ad1)
    
    ad2 = torch.add(A,C)
    print(ad2)
    
    

    输出结果:

    tensor([[0., 0.],
            [0., 0.],
            [0., 0.]])
    tensor([[ 1.,  0.],
            [-1., -2.],
            [-3., -4.]])
    

    可以看到,numpy的广播机制在Pytorch中也适用。

    3)两个张量对应元素相乘:torch.mul(A,B)
    mul1 = torch.mul(A,B)
    print(mul1)
    
    mul2 = torch.mul(A,C)
    print(mul2)
    
    

    输出结果:

    tensor([[ -1.,  -4.],
            [ -9., -16.],
            [-25., -36.]])
    tensor([[ -2.,  -4.],
            [ -6.,  -8.],
            [-10., -12.]])
    
    4)两个张量对应元素相除:torch.div(A,B)
    div1 = torch.div(A,B)
    print(div1)
    
    div2 = torch.div(A,C)
    print(div2)
    
    

    输出结果:

    tensor([[-1., -1.],
            [-1., -1.],
            [-1., -1.]])
    tensor([[-0.5000, -1.0000],
            [-1.5000, -2.0000],
            [-2.5000, -3.0000]])
    
    5)两个张量按照矩阵乘法规则结合:torch.mm(A,B)

    特别注意,这个函数要和torch.mul(A,B)区分,这个函数需要两个张量满足矩阵乘法运算规则才可以运算。

    mm = torch.mm(A,torch.t(B))#对B矩阵转置之后与A矩阵相乘
    print(mm)
    

    输出结果:

    tensor([[ -5., -11., -17.],
            [-11., -25., -39.],
            [-17., -39., -61.]])
    
    6)显示张量元素的值:torch.clamp(A,min,max)

    会使超出[min,max]元素的值被限制在这个范围内。

    cla = = torch.clamp(A,-4,-1)
    print(cla)
    

    输出结果:

    tensor([[-1., -2.],
            [-3., -4.],
            [-4., -4.]])
    

    另外,还有一些操作,例如:

    • 求张量A的n次幂:torch.pow(A,n)
    • 求矩阵和向量的乘积:torch.mv(A,B)。其中A是矩阵B是向量,也需要维度符合规则。

    通过上边的例子可以看到,torch的张量和numpy数组非常类似。的确,Pytorch中的张量可以理解为可以在GPU上运行的numpy数组。两者也可以通过torch.from_numpy()A.numpy这两个函数相互转换。看下边这个例子:

    A = np.array([[1,2,3],[4,5,6]])#生成一个numpy数组
    print("A的数据类型是:",type(A)) #将numpy数组转换成torch张量
    At = torch.from_numpy(A)
    print("At的数据类型是:",type(At))  
    An = At.numpy()   #将torch张量转换成numpy数组
    print("An的数据类型是:",type(An))
    

    输出结果如下:

    A的数据类型是: <class 'numpy.ndarray'>
    At的数据类型是: <class 'torch.Tensor'>
    An的数据类型是: <class 'numpy.ndarray'>
    

    二、变量(Variable)

    在Pytorch中,张量就是个死气沉沉的数组,只可以执行简单的加减乘除以及矩阵操作,而这对于深度学习是远远不够的。变量赋予了张量自动求导这一深度学习反向传播所需要的重要能力。

    其基本原理就是,变量相当于把张量放到了一个计算图中(计算图这概念再TensorFlow中也有,不过TensorFlow中需要用户手动创建计算图,而Pytorch中需要用户执行的操作相对较少)。

    要想使用Variable函数,需要先导入自动求梯度包:from torch.autograd import Variable

    Variable有三个属性:data,grad和grad_fn。
    data属性存放了Variable的张量值,grad属性可以得到这个张量反向传播的梯度,grad_fn可以得到这个Variable的操作【进一步解释】。看这样一个例子:

    import torch
    from torch.autograd import Variable
    
    x1= Variable(torch.Tensor([3]),requires_grad = True)
    y1 = 3*x1 +1
    y1.backward()
    print(x1.grad)
    
    x2 = Variable(torch.Tensor([3]),requires_grad = True)
    y2 = 3*torch.pow(x2,2) +1
    y2.backward()
    print(x2.grad)
    

    其中,requires_grad = True的意思是在反向传播的时候要对这个变量求梯度。输出如下:

    tensor([3.])
    tensor([18.])
    

    可以看到,可能有人会觉得,这明显就是对函数y1 = 3x_1+1y2 = 3x_2^2+1求了个导数嘛,有什么了不起的。但是,Variable最厉害的是对于复杂的函数和复合函数也可以用一条语句求梯度,另外也可以求矩阵的梯度,比如:

    import torch
    from torch.autograd import Variable
    
    x = Variable(torch.Tensor([1,2,3,4]),requires_grad = True)
    y = 3*torch.pow(x,2) +1
    y.backward(torch.Tensor([1,1,1,1]))#这里必须要写入参数,于被求导的张量维数相同。
    print(x.grad)
    

    输出如下:

    tensor([ 6., 12., 18., 24.])
    

    这样,就可以分别得到x = 1,2,3,4时,y的导数值。

    相关文章

      网友评论

        本文标题:Pytorch从0到1系列之(1)---Pytorch的基本数据

        本文链接:https://www.haomeiwen.com/subject/qfuzxctx.html