PyTorch中的CPU和GPU代码实现详解

PyTorch中的CPU和GPU代码实现详解

在深度学习的开发过程中,计算资源的高效利用是至关重要的。PyTorch作为一种流行的深度学习框架,支持使用CPUGPU进行模型训练和推理。相较于CPU,GPU由于其强大的并行计算能力,能够显著加速深度学习任务。然而,将PyTorch代码从CPU版本迁移到GPU版本需要进行一些额外的代码修改。本文将详细介绍如何在PyTorch中编写支持CPU和GPU的代码,以及需要特别注意的事项。

1. 安装PyTorch

首先,确保你已经安装了支持GPU的PyTorch版本。如果还没有安装,可以参考以下命令进行安装:

# For CUDA 11.1
pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu111

2. 编写支持CPU和GPU的PyTorch代码

2.1模型定义

定义模型的代码在CPU和GPU版本中基本一致。但是,我们需要确保模型可以在GPU上运行。

import torch
import torch.nn as nn
import torch.optim as optim

class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()
        self.fc = nn.Linear(784, 10)

    def forward(self, x):
        return self.fc(x)

model = SimpleNN()

2.2数据加载

数据加载部分对于CPU和GPU是相同的。使用DataLoader类加载数据:

在这里插入代码片from torchvision import datasets, transforms

transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])

trainset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True)

2.3 将模型和数据移动到GPU

在PyTorch中,模型和数据需要显式地移动到GPU上。使用.to(device)方法将模型和数据移动到指定设备(CPU或GPU)上。

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

2.4 训练循环

在训练循环中,我们需要确保输入数据和标签也被移动到GPU上。

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

for epoch in range(5):
    running_loss = 0.0
    for inputs, labels in trainloader:
        inputs, labels = inputs.to(device), labels.to(device)

        optimizer.zero_grad()

        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
    print(f"Epoch {epoch+1}, Loss: {running_loss/len(trainloader)}")

3. 关键步骤详解

3.1 定义设备

使用torch.device定义设备,根据当前环境选择使用CPU或GPU。

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

3.2 模型和数据移动到GPU

将模型和数据显式地移动到GPU上。这一步是关键,没有这一步,模型和数据仍然会在CPU上进行计算。

model.to(device)
inputs, labels = inputs.to(device), labels.to(device)

3.3 优化器和损失函数

优化器和损失函数在CPU和GPU版本中不需要特殊处理,它们会自动适应模型所在的设备。

4. 完整代码示例

以下是完整的代码示例,包括从数据加载到训练循环的所有步骤。

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms

# 定义设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# 定义模型
class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()
        self.fc = nn.Linear(784, 10)

    def forward(self, x):
        return self.fc(x)

model = SimpleNN().to(device)

# 数据加载
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
trainset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True)

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)

# 训练循环
for epoch in range(5):
    running_loss = 0.0
    for inputs, labels in trainloader:
        inputs, labels = inputs.to(device), labels.to(device)

        optimizer.zero_grad()

        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
    print(f"Epoch {epoch+1}, Loss: {running_loss/len(trainloader)}")
    

5. 结论

