Pytorch
参考资料
简介
PyTorch是一个基于Python的科学计算包,它主要有两个用途:
类似Numpy但是能利用GPU加速
一个非常灵活和快速的用于深度学习的研究平台
组成
torch torch.autograd torch.nn torch.optim 各种更新权重的方法,如梯度下降、Adam torch.multiprocessing torch.legacy
Tensor
torch.Tensor是这个包的核心类。
x = torch.empty(5, 3) # 未初始化矩阵
x = torch.rand(5, 3)
x = torch.zeros(5, 3, dtype=torch.long)
x = torch.ones(2, 2, requires_grad=True)
# 如果设置它的属性 .requires_grad为True,那么它将会追踪对于该张量的所有操作。
y = x + 2
# tensor([[3., 3.],
# [3., 3.]], grad_fn=<AddBackward0>)
# 广播机制
通过grad_fn属性可以跟踪反向传播过程。
神经网络
torch.nn函数。
nn.Module包含各个层以及一个forward()方法
一个神经网络的典型训练过程如下:
- 定义包含一些可学习参数(或者叫权重)的神经网络
- 在输入数据集上迭代
- 通过网络处理输入
- 计算损失(输出和正确答案的距离)
- 将梯度反向传播给网络的参数
- 更新网络的权重,一般使用一个简单的规则:weight = weight - learning_rate * gradient
实例
import torch
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
# 输入图像channel:1;输出channel:6;5x5卷积核
self.conv1 = nn.Conv2d(1, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
# 仿射变换:y = Wx + b
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
# 2x2 Max pooling
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
# If the size is a square you can only specify a single number
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
x = x.view(-1, self.num_flat_features(x))
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
def num_flat_features(self, x):
size = x.size()[1:] # 除去批大小维度的其余维度
num_features = 1
for s in size:
num_features *= s
return num_features
net = Net()
print(net)
使用者负责定义forward函数,backward函数会自动被定义。
可以通过net.parameters()返回一个模型的可学习参数。
损失函数
损失函数接受一对(output, target)作为输入,计算一个值来估计网络输出结果与目标值相关多少。
例如:
- nn.MSELoss()
更新权重
最常见的是使用梯度下降法。也可以使用Adam。
import torch.optim as optim
## 创建优化器(optimizer)
optimizer = optim.SGD(net.parameters(), lr=0.01)
## 在训练的迭代中:
optimizer.zero_grad() # 清零梯度缓存
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step() # 更新参数
参考资料
简介
PyTorch是一个基于Python的科学计算包,它主要有两个用途:
类似Numpy但是能利用GPU加速
一个非常灵活和快速的用于深度学习的研究平台
组成
torch torch.autograd torch.nn torch.optim 各种更新权重的方法,如梯度下降、Adam torch.multiprocessing torch.legacy
Tensor
torch.Tensor是这个包的核心类。
x = torch.empty(5, 3) # 未初始化矩阵
x = torch.rand(5, 3)
x = torch.zeros(5, 3, dtype=torch.long)
x = torch.ones(2, 2, requires_grad=True)
# 如果设置它的属性 .requires_grad为True,那么它将会追踪对于该张量的所有操作。
y = x + 2
# tensor([[3., 3.],
# [3., 3.]], grad_fn=<AddBackward0>)
# 广播机制
通过grad_fn属性可以跟踪反向传播过程。
神经网络
torch.nn函数。
nn.Module包含各个层以及一个forward()方法
一个神经网络的典型训练过程如下:
- 定义包含一些可学习参数(或者叫权重)的神经网络
- 在输入数据集上迭代
- 通过网络处理输入
- 计算损失(输出和正确答案的距离)
- 将梯度反向传播给网络的参数
- 更新网络的权重,一般使用一个简单的规则:weight = weight - learning_rate * gradient
实例
import torch
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
# 输入图像channel:1;输出channel:6;5x5卷积核
self.conv1 = nn.Conv2d(1, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
# 仿射变换:y = Wx + b
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
# 2x2 Max pooling
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
# If the size is a square you can only specify a single number
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
x = x.view(-1, self.num_flat_features(x))
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
def num_flat_features(self, x):
size = x.size()[1:] # 除去批大小维度的其余维度
num_features = 1
for s in size:
num_features *= s
return num_features
net = Net()
print(net)
使用者负责定义forward函数,backward函数会自动被定义。
可以通过net.parameters()返回一个模型的可学习参数。
损失函数
损失函数接受一对(output, target)作为输入,计算一个值来估计网络输出结果与目标值相关多少。
例如:
- nn.MSELoss()
更新权重
最常见的是使用梯度下降法。也可以使用Adam。
import torch.optim as optim
## 创建优化器(optimizer)
optimizer = optim.SGD(net.parameters(), lr=0.01)
## 在训练的迭代中:
optimizer.zero_grad() # 清零梯度缓存
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step() # 更新参数
参考资料
- Pytorch 官方文档
- pytorch官方教程中文版
- PyTorch简明教程
- w3cschool
- w3cschool
- 深入浅出PyTorch 主要
- 资源 此处列出更多相关的资源
简介
PyTorch是一个基于Python的科学计算包,它主要有两个用途:
类似Numpy但是能利用GPU加速
一个非常灵活和快速的用于深度学习的研究平台
本文内容
- PyTorch基础知识,如张量
- 如何使用现存模型
- 如何使用PyTorch搭建一个模型
- 如何读取数据
- 评估一个模型所需要的必备条件,如optimizer,如损失函数
- 如何使用PyTorch训练模型
- 如何使用GPU
- 其他内容
安装PyTorch
基础知识
组成
torch torch.autograd torch.nn torch.optim 各种更新权重的方法,如梯度下降、Adam torch.multiprocessing torch.legacy
Tensor
torch.Tensor是这个包的核心类。
x = torch.empty(5, 3) # 未初始化矩阵
x = torch.rand(5, 3)
x = torch.zeros(5, 3, dtype=torch.long)
x = torch.ones(2, 2, requires_grad=True)
# 如果设置它的属性 .requires_grad为True,那么它将会追踪对于该张量的所有操作。
y = x + 2
# tensor([[3., 3.],
# [3., 3.]], grad_fn=<AddBackward0>)
# 广播机制
通过grad_fn属性可以跟踪反向传播过程。
如何搭建模型?
torch.nn函数。
nn.Module包含各个层以及一个forward()方法
一个神经网络的典型训练过程如下:
- 定义包含一些可学习参数(或者叫权重)的神经网络
- 在输入数据集上迭代
- 通过网络处理输入
- 计算损失(输出和正确答案的距离)
- 将梯度反向传播给网络的参数
- 更新网络的权重,一般使用一个简单的规则:weight = weight - learning_rate * gradient
实例
构建以下一个模型:
import torch
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
# 输入图像channel:1;输出channel:6;5x5卷积核
self.conv1 = nn.Conv2d(1, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
# 仿射变换:y = Wx + b
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
# 2x2 Max pooling
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
# If the size is a square you can only specify a single number
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
x = x.view(-1, self.num_flat_features(x))
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
def num_flat_features(self, x):
size = x.size()[1:] # 除去批大小维度的其余维度
num_features = 1
for s in size:
num_features *= s
return num_features
net = Net()
print(net)
使用者负责定义forward函数,backward函数会自动被定义。
可以通过net.parameters()返回一个模型的可学习参数。
评估模型
损失函数
损失函数接受一对(output, target)作为输入,计算一个值来估计网络输出结果与目标值相关多少。
例如:
- nn.MSELoss()
优化器
最常见的是使用梯度下降法。也可以使用Adam。
import torch.optim as optim
## 创建优化器(optimizer)
optimizer = optim.SGD(net.parameters(), lr=0.01)
## 在训练的迭代中:
optimizer.zero_grad() # 清零梯度缓存
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step() # 更新参数
训练模型
model.train() # 训练状态
model.eval() # 验证/测试状态
一个完整的训练过程如下(以图像分类为例):
def train(epoch):
model.train()
train_loss = 0
for data, label in train_loader:
data, label = data.cuda(), label.cuda()
optimizer.zero_grad()
output = model(data)
loss = criterion(output, label)
loss.backward()
optimizer.step()
train_loss += loss.item()*data.size(0)
train_loss = train_loss/len(train_loader.dataset)
print('Epoch: {} \tTraining Loss: {:.6f}'.format(epoch, train_loss))
对应的验证过程如下:
def val(epoch):
model.eval()
val_loss = 0
with torch.no_grad():
for data, label in val_loader:
data, label = data.cuda(), label.cuda()
output = model(data)
preds = torch.argmax(output, 1)
loss = criterion(output, label)
val_loss += loss.item()*data.size(0)
running_accu += torch.sum(preds == label.data)
val_loss = val_loss/len(val_loader.dataset)
print('Epoch: {} \tTraining Loss: {:.6f}'.format(epoch, val_loss))
保存/加载模型
- torch.save 使用python的pickle模块进行序列化
- torch.load 使用unpickling
- torch.nn.Module.load_state_dict:使用反序列化函数 state_dict 来加载模型的参数字典。
state dict
# 定义模型
class TheModelClass(nn.Module):
def __init__(self):
super(TheModelClass, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 16 * 5 * 5)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
# 初始化模型
model = TheModelClass()
# 初始化优化器
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
# 打印模型的状态字典
print("Model's state_dict:")
for param_tensor in model.state_dict():
print(param_tensor, "\t", model.state_dict()[param_tensor].size())
# 打印优化器的状态字典
print("Optimizer's state_dict:")
for var_name in optimizer.state_dict():
print(var_name, "\t", optimizer.state_dict()[var_name])
保存与加载
#保存模型权重
torch.save(model.state_dict(), PATH)
#加载state dict
model = TheModelClass(*args, **kwargs)
model.load_state_dict(torch.load(PATH))
model.eval() #设置 dropout 和 batch normalization 层为评估模式。如果不这么做,可能导致 模型推断结果不一致。
也可以保存/加载完整模型
# 保存
torch.save(model.state_dict(), PATH)
# 加载
model = TheModelClass(*args, **kwargs)
model.load_state_dict(torch.load(PATH))
model.eval()
数据并行处理(使用GPU)
device = torch.device("cuda: 0")
# 复制模型到GPU上
model.to(device)
# 复制张量到GPU上
mytensor = my_tensor.to(device)
# 模型并行
model = nn.DataParallel(model)
model = Model(input_size, output_size)
if torch.cuda.device_count() > 1:
print("Let's use", torch.cuda.device_count(), "GPUs!")
# dim = 0 [30, xxx] -> [10, ...], [10, ...], [10, ...] on 3 GPUs
model = nn.DataParallel(model)
model.to(device)
单卡与多卡模型模型存储的区别:
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0' # 如果是多卡改成类似0,1,2
model = model.cuda() # 单卡
model = torch.nn.DataParallel(model).cuda() # 多卡