PyTorch是一个基于Python的科学计算包,它主要有两个用途:
1、类似Numpy但是能利用GPU加速
2、一个非常灵活和快速的用于深度学习的研究平台
tensor
Tensor,也叫做张量,类似与NumPy的ndarray,但是可以用GPU加速。
而对于tensor的基础操作,可以从两个方面来讲。
一、如果从接口的角度,对一个tensor的操作可以分为两类:torch.function
,如torch.save
tensor.function
,如tensor.view
对于这两种接口方法,大多数时候都是等价的,如
torch.sum(a,b)
和a.sum(b)
二、如果从存储的角度讲,对tensor的操作也可以分为两类:a.add(b)
,不会修改a自身的数据,加法的结果会返回一个新的tensora.add_(b)
,会修改a自身的数据,也就是说加法的结果存在a中
函数名以
_
结尾的都是修改调用者自身的数据。
创建tensor
以下是一些创建的函数,其中如果*size
为列表,则按照列表的形状生成张量,否则传入的参数看作是张量的形状:
1 | Tensor(*size) # 基础构造函数,默认为dtype(FloatTensor)类型 |
1 | a = t.Tensor(2, 3) # 指定形状构建2*3维的张量 |
t.Tensor(*size)
创建tensor时,系统不会马上分配空间,只有使用到tensor时才会分配内存,而其他操作都是在创建tensor后马上进行空间分配。
常用tensor操作
调整tensor的形状
view()
方法调整tensor的形状,但是必须得保证调整前后元素个数一致,但是view方法不会修改原tensor的形状和数据
1 | a = t.arange(0, 6) |
resize()
是另一种用来调整size的方法,但是它相比较view
,可以修改tensor的尺寸,如果尺寸超过了原尺寸,则会自动分配新的内存,反之,则会保留老数据
1 | a = t.arange(0, 6) |
添加或压缩tensor维度
unsqueeze()
可以增加tensor的维度;squeeze()
可以压缩tensor的维度
1 | a = t.arange(0, 6) |
1 | a = t.arange(0, 6) |
索引操作
tensor的索引操作和ndarray的索引操作类似,并且索引出来的结果与原tensor共享内存。
高级索引
PyTorch 支持绝大多数 NumPy 的高级索引,高级索引可以看成是基本索引的扩展。
1 | a = torch.arange(9).view([3, 3]) |
1 | index_select(input,dim: _int, index: Tensor) # 在指定维度dim上选取,例如选取某些行、某些列。输出结果与输入张量的维度相同。 |
index_select
1 | a = t.arange(9).view([3, 3]) |
masked_select
1 | a = t.arange(9).view(3, 3) |
take
1 | a = t.arange(9).view(3, 3) |
PyTorch的nn模块
PyTorch有一个专门用于神经网络的完整子模块:torch.nn
。该子模块包含创建各种神经网络体系结构所需的构建块。这些构建块在PyTorch术语中称为module(模块),在其他框架中称为layer(层)。
PyTorch模块都是从基类nn.Module
继承而来的Python类。模块可以具有一个或多个参数(Parameter
)实例作为属性,这些参数就是在训练过程中需要优化的张量(在之前的线性模型中即w和b)。模块还可以具有一个或多个子模块(nn.Module
的子类)属性,并且也可以追踪其参数。
你可以毫不奇怪地可以找到一个名为nn.Linear
的nn.Module
子类,它对其输入进行仿射变换(通过参数属性weight和bias);它就相当于之前在温度计实验中实现的方法。现在,从上次中断的地方开始,将之前的代码转换为使用nn
的形式。
所有PyTorch提供的nn.Module
子类都定义了其调用方法,使你可以实例化nn.Linear
并将其像一个函数一样进行调用,如下面的代码所示:
1 | import torch.nn as nn |
使用一组参数调用nn.Module
实例最终会调用带有相同参数的名为forward
的方法,forward
方法会执行前向传播计算;不过在调用之前和之后还会执行其他相当重要的操作。因此,虽然从技术上讲直接调用forward
是可行的,并且它产生的结果与调用nn.Module
实例相同,但用户不应该这样做。
nn.Liner
表示线性模型(全连接层),nn.Linear
的构造函数接受三个参数:输入特征的数量,输出特征的数量以及线性模型是否包含偏差(此处默认为True)。
这里特征的数量是指输入和输出张量的尺寸,因此本例是1和1。例如,如果在输入中同时使用了温度和气压,则在其中输入具有两个特征输入和而输出只有一个特征。如你所见,对于具有多个中间模块的更复杂的模型,模型的容量与特征的数量有关。