Pytorch迁移学习实例

      写在前面:最近有很久没有更新博客了,主要是在学习研究深度学习这块知识,语言主要为pytorch,目前这块主要对技术知识做一个总结,以此勉励自己以及他人。

      首先,我们会在什么情况下需要用到迁移学习呢?在实际工程应用方面,主要有以下2点

      1、缺乏数据集

      2、重新构造模型难度和代价太大

      因此,所谓迁移学习就是说,已经有一个还不错的模型,但是它的类别数与需求不同,但是应用环境类似,比如图像识别(这里的识别是指单一对象识别,并不包括对象检测这种),那么那些已经训练好的模型对图像特征提取已经做的很好了,我们不太需要自己非要重新构建一个模型去训练,我们只需要利用已经训练好的模型的权重去提取新类别的图像的特征就可以了,所以下面详细介绍迁移学习的类别以及过程,会附上相应源码。

      迁移学习有两类:finetuning  和 feature extraction

      所谓finetuning就是说主要是调参,如(学习率,动量,等)相当于重新训练整个模型,只不过参数是微调

      所谓feature extraction,就是说保留除最后一层以外其他层的weights不变,这个可调范围就很小了

      实际应用中,使用finetuning的居多

      首先我们要了解一下经典的卷积神经网络模型,如果还有刚入门的童鞋没看过,我强烈建议看一看,因为后续许多方法都是基于这些经典模型展开的,深入了解非常有帮助的。好了,废话不多说了。。

     经典模型:[resnet, alexnet, vgg,  densenet, inception],其中应用非常广泛的为resnet与vgg,这里我就不详细介绍这些模型了

    如何进行迁移学习?

    这里,我们首先要找到模型的最后一层,也就是全连接层,这里以resnet为例

    (fc): Linear(in_features=512, out_features=1000, bias=True)

    找到这个后,将out_features改为num_classes,也就是

    model.fc = nn.Linear(512, num_classes)

    看,简单吧,这里说明一下,如果是开源项目的模型,也是同样的道理,找到最后的全连接层,改为我们需要的类别即可

   整个过程如下:

if model_name == "resnet":
        """ Resnet18
        """
        model_ft = models.resnet18(pretrained=use_pretrained)
        set_parameter_requires_grad(model_ft, feature_extract)
        num_ftrs = model_ft.fc.in_features
        model_ft.fc = nn.Linear(num_ftrs, num_classes)
        input_size = 224

   

def set_parameter_requires_grad(model, feature_extracting):
    if feature_extracting:
        for param in model.parameters():
            param.requires_grad = False

其他的步骤,包括加载数据,设置optimizer等与之前方法一致,其中,feature_extract是一个boolean类型的值,如果设置为False则说明采用第一种方式进行迁移学习,模型的所有weights都会更新,如果此值设置为True,则是采用第二种方式进行迁移学习

 

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个基于 PyTorch迁移学习实例,可以参考一下: 1. 导入必要的库 ```python import torch import torch.nn as nn import torchvision from torchvision import datasets, models, transforms import numpy as np import matplotlib.pyplot as plt ``` 2. 加载数据集 ```python data_dir = '/path/to/data' 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]) ]), } 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. 加载预训练模型 ```python model_ft = models.resnet18(pretrained=True) num_ftrs = model_ft.fc.in_features model_ft.fc = nn.Linear(num_ftrs, 2) ``` 4. 定义损失函数和优化器 ```python criterion = nn.CrossEntropyLoss() # Observe that all parameters are being optimized optimizer_ft = torch.optim.SGD(model_ft.parameters(), lr=0.001, momentum=0.9) ``` 5. 训练模型 ```python def train_model(model, criterion, optimizer, 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': 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() optimizer.step() # statistics running_loss += loss.item() * inputs.size(0) running_corrects += torch.sum(preds == labels.data) epoch_loss = running_loss / dataset_sizes[phase] epoch_acc = running_corrects.double() / dataset_sizes[phase] print('{} Loss: {:.4f} Acc: {:.4f}'.format( phase, epoch_loss, epoch_acc)) return model device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") model_ft = model_ft.to(device) model_ft = train_model(model_ft, criterion, optimizer_ft, num_epochs=25) ``` 6. 保存模型 ```python torch.save(model_ft.state_dict(), '/path/to/save/model.pth') ``` 这个例子中,我们使用了一个预训练的 ResNet-18 模型进行迁移学习,然后训练了一个二分类模型。你可以根据自己的需要进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值