怎么用Pytorch实现ResNet网络构建及模型训练

其他教程   发布日期:2025年03月29日   浏览次数:85

这篇“怎么用Pytorch实现ResNet网络构建及模型训练”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么用Pytorch实现ResNet网络构建及模型训练”文章吧。

构建网络

ResNet由一系列堆叠的残差块组成,其主要作用是通过无限制地增加网络深度,从而使其更加强大。在建立ResNet模型之前,让我们先定义4个层,每个层由多个残差块组成。这些层的目的是降低空间尺寸,同时增加通道数量。

以ResNet50为例,我们可以使用以下代码来定义ResNet网络:

  1. class ResNet(nn.Module):
  2. def __init__(self, num_classes=1000):
  3. super().__init__()
  4. self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)
  5. self.bn1 = nn.BatchNorm2d(64)
  6. self.relu = nn.ReLU(inplace
  7. (续)
  8. 即模型需要在输入层加入一些 normalization 和激活层。
  9. ```python
  10. import torch.nn.init as init
  11. class Flatten(nn.Module):
  12. def __init__(self):
  13. super().__init__()
  14. def forward(self, x):
  15. return x.view(x.size(0), -1)
  16. class ResNet(nn.Module):
  17. def __init__(self, num_classes=1000):
  18. super().__init__()
  19. self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)
  20. self.bn1 = nn.BatchNorm2d(64)
  21. self.relu = nn.ReLU(inplace=True)
  22. self.layer1 = nn.Sequential(
  23. ResidualBlock(64, 256, stride=1),
  24. *[ResidualBlock(256, 256) for _ in range(1, 3)]
  25. )
  26. self.layer2 = nn.Sequential(
  27. ResidualBlock(256, 512, stride=2),
  28. *[ResidualBlock(512, 512) for _ in range(1, 4)]
  29. )
  30. self.layer3 = nn.Sequential(
  31. ResidualBlock(512, 1024, stride=2),
  32. *[ResidualBlock(1024, 1024) for _ in range(1, 6)]
  33. )
  34. self.layer4 = nn.Sequential(
  35. ResidualBlock(1024, 2048, stride=2),
  36. *[ResidualBlock(2048, 2048) for _ in range(1, 3)]
  37. )
  38. self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
  39. self.flatten = Flatten()
  40. self.fc = nn.Linear(2048, num_classes)
  41. for m in self.modules():
  42. if isinstance(m, nn.Conv2d):
  43. init.kaiming_normal_(m.weight, mode="fan_out", nonlinearity="relu")
  44. elif isinstance(m, (nn.BatchNorm2d, nn.GroupNorm)):
  45. init.constant_(m.weight, 1)
  46. init.constant_(m.bias, 0)
  47. def forward(self, x):
  48. x = self.conv1(x)
  49. x = self.bn1(x)
  50. x = self.relu(x)
  51. x = self.layer1(x)
  52. x = self.layer2(x)
  53. x = self.layer3(x)
  54. x = self.layer4(x)
  55. x = self.avgpool(x)
  56. x = self.flatten(x)
  57. x = self.fc(x)
  58. return x

改进点如下:

  • 我们使用

    1. nn.Sequential
    组件,将多个残差块组合成一个功能块(layer)。这样可以方便地修改网络深度,并将其与其他层分离九更容易上手,例如迁移学习中重新训练顶部分类器时。
  • 我们在ResNet的输出层添加了标准化和激活函数。它们有助于提高模型的收敛速度并改善性能。

  • 对于

    1. nn.Conv2d
    和批标准化层等神经网络组件,我们使用了PyTorch中的内置初始化函数。它们会自动为我们设置好每层的参数。
  • 我们还添加了一个

    1. Flatten
    层,将4维输出展平为2维张量,以便通过接下来的全连接层进行分类。

训练模型

我们现在已经实现了ResNet50模型,接下来我们将解释如何训练和测试该模型。

首先我们需要定义损失函数和优化器。在这里,我们使用交叉熵损失函数,以及Adam优化器。

  1. import torch.optim as optim
  2. device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
  3. model = ResNet(num_classes=1000).to(device)
  4. criterion = nn.CrossEntropyLoss()
  5. optimizer = optim.Adam(model.parameters(), lr=0.001)

在使用PyTorch进行训练时,我们通常会创建一个循环,为每个批次的输入数据计算损失并对模型参数进行更新。以下是该循环的代码:

  1. def train(model, optimizer, criterion, train_loader, device):
  2. model.train()
  3. train_loss = 0
  4. correct = 0
  5. total = 0
  6. for batch_idx, (inputs, targets) in enumerate(train_loader):
  7. inputs, targets = inputs.to(device), targets.to(device)
  8. optimizer.zero_grad()
  9. outputs = model(inputs)
  10. loss = criterion(outputs, targets)
  11. loss.backward()
  12. optimizer.step()
  13. train_loss += loss.item()
  14. _, predicted = outputs.max(1)
  15. total += targets.size(0)
  16. correct += predicted.eq(targets).sum().item()
  17. acc = 100 * correct / total
  18. avg_loss = train_loss / len(train_loader)
  19. return acc, avg_loss

在上面的训练循环中,我们首先通过

  1. model.train()
代表进入训练模式。然后使用
  1. optimizer.zero_grad()
清除

以上就是怎么用Pytorch实现ResNet网络构建及模型训练的详细内容,更多关于怎么用Pytorch实现ResNet网络构建及模型训练的资料请关注九品源码其它相关文章!