这章说的是基础概念Tensor,但是在说之前想简单扯一扯pytorch的安装和大厂提供给我们的GPU白嫖资源~
1.1 Install pytorch
pytorch的安装其实很简单,只要上pytorch的官网,选好对应的配置后复制给出的command,然后在终端Terminal运行即可
【快速链接】pytorch官方下载
由于pytorch的安装太简单,这里就不多赘述了,如果不想在自己电脑上跑pytorch的话,也可以在kaggle和colaboratory上学习,相关环境也已经帮我们配置好了~【提一句,最好科学上网一下】
附上对应链接,注册账号后就可以免费用在线的notebook和GPU了
- google_colaboratory
- kaggle
在pytorch中,我们操作的基本数据类型叫张量(Tensor),那这个Tensor到底是个啥东西呢,我个人理解其实可以简单理解为数组,熟悉Numpy或者线性代数的小伙伴应该都不会陌生,零维数组就是一个标量,一维数组代表向量,二维数组代表矩阵,n维数组代表高维度数组
那有小伙伴问了,那我为啥不直接用Numpy的array要用tensor呢?这是因为深度学习框架很多时候是需要用到GPU来进行运算的,同样是一个相同的矩阵,如果不是tensor类型的话,是不能被放到GPU中运算的,这也是为什么在pytorch中我们都会使用张量来运算而不是数组
1.2 创建张量
1.2.1 通过3种数据结构创建
学习首先要从最基础的开始,对pytorch来说,最基础的就是张量的创建了
在pytorch下,有三种方法可以创建张量,一是通过列表(list),二是通过元组(tuple),三是通过Numpy的数组(array),基本创建代码如下:
import torch # 导入pytorch
import numpy as np # 导入numpy
print(torch.__version__) # 查看torch版本
t1 = torch.tensor([1,1]) # 通过列表创建
t1 = torch.tensor((1,1)) # 通过元组创建
t1 = torch.tensor(np.array([1,1]) # 通过数组创建
t1 # tensor([1, 1])
创建完张量后,我们还需要记住一些查看张量相关属性的基本操作,因为后期遇到的张量结构都比较复杂,难以用肉眼直接看出,因此相关方法用的也比较频繁
方法 | 描述 | 栗子 |
---|---|---|
ndim |
查看张量的维度,也可使用dim() | t.ndim /t.dim() |
dtype |
查看张量的数据结构 | t.dtype |
shape |
查看张量的形状 | t.shape |
size |
查看张量的形状,和shape方法相同 | t.size() |
numel |
查看张量内元素的元素 | t.numel() |
稍微注意一下,size()和numel()是需要加括号滴【代表函数的调用】,下面是具体案例用法
t2 = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
t2.ndim # 2
t2.dtype # torch.int64
t2.shape # torch.Size([3, 3])
t2.size() # torch.Size([3, 3])
t2.numel() # 返回9
python作为动态语言,平常我们基本不会去注意到变量的类型,因为我们编写代码时并不需要声明变量类型,但是细心的小伙伴会发现,调用dtype后返回的是torch.int64, 这说明pytorch对于数组的类型是很严谨,因此我们还要了解在pytorch下的数组类型
懒的小伙伴其实只需要记住有整数,浮点数,布尔型和复数即可,但为了文章的完整,我肯定还是要说一说
类型 | dtype |
---|---|
32bit浮点数 | 【单精度】torch.float32 / torch.float |
64bit浮点数 | 【双精度】torch.float64或torch.double |
16bit浮点数 | torch.float16 |
8bit无符号整数 byte | torch.unit8 |
8bit有符号整数 | torch.int8 |
16bit有符号整数 | torch.int16 / torch.short |
32bit有符号整数 | torch.int32 / torch.int |
64bit有符号整数 | torch.int64 / torch.long |
布尔型 | torch.bool |
复数型 | torch.complex64 |
在pytorch中,默认的张量整数类型是int64,使用浮点数类型是float32【根据pytorch版本的不同可能会有所不同】;
双精度double能存储的有效位数比单精度float更多,但相应的需要的存储空间越多
int16,int32,int64的区别主要在于表示值的范围不同,数字越大所能表示的范围越大
在pytorch中,可以使用在创建时指定数据类型,也可以后期进行修改,下面是案例
t3 = torch.tensor([True, 1.0]) # tensor([1., 1.])隐式转换
t3 = torch.tensor([1,1,1,1],dtype=float)
t3.dtype # torch.float64
t3.int() # tensor([1, 1, 1, 1], dtype=torch.int32)
t3.byte() # tensor([1., 1., 1., 1.], dtype=torch.float64)
t3.short() # tensor([1, 1, 1, 1], dtype=torch.int16)
t3.bool() # tensor([True, True, True, True])
1.2.2 通过相关方法创建特殊张量
除了使用列表,元组和数组创建张量外,还可以使用相关方法来创建张量
方法 | 描述 |
---|---|
torch.zeros() |
创建全为0的张量 |
torch.ones() |
创建全为1的张量 |
torch.eye() |
创建对角为1的单位矩阵 |
torch.diag(t) |
创建对角矩阵,需要传入1维张量 |
torch.rand() |
创建服从0-1均匀分布的张量 |
torch.randn() |
创建服从标准正态分布的张量 |
torch.normal() |
创建服从制定正态分布的张量 |
torch.randn |
创建服从标准正态分布的张量 |
torch.randint() |
创建由指定范围随机抽样整数组成的张量 |
torch.arange() |
创建给定范围内的连续整数组成的张量 |
torch.linspace() |
创建给定范围内等距抽取的数组成的张量 |
torch.empty() |
创建未初始化的指定形状的张量 |
torch.full() |
创建指定形状,指定填充数值的张量 |
以下是案例,需要注意有哪些方法是传入代表结构的列表,有哪些是传入张量,有哪些是传入数字
torch.zeros([3,3]) # 创建3行3列,元素全为0的2维张量
torch.ones([3,3]) # 创建3行3列,元素全为1的2维张量
torch.eye(4) # 创建4行4列的单位矩阵
t = torch.tensor([1,2,3,4]) # 创建需要传入的1维张量
torch.diag(t) # 创建对角元素为1,2,3,4的对角矩阵
torch.rand([3,4]) # 创建元素为0-1分布的3行4列张量
torch.normal(3, 4, [2, 2]) # 创建服从均值为3,标准差为4的正态分布元素组成的张量
torch.randn([3,4]) # 创建元素为标准正态分布的3行4列张量
torch.randint(0,20,[3,4]) # 创建由0-20间的随机整数组成的3行4列的张量
torch.arange(1,20) # 创建0-20内连续整数组成的张量
torch.linspace(1, 10, 5) # 创建给定范围内等距取样的数组成的张量
torch.empty([3,4]) # 创建3行4列的未初始化张量
torch.full([3, 4], 2) # 创建3行4列的全为2的张量
上述是一些用的较多的特殊常见方法,也不需要全记住,需要用到的时候查阅即可
1.2 张量的维度&形状
张量的维度是怎么看的呢?代表什么意思呢?比如,为什么torch.tensor([[1, 2], [3, 4]]).ndim
为什么返回的是2呢?这个2代表什么意思呢?别急,现在就给大家说说
ndim
返回的是对应张量对象的维度,范围2就说明这个张量是2维的,3就说明这个张量是3维的,返回几就说明这个向量的几维的
那么怎么理解这个结构呢?
我们先从0维讲起,0维说明这个张量是一个0维张量,对应的其实是一个标量,也就是一个数,但要注意这个标量和普通的标量又有所区别,这是一个可以在GPU下运行的标量
如果ndim
返回的是1,对应的是1维张量,说明这个张量是一个向量vector
如果ndim
返回的是2,对应的是2维张量,是有n行m列的矩阵matrix
如果ndim
返回的是3,对应的是有a个n行m列的矩阵,比如下面的矩阵就代表2个2行2列的矩阵
torch.tensor([[[1,1],[1,1]],[[1,1],[1,1]]])
'''
tensor([[[1, 1],
[1, 1]],
[[1, 1],
[1, 1]]])
'''
如果ndim
返回的是4呢,对应的就是a组,每组里有b个n行m列的矩阵
以此类推....
我们在创建张量时可以指定其结构和维度,在创建后也可以对其进行修改,我们可以使用reshape()
方法修改其结构和维度,参数传入维度组成的列表,需要注意修改结构前后元素的数量要相等
如果高纬张量要变成一维张量,可以使用flatten()
方法,也可以使用reshape(t.numel())
torch.normal(3, 4, size=[2, 2]) # 创建时指定形状
t4 = torch.tensor([1,2,3,4,5,6,7,8])
t4 = t4.reshape([2,4]) # 改成2行4列的张量
t4
'''
tensor([[1, 2, 3, 4],
[5, 6, 7, 8]])
'''
t4.reshape(t4.numel()) # tensor([1, 2, 3, 4, 5, 6, 7, 8])
t4.flatten() # tensor([1, 2, 3, 4, 5, 6, 7, 8])
以上是chapter1 1.1到1.2部分的内容,欢迎小伙伴们一起交流讨论~
参考资料
[1] pytorch官方文档