两类深度学习框架的优缺点 动态图(PyTorch) 计算图的进行与代码的运行时同时进行的。 静态图(Tensorflow <2.0) 自建命名体系 自建时序控制 难以介入 使用深度学习框架的优点 GPU 加速 (cuda) 自动求导 常用网络层的API PyTorch 的特点 支持 GPU 动态神经网络 Python 优先 命令式体验 轻松扩展
1.Pytorch简介 Pytorch是Facebook 的 AI 研究团队发布了一个基于 Python的科学计算包,旨在服务两类场合: 替代numpy发挥GPU潜能(在线环境暂时不支持GPU) 一个提供了高度灵活性和效率的深度学习实验性平台 2.Pytorch特点及优势 2.1 Pytorch特点 PyTorch 提供了运行在 GPU/CPU 之上、基础的张量操作库; 可以内置的神经网络库; 提供模型训练功能; 支持共享内存的多进程并发(multiprocessing )库等; 2.2 Pytorch特点 处于机器学习第一大语言 Python 的生态圈之中,使得开发者能使用广大的 Python 库和软件;如 NumPy、SciPy 和 Cython(为了速度把 Python 编译成 C 语言); (最大优势)改进现有的神经网络,提供了更快速的方法——不需要从头重新构建整个网络,这是由于 PyTorch 采用了动态计算图(dynamic computational graph)结构,而不是大多数开源框架(TensorFlow、Caffe、CNTK、Theano 等)采用的静态计算图; 提供工具包,如torch 、torch.nn、torch.optim等; 3.Pytorch常用工具包 torch :类似 NumPy 的张量库,强 GPU 支持 ; torch.autograd :基于 tape 的自动区别库,支持 torch 之中的所有可区分张量运行; torch.nn :为最大化灵活性未涉及、与 autograd 深度整合的神经网络库; torch.optim:与 torch.nn 一起使用的优化包,包含 SGD、RMSProp、LBFGS、Adam 等标准优化方式; torch.multiprocessing: python 多进程并发,进程之间 torch Tensors 的内存共享; torch.utils:数据载入器。具有训练器和其他便利功能; torch.legacy(.nn/.optim) :处于向后兼容性考虑,从 Torch 移植来的 legacy 代码;
pytorch 入门指南
1. pytorch 概述
pytorch是facebook 开发的torch(Lua语言)的python版本,于2017年引爆学术界
官方宣传pytorch侧重两类用户:numpy的gpu版、深度学习研究平台
pytorch使用动态图机制,相比于tensorflow最开始的静态图,更为灵活
当前pytorch支持的系统包括:win,linux,macos
官方宣传pytorch侧重两类用户:numpy的gpu版、深度学习研究平台
pytorch使用动态图机制,相比于tensorflow最开始的静态图,更为灵活
当前pytorch支持的系统包括:win,linux,macos
2. pytorch基本库
常用的pytorch基本库主要包括:
torch: 内含一些常用方法,与numpy比较像
torch.Tensor:内含一些操作tensor的方法,可通过tensor.xx()进行调用
torch.nn:内含一些常用模型,如rnn,cnn等
torch.nn.functional:内含一些常用方法,如sigmoid,softmax等
torch.optim:内含一些优化算法,如sgd,adam等
torch.utils.data:内含一些数据迭代方法
3. 基本操作
a. tensor操作
# 初始化空向量
torch.empty(3,4)
torch.empty(3,4)
# 随机初始化数组
torch.rand(4,3)
torch.rand(4,3)
# 初始化零向量
torch.zeros(4,3, dtype=torch.int)
torch.zeros(4,3, dtype=torch.int)
# 从数据构建数组
x = torch.tensor([3,4],dtype=torch.float)
x = torch.IntTensor([3,4])
x = torch.tensor([3,4],dtype=torch.float)
x = torch.IntTensor([3,4])
# 获取tensor的尺寸,元组
x.shape
x.size()
x.shape
x.size()
# _在方法中的意义:表示对自身的改变
x = torch.ones(3,4)
# 以下三个式子 含义相同
x = x + x
x = torch.add(x, x)
x.add_(x)
x = torch.ones(3,4)
# 以下三个式子 含义相同
x = x + x
x = torch.add(x, x)
x.add_(x)
# 索引,像操作numpy一样
x[:,1]
x[:,1]
# 改变形状
x.view(-1)
x.view(4,3)
x.view(-1)
x.view(4,3)
# 如果只包含一个元素值,获取
x = torch.randn(1)
x.item()
x = torch.randn(1)
x.item()
# 增加一维
input = torch.randn(32, 32)
input = input.unsqueeze(0)
input.size()
input = torch.randn(32, 32)
input = input.unsqueeze(0)
input.size()
# tensor的data还是tensor,但是requires_grad=False
x.data.requires_grad
x.data.requires_grad
# 改变类型
x.type(torch.LongTensor)123456789101112131415161718192021222324252627282930313233343536373839404142434445
x.type(torch.LongTensor)123456789101112131415161718192021222324252627282930313233343536373839404142434445
b. numpy 与 tensor的转换
# 转换, 共享内存
a= numpy.array([1,2,3])
a = torch.from_numpy(a)
a.numpy()1234
a= numpy.array([1,2,3])
a = torch.from_numpy(a)
a.numpy()1234
c. 调用gpu
# gpu是否可用
torch.cuda.is_available()
# 调用设备
device = torch.device('cpu') # cuda or cpu
a = torch.tensor([1,2,3], device='cuda') # 直接在gpu上创建
a = a.to(device) # 上传
a = a.to('cpu') # 上传, cpu or cuda
a = a.cuda() # 上传cuda12345678
torch.cuda.is_available()
# 调用设备
device = torch.device('cpu') # cuda or cpu
a = torch.tensor([1,2,3], device='cuda') # 直接在gpu上创建
a = a.to(device) # 上传
a = a.to('cpu') # 上传, cpu or cuda
a = a.cuda() # 上传cuda12345678
d. 梯度
.requires_grad ,决定是否可微(梯度)
.backward(), 计算梯度;如果单独一个值则不需指定参数,否则需传入权重(尺寸与tensor的size同)
.grad, 用于存储梯度累计值。 只有tensor有梯度值,计算节点没有
.detach(), 相当于新建了一个变量,历史的计算图无效
with torch.no_grad():, 评估模型时可用到,不计算梯度
.grad_fn, 节点是如何产生的;用户创造的tensor([1,2,3]).grad_fn 为None
.data(), tensor值,requires_grad=False
# 创建可微的tensor
x = torch.ones(2,3,requires_grad=True)
# 改变可微性
x.requires_grad_(False)
x.requires_grad_(False)
# 获得梯度值
x = torch.ones(2, 2, requires_grad=True)
y = x +2
z = y * y *3
out = torch.sum(z)
out.backward()
x.grad
x = torch.ones(2, 2, requires_grad=True)
y = x +2
z = y * y *3
out = torch.sum(z)
out.backward()
x.grad
# 无梯度, 报错
with torch.no_grad():
x = torch.ones(2, 2, requires_grad=True)
y = x +2
z = y * y *3
out = torch.sum(z)
out.backward()
x.grad12345678910111213141516171819202122
with torch.no_grad():
x = torch.ones(2, 2, requires_grad=True)
y = x +2
z = y * y *3
out = torch.sum(z)
out.backward()
x.grad12345678910111213141516171819202122
e. 定义模型
两种定义方式
class定义
Sequential定义
# 通过class定义
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
# 下面通过实例变量的形式声明模型内需要学习的参数
self.fc1 = nn.Linear(5, 10)
self.fc2 = nn.Linear(10,20)
def forward(self, x):
# 下面定义计算图
x = self.fc1(x)
x = nn.functional.relu(x)
x = self.fc2(x)
return x
net = Net()
# 下面定义计算图
x = self.fc1(x)
x = nn.functional.relu(x)
x = self.fc2(x)
return x
net = Net()
# 通过Sequential定义
net = Sequential(
nn.Linear(5, 10),
nn.Relu(),
nn.Linear(10, 20)
)12345678910111213141516171819202122
net = Sequential(
nn.Linear(5, 10),
nn.Relu(),
nn.Linear(10, 20)
)12345678910111213141516171819202122
f. 模型参数操作
# 获取模型参数
net.parameters() #可用for 迭代
net.parameters() #可用for 迭代
# 模型内参数梯度清零
net.zero_grad()12345
net.zero_grad()12345
g. 定义损失函数
loss = nn.CrossEntropyLoss()1
h. 定义优化算子
optimizer = optim.SGD(net.parameters(), lr=0.01)1
i. 训练
optimizer.zero_grad() # zero the gradient buffers
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step() 12345
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step() 12345
j. 测试
# 测试
with torch.no_grad():
output = net(input)123
with torch.no_grad():
output = net(input)123
k. 保存与载入
# 模型
torch.save(net, file)
net = torch.load(file)
torch.save(net, file)
net = torch.load(file)
# 参数
torch.save(model.state_dict(), file)
net = Model()
net.load_state_dict(file)12345678
torch.save(model.state_dict(), file)
net = Model()
net.load_state_dict(file)12345678
4. 一个完整的机器学习流程
数据
载入数据
数据处理
构建迭代器
模型
loss
optimizer
新建/载入模型
新建
载入
直接载入模型
载入参数
新建模型
载入模型参数(对于adam等优化器,其参数也需载入)
训练
batch训练
for i, batch in enumerate(dataloader):
x_batch, y_batch = batch
outputs = net(x_batch)
loss = criterion(output, target)
optimizer.zero_grad()
loss.backward()
optimizer.step()1234567
每隔一段时间,打印验证集loss
每隔一段时间,存储模型
测试
x_batch, y_batch = batch
outputs = net(x_batch)
loss = criterion(output, target)
optimizer.zero_grad()
loss.backward()
optimizer.step()1234567
每隔一段时间,打印验证集loss
每隔一段时间,存储模型
测试
载入测试数据
数据处理
构建迭代器(可选)
放入模型,输出结果
计算accuracy
数据处理
构建迭代器(可选)
放入模型,输出结果
计算accuracy