如何同时使用两个gpu进行猫狗识别训练
时间: 2023-06-13 11:04:49 浏览: 121
使用两个GPU进行猫狗识别训练的方法可以通过数据并行或模型并行来实现。
1. 数据并行
数据并行是将训练数据分配到不同的GPU上,每个GPU上训练一个模型,然后将每个模型的梯度进行平均,从而更新模型参数。
代码示例:
```python
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision.datasets import ImageFolder
from torchvision.transforms import transforms
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 定义模型
model = nn.Sequential(
nn.Conv2d(3, 32, 3, 1, 1),
nn.ReLU(),
nn.MaxPool2d(2, 2),
nn.Conv2d(32, 64, 3, 1, 1),
nn.ReLU(),
nn.MaxPool2d(2, 2),
nn.Flatten(),
nn.Linear(64 * 7 * 7, 128),
nn.ReLU(),
nn.Linear(128, 2)
)
model = nn.DataParallel(model) # 将模型并行化
model.to(device)
# 定义数据处理方式
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
])
# 加载数据
train_dataset = ImageFolder('train/', transform=transform)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True, num_workers=4)
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 训练模型
for epoch in range(10):
running_loss = 0.0
for i, (inputs, labels) in enumerate(train_loader):
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()
if i % 100 == 99:
print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 100))
running_loss = 0.0
```
2. 模型并行
模型并行是将模型的不同部分分配到不同的GPU上,每个GPU上训练部分模型,然后将每个部分的梯度进行传递和合并,从而更新模型参数。
代码示例:
```python
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchvision.datasets import ImageFolder
from torchvision.transforms import transforms
device1 = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
device2 = torch.device("cuda:1" if torch.cuda.is_available() else "cpu")
# 定义模型
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.conv1 = nn.Conv2d(3, 32, 3, 1, 1)
self.relu1 = nn.ReLU()
self.maxpool1 = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(32, 64, 3, 1, 1)
self.relu2 = nn.ReLU()
self.maxpool2 = nn.MaxPool2d(2, 2)
self.flatten = nn.Flatten()
self.linear1 = nn.Linear(64 * 7 * 7, 128)
self.relu3 = nn.ReLU()
self.linear2 = nn.Linear(128, 2)
def forward(self, x):
x = self.conv1(x)
x = self.relu1(x)
x = self.maxpool1(x)
x = self.conv2(x)
x = self.relu2(x)
x = self.maxpool2(x)
x = self.flatten(x)
x = self.linear1(x)
x = self.relu3(x)
x = self.linear2(x)
return x
model1 = nn.Sequential(
nn.DataParallel(Model().to(device1), device_ids=[0, 1])
)
model2 = nn.Sequential(
nn.DataParallel(Model().to(device2), device_ids=[2, 3])
)
# 定义数据处理方式
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
])
# 加载数据
train_dataset = ImageFolder('train/', transform=transform)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=4)
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer1 = optim.Adam(model1.parameters(), lr=0.001)
optimizer2 = optim.Adam(model2.parameters(), lr=0.001)
# 训练模型
for epoch in range(10):
running_loss = 0.0
for i, (inputs, labels) in enumerate(train_loader):
inputs, labels = inputs.to(device1), labels.to(device1)
optimizer1.zero_grad()
optimizer2.zero_grad()
outputs1 = model1(inputs[:, :, :112, :])
inputs = inputs.flip(3)
outputs2 = model2(inputs[:, :, :112, :])
outputs = torch.cat((outputs1, outputs2), dim=0)
labels = torch.cat((labels, labels), dim=0)
loss = criterion(outputs, labels)
loss.backward()
optimizer1.step()
optimizer2.step()
running_loss += loss.item()
if i % 100 == 99:
print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 100))
running_loss = 0.0
```
以上代码均为示例代码,具体实现需要根据具体情况进行修改。