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

正如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的导数值,其中,y.backward(torch.Tensor([1,1,1,1]))中的[1,1,1,1]分别会和对应维数得到的导数相乘,代表向量的每个维度反向传播的更新系数\alpha

总结:

本文主要介绍了Pytorch的基本数据类型:Tensor和Variable的使用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342