PyTorch学习(1):基础知识
- Pytorch官方文档: https://pytorch-cn.readthedocs.io/zh/latest/
- Pytorch学习文档: https://github.com/tensor-yu/PyTorch_Tutorial
- 参考: https://blog.csdn.net/u011995719/article/details/85102770
https://blog.csdn.net/weicao1990/article/details/93177626
文章目录
- PyTorch学习(1):基础知识
- 1.什么是PyTorch?
- 2.Tensor(张量)
- (1)创建张量
- (2)类型转换
- (3)Tensor和Numpy.ndarray之间的转换
- (4)CPU和GPU张量之间的转换
- 3.Variable(变量)
- 总结
1.什么是PyTorch?
PyTorch是一个基于Python的科学计算包,主要定位两类人群:
(1)Numpy的替代品,可以利用GPU的高性能进行计算。
(2)深度学习研究平台,动态图机制拥有足够的灵活性和速度。
2.Tensor(张量)
PyTorch里面处理的最基本的操作对象就是Tensor,Tensor是张量的英文,表示的是一个多维的矩阵,比如零维就是一个点,一维就是向量,二维就是一般的矩阵,多维就相当于一个多维的数组,这和numpy是对应的,而且PyTorch的Tensor可以和numpy的ndarray相互转换,唯一不同的是PyTorch可以在GPU上运行,而numpy的ndarray只能在CPU上运行。
Tensor常见的数据类型包括:
32位的浮点型torch.FloatTensor、64位浮点型torch.DoubleTensor、16位整型torch.ShortTensor、32位整型torch.IntTensor和64位整型torch.LongTensor。
(1)创建张量
张量可以在Python list形式下通过torch.Tensor()函数创建。
E.g1. 定义一个三行两列给定元素的矩阵,并且显示出矩阵的元素和大小:
import torch
V = torch.Tensor([[2,3], [4,8], [7,9]])
print('V is: {}'.format(V))
print('V size is {}'.format(V.size()))
需要注意的是torch.Tensor默认的是torch.FloatTensor数据类型。
E.g2. 也可以指定特定的数据类型:
B = torch.LongTensor([[2,3], [4,8], [7,9]])
print('B is : {}'.format(B.type()))
E.g3. 当然也可以创建一个全0的空Tensor或者取一个正太分布作为随机初始值:
S = torch.zeros((3,2))
print('S is : {}'.format(S))
C = torch.randn((3,2))
print('C is : {}'.format(C))
张量可以像numpy一样通过索引的方式取得其中的元素,同时也可以改变它的值。
比如将S的第一行第二列改变为100:
S[0,1] = 100
print('changed S is : {}'.format(S))
重构张量,许多神经网络的神经元对输入格式有明确的要求。通常需要先将数据重构再输入到神经元中。 使用.view()进行实现,如果维度为-1,那么它的大小可以根据数据推断出来。
X = S.view(1,6)
print('restructure X is : {}'.format(X))
(2)类型转换
Pytorch数据类型的检查可以通过以下三种方式:
1)python的内置函数type()
2)Tensor的成员函数Tensor.type()
3)Pytorch提供的类型判断函数isinstance()
A = torch.LongTensor([[2,3], [4,8], [7,9]])
print(type(A))
print(A.type())
print(isinstance(A, torch.LongTensor))
从运行结果来看,Tensor的**成员函数type()**更加直观,可以检测出Tensor的基本类型。
Tensor类型的变量进行转换一般有两种方法:
1) Tensor类型的变量直接调用long(),int(),double(),float(),byte()等函数;
2) 在Tensor的成员函数type()中直接传入要转换的数据类型。
注:当不知道要转换的类型时,但要计算两个张量的乘积时,可以使用a.type_as(b)将a转换为b的同类型。
import torch
A = torch.randn((3,2))
print(A.type())
B = A.int()
print(B.type())
C = A.type(torch.LongTensor)
print(C.type())
D = A.type_as(B)
print(D.type())
(3)Tensor和Numpy.ndarray之间的转换
Tensor和Numpy直接数据类型还可以相互转换,其方式如下:
1)Numpy转换为Tensor:torch.from_numpy(numpy矩阵)
2)Tensor转换为Numpy:Tensor矩阵.numpy()
import torch
import numpy as np
A = torch.randn((3,2))
numpy_A = A.numpy()
print(numpy_A)
numpy_B = np.array([[2,3], [4,8], [7,9]])
torch_B = torch.from_numpy(numpy_B)
print(torch_B)
(4)CPU和GPU张量之间的转换
如果电脑支持GPU加速,还可以将Tensor放到GPU上。具体操作如下:
1)CPU张量 --> GPU张量,使用Tensor.cuda()
2)GPU张量 --> CPU张量,使用Tensor.cpu()
首先通过torch.cuda.is_available() 函数判断一下是否支持GPU,如果支持,则返回True。
import torch
A = torch.zeros((3,2))
if torch.cuda.is_available():
inputs = A.cuda()
else:
inputs = A
print(A.device)
print(inputs.device)
3.Variable(变量)
变量Variable,这个在Numpy里面是没有的,是神经网络计算图里特有的一个概念,就是Variable提供了自动求导的功能。
Variable和Tensor本质上没有区别,不过Variable会被放入一个计算图中,然后进行前向传播、反向传播,自动求导。
Variable是定义在torch.autograd.Variable中的,要将一个Tensor变成Variable也非常简单,比如想让一个tensor a变成Variable,只需要Variable(a)即可。
Variable有三个比较重要的组成属性:data,grad和grad_fn。
(1) 通过data可以取出Variable里面的tensor数值;
(2) grad_fn表示的是得到这个Variable的操作,比如通过加减还是乘除来得到的;
(3) 最后grad是这个Variable的反向传播梯度。
E.g.1:通过具体例子来进行说明
import torch
from torch.autograd import Variable
x = Variable(torch.Tensor([1]), requires_grad=True)
w = Variable(torch.Tensor([2]), requires_grad=True)
b = Variable(torch.Tensor([3]), requires_grad=True)
y = w * x + b
y.backward()
print(y.data)
print(y.grad_fn)
print(x.grad)
print(w.grad)
print(b.grad)
构建Variable,要注意得传入一个参数requires_grad=True,这个参数表示是否对这个变量求梯度,默认的是False,也就是不对这个变量求梯度,如果需要这些变量的梯度,那么就要传入这个参数。
上述代码中的y.backward(),这一行代码就是所谓的自动求导,这其实等价于y.backward(torch.FloatTensor([1])),只不过对于标量求导里面的参数写不写都行。自动求导不需要再去明确地写明哪个函数对哪个函数求导,直接通过这行代码就能对所有的需要梯度的变量进行求导,得到它们的梯度,然后通过x.grad可以得到x的梯度。
E.g.2: 对矩阵求导
import torch
from torch.autograd import Variable
x = torch.Tensor([2,3,4])
x = Variable(x, requires_grad=True)
y = x * 2
print(y)
y.backward(torch.FloatTensor([1, 0.1, 0.01]))
print(x.grad)
代码相当于给出了一个三维向量去做运算,这时得到的结果y就是一个向量,这里对这个向量求导就不能直接写成y.backward(),这样程序会报错。这个时候需要传入参数声明,比如y.backward(torch.FloatTensor([1, 1, 1])),这样得到的结果就是它们每个分量的梯度,或者可以传入y.backward(torch.FloatTensor([1, 0.1, 0.01])),这样得到的梯度就是它们原本的梯度分别乘上1,0.1,0.01。
总结
至此,对PyTorch框架的基本元素Tensor有了一定的了解,包括Tensor的创建、类型转换、和Numpy之间的转换,以及GPU和CPU上的转换; 对变量也有了一定的了解,主要是在Tensor的基础上多了requires_grad=True,来完成自动求导的功能。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)