Pytorch学习(四)GPU上使用神经网络及数据并行处理

CUDA

官方教程
首先将神经网络转到GPU上,前提条件是CUDA可以用。所以我们需要进行检测。

import torch
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)

如果CUDA可用输出cuda:0,不可用则输出cpu

使用多GPU数据并行

首先需要数据

1.定义一些参数
#定义参数
input_size = 5
output_size = 2
batch_size = 30
data_size = 100
#CUDA设备
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
2.制作一个数据集

这里我们使用randn创建随机数据集,并将这些数据使用DataLoader封装成30大小的Tensor用于训练。
该接口的目的:将自定义的Dataset根据batch size大小、是否shuffle等封装成一个Batch Size大小的Tensor,用于后面的训练。

#创建一个随机数据集,制作假数据
class RandomDataset(Dataset):
    def __init__(self, size, length):
        self.len = length
        self.data = torch.randn(length, size)
    def __getitem__(self, index):
        return self.data[index]
    def __len__(self):
        return self.len
#随机数集,shffule=True在表示不同批次的数据遍历时,打乱顺序,每份30个数据
rand_loader = DataLoader(dataset=RandomDataset(input_size, data_size), batch_size=batch_size, shuffle=True)

定义神经网络建立模型

这里我们定义一个很简单的神经网络,模型仅获得输入,执行线性运算并给出输出。在模型中放置了一条打印语句,以监视输入和输出张量的大小。请注意批次等级0上打印的内容。

class Model(nn.Module):
        #定义net的初始化函数,这个函数定义了该神经网络的基本结构
	def __init__(self, input_size, output_size):
	        #复制并使用Net的父类的初始化方法,即先运行nn.Module的初始化函数
		super(Model, self).__init__()
		#定义fc(fullconnect)全连接函数为线性函数:y = Wx + b,并将5个节点连接到2个节点上。
		self.fc = nn.Linear(input_size, output_size)
	#定义该神经网络的向前传播函数,该函数必须定义,一旦定义成功,向后传播函数也会自动生成(autograd)
	def forward(self, input):
	        #输入input经过全连接函数fc后,更新output
		output = self.fc(input)
		#打印input和output的大小
		print("\t In Model: input size", input.size(), "output size", output.size())
		return output

新建网络并实现数据并行化,PyTorch默认只使用一个GPU,可以使用DataParallel来实现使用多个GPUmodel = nn.DataParallel(model)
调用model.to(device)返回的是一个model新的备份,而不是重写了model. 需要将其分配到一个新的张量,并在GPU上使用这个张量.

#建一个模型实例
model = Model(input_size, output_size)
#是否有多个GPU
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
   #PyTorch默认只使用一个GPU,使用DataParallel来实现使用多个GPU
   model = nn.DataParallel(model)
else:print("only one")
#将模型放入GPU
model.to(device)

这里遇到了问题,我的电脑明明有两个GPU,但是torch.cuda.device_count()只显示有一个。
运行后输出

only one

但是任务管理器中显示我有两个GPU
在这里插入图片描述
待解决。相同问题

运行模型

具体代码和注释如下

#遍历我们随机产生的数据集
for data in rand_loader:
    #将数据放入GPU中,赋值给input
    input = data.to(device)
    #将input投入模型更新output
    output = model(input)
    #打印input和output的大小
    print("Outside: input size", input.size(),
          "output_size", output.size())

在GPU上训练神经网络时,需要在网络模型定义好后放入GPU中net.to(device),这个方法将递归遍历所有模块,并将其参数和缓冲区都转换为CUDA张量。然后要将每一步的输入和数据都放入GPU中,比如在训练网络时,每一次获取数据后,都要inputs, labels = data[0].to(device), data[1].to(device)

本文模型运行结果(只有一个GPU)

D:\Python\python.exe C:/Users/465/Desktop/try/通信/test.py
only one
  In Model: input size torch.Size([30, 5]) output size torch.Size([30, 2])
Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
  In Model: input size torch.Size([30, 5]) output size torch.Size([30, 2])
Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
  In Model: input size torch.Size([30, 5]) output size torch.Size([30, 2])
Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
  In Model: input size torch.Size([10, 5]) output size torch.Size([10, 2])
Outside: input size torch.Size([10, 5]) output_size torch.Size([10, 2])

30是batch_size = 30每份是30个数据,5和2是self.fc = nn.Linear(input_size, output_size)将5个节点连接到了2个节点上。总共有data_size = 100个数据。

如果有两个GPU

# on 2 GPUs
Let's use 2 GPUs!
    In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
    In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
    In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
    In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
    In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
    In Model: input size torch.Size([15, 5]) output size torch.Size([15, 2])
Outside: input size torch.Size([30, 5]) output_size torch.Size([30, 2])
    In Model: input size torch.Size([5, 5]) output size torch.Size([5, 2])
    In Model: input size torch.Size([5, 5]) output size torch.Size([5, 2])
Outside: input size torch.Size([10, 5]) output_size torch.Size([10, 2])

DataParallel会自动分割数据,并将作业订单发送到多个GPU上的多个模型。每个模型完成工作后,DataParallel会收集并合并结果,然后再将结果返回。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值