pytorch 多GPU训练

时间:2018年1月19

pytorch多GPU最终还是没搞通,可用的部分是前向计算,back propagation会出错,当时运行通过,也不太确定是如何通过了的。目前是这样,有机会再来补充

时间:2018年1月17

pytorch支持多GPU训练,官方文档(pytorch 0.30)给了一些说明:pytorch数据并行,但遗憾的是给出的说明并不详细。不过说的还是蛮清楚的,建议使用DataParallel。

pytorch使用多GPU训练的时候要考虑的主要的不过是前向计算和后向计算两个部分。

前向计算:

net = Net() #Net是自定义的一个网络结构类
device_ids = [2, 4, 5]
cudnn.benchmark = True
net = net.cuda(device_ids[0])
net = nn.DataParallel(net, device_ids=device_ids) #使用dataParallel重新包装一下
Dataparallel会把输入数据以某个轴(默认是 0 轴)将数据分开成平均几份,所以要保证batch size每一个批中的图片数目是相对于用到的GPU可除的。等调用net结束后,将再次把分开运算得到的数据自动组合在一起。

后向计算:

神经网络还需要后向计算以更新梯度,因为grad_fn在dataparallel中,所以也要将更新梯度的方法放入到dataparallel中去。
lr = 1e-2
momentum = 0.9
weight_decay = 1e-3
param = get_param(net, lr)
optimizer = optim.SGD(param, momentum=momentum, weight_decay=weight_decay) #准备pytorch中的随机梯度下降方法
loss = nn.MSEloss() 
optimizer = nn.DataParallel(optimizer, device_ids=device_ids) #将optimizer放入dataparallel中。

DataParallel的使用:

img = Variable(img, requires_grad=True).cuda(device_ids[0])  # 输入图片数据
gt = Variable(gt_heatmap).cuda(device_ids[0]) #ground truth

predicted = net(img) # net是DataParallel对象,img 作为输入会将分为3份(bachsize/3),等3个并行计算结束后再以该轴组合再一起,predicted和img的shape是一样的。
l = loss(gt, predicted) 

# compute gradient and do SGD step
optimizer.zero_grad() 
l.backward() #在这儿使用optimizer的相应的对象。
optimizer.module.step() #因为它在DataParallel里面,所以要先变成普通的nn.SGD对象,然后才能调用该类的梯度更新方法。类似的,还有其他的一些需要注意的地方,看下面:

相应的学习率更新的方法:

for param_lr in optimizer.module.param_groups: #同样是要加module
    param_lr['lr'] /= 2

加载保存的网络参数:

加载保存的网络参数时也要注意,因为所有的保存的参数对应的关键字都加了module。可以像下面这样使用序号的方式重新加载所保存的网络参数。

model_dict = net.state_dict()
vgg_19_key = list(vgg_19.keys())
model_key = list(model_dict.keys())
from collections import OrderedDict
vgg_dict = OrderedDict()
for i in range(param_num):
    vgg_dict[model_key[i]] = vgg_19[vgg_19_key[i]]
model_dict.update(vgg_dict)

也可以简单的去掉OrderedDict关键字多出的module,像这样:

for item, value in saved_state.items():
    name = '.'.join(item.split('.')[1:])
    trans_param[name] = value
像这样就可以实现pytorch多GPU训练网络了。








  • 6
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
以下是使用 PyTorch 进行多 GPU 训练的示例代码: ```python import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader from torchvision.datasets import CIFAR10 from torchvision.transforms import transforms # 定义模型 class Net(nn.Module): def __init__(self): super(Net, 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(torch.relu(self.conv1(x))) x = self.pool(torch.relu(self.conv2(x))) x = x.view(-1, 16 * 5 * 5) x = torch.relu(self.fc1(x)) x = torch.relu(self.fc2(x)) x = self.fc3(x) return x # 定义训练函数 def train(model, device, train_loader, optimizer, criterion): model.train() for batch_idx, (data, target) in enumerate(train_loader): data, target = data.to(device), target.to(device) optimizer.zero_grad() output = model(data) loss = criterion(output, target) loss.backward() optimizer.step() # 定义测试函数 def test(model, device, test_loader, criterion): model.eval() test_loss = 0 correct = 0 with torch.no_grad(): for data, target in test_loader: data, target = data.to(device), target.to(device) output = model(data) test_loss += criterion(output, target).item() pred = output.argmax(dim=1, keepdim=True) correct += pred.eq(target.view_as(pred)).sum().item() test_loss /= len(test_loader.dataset) accuracy = 100. * correct / len(test_loader.dataset) print('Test set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)'.format( test_loss, correct, len(test_loader.dataset), accuracy)) # 定义主函数 def main(): # 设置超参数 batch_size = 128 epochs = 10 lr = 0.01 momentum = 0.9 num_workers = 4 num_gpus = torch.cuda.device_count() # 加载数据集 transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) ]) train_dataset = CIFAR10(root='./data', train=True, download=True, transform=transform) test_dataset = CIFAR10(root='./data', train=False, download=True, transform=transform) train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=num_workers) test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False, num_workers=num_workers) # 初始化模型和优化器 model = Net() if num_gpus > 1: model = nn.DataParallel(model) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model.to(device) optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum) criterion = nn.CrossEntropyLoss() # 训练和测试 for epoch in range(1, epochs + 1): train(model, device, train_loader, optimizer, criterion) test(model, device, test_loader, criterion) if __name__ == '__main__': main() ``` 这个示例代码可以在多个 GPU 上并行训练模型,如果只有一个 GPU,可以将 `num_gpus` 设置为 1。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值