通过本文的详细讲解,我们了解了如何在PyTorch中编写支持CPU和GPU的代码。重点在于将模型和数据显式地移动到GPU上,并确保训练循环中的每一步都在正确的设备上进行计算。掌握这些技巧后,你可以充分利用GPU的强大计算能力,加速深度学习模型的训练和推理过程。

  • 14
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PointNet2是一个用于点云分类和语义分割的神经网络模型,是PointNet的升级版。Pytorch是一个基于Python的科学计算框架,广泛应用于深度学习领域。下面对PointNet2的Pytorch版本代码进行详解。 1.数据预处理 首先,需要对输入的点云数据进行预处理。在Pytorch版本的PointNet2,点云数据是以numpy数组的形式输入的,需要进行归一化和随机打乱顺序的操作。代码如下: ```python def provider(): ...... for i in range(len(batch_data)): # 数据归一化 batch_data[i, :, :3] = pc_normalize(batch_data[i, :, :3]) # 随机打乱顺序 batch_data[i, :, :] = random_scale_point_cloud(batch_data[i, :, :]) batch_data[i, :, :] = random_shift_point_cloud(batch_data[i, :, :]) batch_data[i, :, :] = random_rotate_point_cloud(batch_data[i, :, :]) batch_data[i, :, :] = jitter_point_cloud(batch_data[i, :, :]) ...... ``` 其,pc_normalize函数用于归一化点云数据,random_scale_point_cloud、random_shift_point_cloud、random_rotate_point_cloud和jitter_point_cloud函数用于随机打乱点云数据的顺序。 2.构建模型 在Pytorch版本的PointNet2,模型的构建使用了Pytorch的nn.Module类,可以方便地进行模型的组合和优化。代码如下: ```python class PointNet2ClsMsg(nn.Module): def __init__(self, input_channels=0, use_xyz=True): super().__init__() self.input_channels = input_channels self.use_xyz = use_xyz self.sa1 = PointNetSetAbstractionMsg(512, [0.1, 0.2, 0.4], [32, 64, 128], input_channels, use_xyz) self.sa2 = PointNetSetAbstractionMsg(128, [0.4, 0.8], [128, 256], self.sa1.out_channels, use_xyz) self.sa3 = PointNetSetAbstractionMsg(None, None, [512, 1024], self.sa2.out_channels, use_xyz) self.fc1 = nn.Linear(1024, 512) self.bn1 = nn.BatchNorm1d(512) self.drop1 = nn.Dropout(0.5) self.fc2 = nn.Linear(512, 256) self.bn2 = nn.BatchNorm1d(256) self.drop2 = nn.Dropout(0.5) self.fc3 = nn.Linear(256, 40) def forward(self, xyz, points): l1_xyz, l1_points = self.sa1(xyz, points) l2_xyz, l2_points = self.sa2(l1_xyz, l1_points) l3_xyz, l3_points = self.sa3(l2_xyz, l2_points) x = l3_points.view(l3_points.size()[0], -1) x = F.relu(self.bn1(self.fc1(x))) x = self.drop1(x) x = F.relu(self.bn2(self.fc2(x))) x = self.drop2(x) x = self.fc3(x) x = F.log_softmax(x, -1) return x ``` 在这个模型,使用了三个PointNetSetAbstractionMsg模块和三个全连接层,其PointNetSetAbstractionMsg是PointNet2的一个基础模块。在这个模型,首先通过PointNetSetAbstractionMsg模块对输入的点云数据进行特征提取,然后通过全连接层将提取的特征映射到输出空间。最后,通过log_softmax函数将输出转化为概率分布。 3.定义损失函数和优化器 在Pytorch版本的PointNet2,使用交叉熵损失函数和Adam优化器进行训练。代码如下: ```python criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4) ``` 其,nn.CrossEntropyLoss是Pytorch的交叉熵损失函数,optim.Adam是Pytorch的Adam优化器,lr表示学习率,weight_decay表示L2正则化参数。 4.模型训练 在Pytorch版本的PointNet2,模型训练的流程与Pytorch的通用模型训练流程相似,包括前向传播、计算损失、反向传播和参数更新等步骤。代码如下: ```python for epoch in range(num_epochs): train_loss = 0.0 train_correct = 0 train_total = 0 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[:, :, :3], data) loss = criterion(output, target) loss.backward() optimizer.step() train_loss += loss.item() _, predicted = output.max(1) train_total += target.size(0) train_correct += predicted.eq(target).sum().item() train_acc = 100. * train_correct / train_total train_loss /= train_total print('Train Epoch: {} | Loss: {:.4f} | Acc: {:.4f}'.format( epoch, train_loss, train_acc)) ``` 其,train_loader是Pytorch的数据加载器,用于进行数据批量加载,device表示使用的设备(CPUGPU)。在训练过程,首先将数据和标签转移到指定的设备上,然后进行前向传播、计算损失、反向传播和参数更新等操作。最后,输出每个epoch的训练损失和准确率。 5.模型测试 在Pytorch版本的PointNet2,模型测试的流程与模型训练的流程类似,也需要进行数据加载、前向传播和输出预测结果等操作。代码如下: ```python model.eval() with torch.no_grad(): for batch_idx, (data, target) in enumerate(test_loader): data, target = data.to(device), target.to(device) output = model(data[:, :, :3], data) _, predicted = output.max(1) # 输出预测结果 print(predicted) ``` 在测试过程,需要将模型设置为eval模式,关闭梯度计算,然后进行前向传播和输出预测结果等操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值