笔记的代码全部是基于Pytorch的,同Tensorflow一样,也是著名的开源深度学习框架(炼丹的优质丹炉),来源于Facebook。个人感觉最近的一年,github上的深度学习开源项目,用Pytorch作为框架的越来越多,尤其是顶会论文的复现项目,更是Pytorch居首,这也体现了框架的发展和本身的优点。
1. 安装
Pytorch官网上已经给出了安装的命令,十分的方便,选择和自己的Python版本以及CUDA版本相匹配的就可以了。
如果没找到匹配的cuda或者python版本,或者想安装旧一点的pytorch,看这里。
注意这里有个小坑,官网给的安装命令里面有个-c pytorch,这里的c指的是channels,也就是指定你要按照官方的源来下载,这样当然是很慢的,搞不好下不下来还会出现HTTP error!所以去掉就行了。如果你之前对conda和pip都换了国内源,那么安装起来还是飞快的(国内源比如换成清华镜像)。
另外还需要方便的IDE来学习和开发,个人推荐PyCharm和jupyter lab,用jupyter lab 学习,用Pycharm开发,美滋滋。Pycharm可以安装免费版也可以安装专业版,专业版在验证学生身份后也是可以免费使用的。
2. 数据的操作
该部分示例来自于《动手学深度学习(Pytorch版)》。感谢项目原作者:项目地址。
关于Pytorch的用法完全可以参照官方文档,十分的详细,而学习Pytorch的最好办法就是在了解一些基本的操作之后通过具体的案例和项目来学习。本节会参照书上内容介绍Pytorch的一些基本操作。
和Numpy的多维数组类似,Pytorch中的torch.Tensor也是存储和变换数据的主要⼯具,且Tensor还提供了GPU计算和⾃动求梯度等更多功能,更方便于深度学习。
2.1 创建Tensor
以下是几个常用的创建Tensor的方法:
import torch #导入Pytorch
x1 = torch.empty(5, 3) #创建⼀个5x3的未初始化的 Tensor
print(x1)
'''
输出:
tensor([[ 0.0000e+00, 1.5846e+29, 0.0000e+00],
[ 1.5846e+29, 5.6052e-45, 0.0000e+00],
[ 0.0000e+00, 0.0000e+00, 0.0000e+00],
[ 0.0000e+00, 0.0000e+00, 0.0000e+00],
[ 0.0000e+00, 1.5846e+29, -2.4336e+02]])
'''
x2 = torch.rand(5, 3) #创建⼀个5x3的随机初始化的 Tensor
print(x2)
'''
输出:
tensor([[0.4963, 0.7682, 0.0885],
[0.1320, 0.3074, 0.6341],
[0.4901, 0.8964, 0.4556],
[0.6323, 0.3489, 0.4017],
[0.0223, 0.1689, 0.2939]])
'''
x3 = torch.zeros(5, 3, dtype=torch.long) #创建5*3的指定为long类型的全零 Tensor
print(x3)
'''
输出:
tensor([[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]])
'''
x4 = torch.tensor([5.5, 3]) #直接根据数来创建
print(x4)
'''
输出:tensor([5.5000, 3.0000])
'''
##可以通过shape 或者 size() 来获取 Tensor 的形状:
print(x3.size())
print(x3.shape)
'''
输出:
torch.Size([5, 3])
torch.Size([5, 3])
'''
更多的创建Tensor方法可以参考官方文档,这些创建⽅法都可以在创建的时候指定数据类型dtype和存放device(cpu/gpu)。
2.2 Tensor运算
关于数据操作,在PyTorch中,同⼀种操作可能有很多种形式,以加法为例:
x = torch.zeros(5, 3)
y = torch.rand(5, 3)
print(x + y)
print(torch.add(x, y))
result = torch.empty(5, 3)
torch.add(x, y, out=result)
print(result)
这三个print出的结果是等价的。
Pytorch中的索引操作和Numpy类似,这⾥不详细介绍,更高级的函数可以参考官方文档,实际上能用到的不多。
2.3 改变 Tensor 形状
Pytorch可以⽤ view() 来改变 Tensor 的形状:
y = x.view(15)
z = x.view(-1, 5) # -1所指的维度可以根据其他维度的值推出来
print(x.size(), y.size(), z.size())
'''
输出:
torch.Size([5, 3]) torch.Size([15]) torch.Size([3, 5])
'''
注意:view() 返回的新tensor与原tensor共享内存(其实是同⼀个tensor),也即更改其中的⼀个,另外⼀个也会跟着改变。 (顾名思义, view仅仅是改变了对这个张量的观察⻆度)
2.4 Tensor与其他类型的转换
另外⼀个常⽤的函数就是 item() , 它可以将⼀个标量 Tensor 转换成⼀个Python number:
x = torch.randn(1)
print(x)
print(x.item())
'''
输出:
tensor([2.3466])
2.3466382026672363
'''
Tensor和Numpy的互换:我们很容易⽤numpy() 和 from_numpy() 将 Tensor 和NumPy中的数组相互转换。但是需要注意的⼀点是: 这两个函数所产⽣的的 Tensor 和NumPy中的数组共享相同的内存(所以他们之间的转换很快),改变其中⼀个时另⼀个也会改变!
#numpy()函数用于将 Tensor 转换成NumPy数组
a = torch.ones(5)
b = a.numpy()
print(a, b)
a += 1
print(a, b)
b += 1
print(a, b)
'''
输出:
tensor([1., 1., 1., 1., 1.]) [1. 1. 1. 1. 1.]
tensor([2., 2., 2., 2., 2.]) [2. 2. 2. 2. 2.]
tensor([3., 3., 3., 3., 3.]) [3. 3. 3. 3. 3.]
'''
#from_numpy()函数 将NumPy数组转换成 Tensor
import numpy as np
a = np.ones(5)
b = torch.from_numpy(a)
print(a, b)
a += 1
print(a, b)
b += 1
print(a, b)
'''
输出:
[1. 1. 1. 1. 1.] tensor([1., 1., 1., 1., 1.], dtype=torch.float64)
[2. 2. 2. 2. 2.] tensor([2., 2., 2., 2., 2.], dtype=torch.float64)
[3. 3. 3. 3. 3.] tensor([3., 3., 3., 3., 3.], dtype=torch.float64)
'''
##此外上⾯提到还有⼀个常⽤的⽅法就是直接⽤ torch.tensor() 将NumPy数组转换成 Tensor ,需要注意的是该⽅法总是会进⾏数据拷⻉,返回的 Tensor 和原##来的数据不再共享内存。
2.5 Tensor的CPU,GPU切换
⽤⽅法 to() 可以将 Tensor 在CPU和GPU(需要硬件⽀持)之间相互移动。
# 以下代码只有在PyTorch GPU版本上才会执⾏
if torch.cuda.is_available():
device = torch.device("cuda") # GPU
y = torch.ones_like(x, device=device) # 直接创建⼀个在GPU上的
Tensor
x = x.to(device) # 等价于 .to("cuda")
z = x + y
print(z)
print(z.to("cpu", torch.double)) # to()还可以同时更改数据类型