pytorch 加载预训练权重后,验证结果与之前完整训练时结果不同

问题描述:

相同的训练、验证和测试集,当完整的从头开始训练一个模型时,最终的测试集score能定格在0.9左右,但当将训练、验证集代码注释掉之后,加载之前训练的权重,仅仅将模型在测试集上测试时,发现score又只有0.5了。

也就是说模型和权重必须完整经历过一遍训练、验证和测试集的流程才能正常得到最终训练好的score,仅仅放在测试集上运行则没有应有的训练效果。

解决方法:

问题出在BatchNorm上,在加载权重的代码后面加一个model.eval()就可解决问题。

self.rcnn.load_state_dict(torch.load(
            						 "../models/2024_1_12_9_12_128.h5",
            						 map_location=torch.device(self.device)))
self.rcnn.eval()
  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是关于使用PyTorch进行迁移学习和训练VGG16模型的一些基本步骤: 1. 导入必要的PyTorch库: ``` import torch import torch.nn as nn import torch.optim as optim from torch.optim import lr_scheduler import torchvision from torchvision import datasets, models, transforms ``` 2. 加载数据集并进行数据增强: ``` data_transforms = { 'train': transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), 'val': transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), } data_dir = 'path/to/dataset' image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in ['train', 'val']} dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4, shuffle=True, num_workers=4) for x in ['train', 'val']} dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']} class_names = image_datasets['train'].classes ``` 3. 加载预训练的VGG16模型: ``` model_ft = models.vgg16(pretrained=True) ``` 4. 修改VGG16的最后一层,使其适应数据集: ``` num_ftrs = model_ft.classifier[6].in_features model_ft.classifier[6] = nn.Linear(num_ftrs, len(class_names)) ``` 5. 设置损失函数和优化器: ``` criterion = nn.CrossEntropyLoss() optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9) ``` 6. 设置学习率调整器: ``` exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1) ``` 7. 训练模型: ``` def train_model(model, criterion, optimizer, scheduler, num_epochs=25): for epoch in range(num_epochs): print('Epoch {}/{}'.format(epoch, num_epochs - 1)) print('-' * 10) # Each epoch has a training and validation phase for phase in ['train', 'val']: if phase == 'train': scheduler.step() model.train() # Set model to training mode else: model.eval() # Set model to evaluate mode running_loss = 0.0 running_corrects = 0 # Iterate over data. for inputs, labels in dataloaders[phase]: inputs = inputs.to(device) labels = labels.to(device) # zero the parameter gradients optimizer.zero_grad() # forward # track history if only in train with torch.set_grad_enabled(phase == 'train'): outputs = model(inputs) _, preds = torch.max(outputs, 1) loss = criterion(outputs, labels) # backward + optimize only if in training phase if phase == 'train': loss.backward() 好的,下面是关于使用 PyTorch 迁移学习 VGG16 模型的一些步骤和示例代码。 1. 导入 PyTorch 和 torchvision 库 ```python import torch import torch.nn as nn import torchvision.models as models import torchvision.transforms as transforms ``` 2. 加载预训练的 VGG16 模型 ```python vgg16 = models.vgg16(pretrained=True) ``` 3. 冻结 VGG16 模型的参数,只训练最后的全连接层 ```python for param in vgg16.parameters(): param.requires_grad = False classifier = nn.Sequential( nn.Linear(25088, 4096), nn.ReLU(inplace=True), nn.Dropout(p=0.5), nn.Linear(4096, 4096), nn.ReLU(inplace=True), nn.Dropout(p=0.5), nn.Linear(4096, 1000), nn.ReLU(inplace=True), nn.Dropout(p=0.5), nn.Linear(1000, 2), ) vgg16.classifier = classifier ``` 4. 加载数据并进行预处理 ```python data_transforms = { 'train': transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), 'val': transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), } train_data = torchvision.datasets.ImageFolder('./data/train', transform=data_transforms['train']) val_data = torchvision.datasets.ImageFolder('./data/val', transform=data_transforms['val']) train_loader = torch.utils.data.DataLoader(train_data, batch_size=32, shuffle=True, num_workers=4) val_loader = torch.utils.data.DataLoader(val_data, batch_size=32, shuffle=False, num_workers=4) ``` 5. 定义损失函数和优化器 ```python criterion = nn.CrossEntropyLoss() optimizer = torch.optim.Adam(vgg16.classifier.parameters(), lr=0.001) ``` 6. 训练模型 ```python num_epochs = 10 for epoch in range(num_epochs): running_loss = 0.0 running_corrects = 0 for images, labels in train_loader: images = images.cuda() labels = labels.cuda() optimizer.zero_grad() outputs = vgg16(images) _, preds = torch.max(outputs, 1) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() * images.size(0) running_corrects += torch.sum(preds == labels.data) epoch_loss = running_loss / len(train_data) epoch_acc = running_corrects.double() / len(train_data) print('Epoch [{}/{}], Loss: {:.4f}, Accuracy: {:.4f}'.format(epoch+1, num_epochs, epoch_loss, epoch_acc)) ``` 7. 在验证集上评估模型 ```python vgg16.eval() val_loss = 0.0 val_corrects = 0 for images, labels in val_loader: images =好的,下面是关于使用 PyTorch 进行迁移学习和训练 VGG16 模型的步骤: 1.导入 PyTorch 和其他必要的库: ``` python import torch import torch.nn as nn import torch.optim as optim from torch.optim import lr_scheduler import numpy as np import torchvision from torchvision import datasets, models, transforms import matplotlib.pyplot as plt import time import os ``` 2.加载数据集并进行数据增强: ``` python data_transforms = { 'train': transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), 'val': transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), } data_dir = 'path/to/data' image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in ['train', 'val']} dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4, shuffle=True, num_workers=4) for x in ['train', 'val']} dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']} class_names = image_datasets['train'].classes device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") ``` 3.加载预训练的 VGG16 模型并替换最后一层: ``` python model_ft = models.vgg16(pretrained=True) num_ftrs = model_ft.classifier[6].in_features model_ft.classifier[6] = nn.Linear(num_ftrs, 2) model_ft = model_ft.to(device) criterion = nn.CrossEntropyLoss() optimizer_ft = optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9) exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1) ``` 4.训练模型: ``` python def train_model(model, criterion, optimizer, scheduler, num_epochs=25): since = time.time() best_model_wts = copy.deepcopy(model.state_dict()) best_acc = 0.0 for epoch in range(num_epochs): print('Epoch {}/{}'.format(epoch, num_epochs - 1)) print('-' * 10) # Each epoch has a training and validation phase for phase in ['train', 'val']: if phase == 'train': scheduler.step() model.train() # Set model to training mode else: model.eval() # Set model to evaluate mode running_loss = 0.0 running_corrects = 0 # Iterate over data. for inputs, labels in dataloaders[phase]: inputs = inputs.to(device) labels = labels.to(device) # zero the parameter gradients optimizer.zero_grad() # forward # track history if only in train with torch.set_grad_enabled(phase == 'train'): outputs = model(inputs) _, preds = torch.max(outputs, 1) loss = criterion好的,下面是关于使用PyTorch进行迁移学习和Fine-tuning VGG16模型的一些指导: 1. 下载预训练模型: 首先需要下载预训练模型,可以使用PyTorch中自带的torchvision库来下载: ``` import torchvision.models as models vgg16 = models.vgg16(pretrained=True) ``` 这将下载VGG16的预训练权重。 2. 用新数据集进行微调: 接下来,需要将新数据集加载到模型中进行微调,可以使用torchvision.datasets和torch.utils.data.DataLoader来完成数据的预处理和加载。 ``` import torchvision.datasets as datasets import torchvision.transforms as transforms from torch.utils.data import DataLoader # 数据集预处理 data_transforms = transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) # 加载数据集 train_dataset = datasets.ImageFolder(root='./train/', transform=data_transforms) train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) # 微调模型 for param in vgg16.parameters(): param.requires_grad = False vgg16.classifier[6] = nn.Linear(4096, num_classes) # 修改分类层 optimizer = optim.SGD(vgg16.classifier[6].parameters(), lr=0.001, momentum=0.9) criterion = nn.CrossEntropyLoss() for epoch in range(num_epochs): for inputs, labels in train_loader: inputs, labels = inputs.to(device), labels.to(device) optimizer.zero_grad() outputs = vgg16(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() ``` 在此代码中,我们首先使用transforms.Compose将数据集进行预处理,然后使用ImageFolder将数据集加载到内存中。接下来,我们使用for循环对模型进行微调。需要将所有参数的requires_grad设置为False,这是因为我们只想更新分类器层的参数。修改完分类器层之后,我们使用SGD作为优化器来更新参数。在每个epoch中,我们将数据集分批次加载到模型中,并计算输出和损失,然后使用反向传播来更新模型的权重。 3. 保存模型: 在训练完成后,可以使用torch.save来保存模型的权重。 ``` torch.save(vgg16.state_dict(), 'vgg16_weights.pth') ``` 以上是使用PyTorch迁移学习和Fine-tuning VGG16模型的基本指导,希望能对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值