基于pytorch搭建resnet模型的步骤
时间: 2023-07-11 08:12:03 浏览: 79
好的,下面是基于PyTorch搭建ResNet模型的步骤:
1. 导入必要的库和模块
```python
import torch.nn as nn
```
2. 定义ResNet的基本模块
ResNet的基本模块是BasicBlock,包含两个卷积层和一个shortcut连接。其中,shortcut连接可以是一个恒等映射或者一个1×1卷积层。这里我们使用恒等映射作为shortcut连接。
```python
class BasicBlock(nn.Module):
expansion = 1
def __init__(self, in_planes, planes, stride=1):
super(BasicBlock, self).__init__()
self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(planes)
self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(planes)
self.shortcut = nn.Sequential()
if stride != 1 or in_planes != self.expansion*planes:
self.shortcut = nn.Sequential(
nn.Conv2d(in_planes, self.expansion*planes, kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(self.expansion*planes)
)
def forward(self, x):
out = nn.ReLU()(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
out += self.shortcut(x)
out = nn.ReLU()(out)
return out
```
3. 定义ResNet的整体结构
ResNet的整体结构由多个BasicBlock组成,包含一个卷积层、一个BatchNorm层、四个BasicBlock层、一个全局平均池化层和一个全连接层。
```python
class ResNet(nn.Module):
def __init__(self, block, num_blocks, num_classes=10):
super(ResNet, self).__init__()
self.in_planes = 64
self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(64)
self.layer1 = self._make_layer(block, 64, num_blocks[0], stride=1)
self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)
self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)
self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)
self.linear = nn.Linear(512*block.expansion, num_classes)
def _make_layer(self, block, planes, num_blocks, stride):
strides = [stride] + [1]*(num_blocks-1)
layers = []
for stride in strides:
layers.append(block(self.in_planes, planes, stride))
self.in_planes = planes * block.expansion
return nn.Sequential(*layers)
def forward(self, x):
out = nn.ReLU()(self.bn1(self.conv1(x)))
out = self.layer1(out)
out = self.layer2(out)
out = self.layer3(out)
out = self.layer4(out)
out = nn.AvgPool2d(4)(out)
out = out.view(out.size(0), -1)
out = self.linear(out)
return out
```
4. 定义ResNet18模型
ResNet18模型是一个包含多个BasicBlock的ResNet模型,其中包括两个3×3卷积层和一个1×1卷积层。我们可以使用ResNet类来定义ResNet18模型。
```python
def ResNet18():
return ResNet(BasicBlock, [2,2,2,2])
```
5. 实例化模型并进行训练
在实例化ResNet18模型之后,我们可以使用PyTorch提供的优化器和损失函数对模型进行训练,如下所示:
```python
import torch.optim as optim
device = 'cuda' if torch.cuda.is_available() else 'cpu'
net = ResNet18().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4)
for epoch in range(100):
net.train()
for batch_idx, (inputs, targets) in enumerate(trainloader):
inputs, targets = inputs.to(device), targets.to(device)
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, targets)
loss.backward()
optimizer.step()
net.eval()
test_loss = 0
correct = 0
with torch.no_grad():
for batch_idx, (inputs, targets) in enumerate(testloader):
inputs, targets = inputs.to(device), targets.to(device)
outputs = net(inputs)
test_loss += criterion(outputs, targets).item()
_, predicted = outputs.max(1)
correct += predicted.eq(targets).sum().item()
test_loss /= len(testloader.dataset)
print('Epoch: {} | Test Loss: {:.3f} | Test Acc: {:.3f}'.format(epoch, test_loss, 100.*correct/len(testloader.dataset)))
```
在训练过程中,我们首先将模型移动到GPU上,然后定义交叉熵损失函数和随机梯度下降优化器。在每个epoch中,我们先将模型设置为训练模式,然后对训练集进行迭代,并在每个batch上计算损失和梯度,并更新模型的参数。接着,我们将模型设置为评估模式,对测试集进行迭代,并在每个batch上计算损失和精度。最后,我们输出每个epoch的测试损失和测试精度。
阅读全文