在PyTorch中,加载ResNet50模型并冻结模型的前几层可以通过以下步骤进行:
import torch
from torchvision.models import resnet50
# 设置GPU环境
use_cuda = True
device = torch.device("cuda" if (use_cuda and torch.cuda.is_available()) else "cpu")
# 加载预训练的ResNet50模型
trained_model = resnet50(pretrained=True)
# 冻结需要保持不变的层,通常是前几个卷积层
for name, param in trained_model.named_parameters():
if 'conv1' in name or 'bn1' in name or 'conv2' in name or 'bn2' in name or 'conv3' in name or 'bn3' in name:
param.requires_grad = False
# 修改最后一层进行微调
model = nn.Sequential(*list(trained_model.children())[:-1],
Flatten(), # [b,2048]
nn.Linear(2048, 4), # 假设输出类别数为4
).to(device)
# 损失、优化器
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
# 训练模型
for epoch in range(epochs):
total_loss = 0
for imgs, labels in train_loader:
imgs, labels = imgs.to(device), labels.to(device)
optimizer.zero_grad()
# 前向传播
outputs = model(imgs)
loss = criterion(outputs, labels)
# 反向传播和优化
loss.backward()
optimizer.step()
total_loss += loss.item()
# 打印每个epoch的损失值
print(f"Epoch {epoch+1} Loss: {total_loss /len(train_loader)}")
# 保存模型参数
torch.save(model.state_dict(), 'retrain_resnet50.pth')
# 测试模型
def evalute(model, loader):
model.eval()
correct = 0
total = len(loader.dataset)
for x, y in loader:
x, y = x.to(device), y.to(device)
with torch.no_grad():
logits = model(x)
pred = logits.argmax(dim=1)
correct += torch.eq(pred, y).sum().float().item()
return correct/total
model.load_state_dict(torch.load('retrain_resnet50.pth'))
test_acc = evalute(model, test_loader)
print('test acc:', test_acc)