利用迁移学习加速深度学习:PyTorch Playbook

发布日期:2026-07-07 09:16:04   来源 : 杭州电子商务研究院    浏览量 :14
杭州电子商务研究院 发布日期:2026-07-07 09:16:04  
14

介绍

是的!如果你已经会弹原声吉他,那么学习弹电子吉他会更容易。你不必从头开始重新学习电吉他的基础知识。我们人类可以聪明地将以前学到的知识应用到不同的任务或领域,并利用这些知识有效地解决新问题。

机器可以模仿人脑这种知识转移的能力吗?是的,这要归功于迁移学习(TL)

本指南将介绍 TL 的动机和类型。有关预训练模型的简要介绍和实际示例,请查看 Kaggel 竞赛“狗与猫”。由于它是二分类,因此在机器学习术语中它被称为二元分类问题。

动机

迁移学习强调将解决一项任务时获得的知识存储在数据库中,并将其应用于不同但相关的任务。基本的学习过程如下所示。

图片来源

传统上,CNN深度学习算法用于解决特定任务。一旦特征空间分布发生变化,就需要从头开始构建模型。卷积网络中的初始层检测强度、颜色、边缘等低级特征。无论您检测的是汽车、人类还是动物,这些层都很常见。更深的层将检测更复杂的特征,如形状、面部、图案等。

训练数据越大,预测准确率就越高。在处理复杂问题时,需要大量的训练图像数据。这意味着堆叠越来越多的层来使网络更深。但假设堆叠 1000 个神经网络 (NN) 层不会产生良好的结果,并使情况变得更糟。

迁移学习来救援!

该模型无需从头开始创建整个网络,而是可以学习一项任务的特征并将其应用于另一项任务。通常使用预先训练的模型。最常见的是,这些模型在 ImageNet 上进行了训练——120 万张图像,1000 个类别。

记住将分类层(FC)更改为与您需要预测的类别数量相同。

迁移学习技术的类型

TL 技术有三种类型:归纳式传导式无监督式。以下是不同传输设置的概述。

图片来源

下面给出它们的定义和区别。

下图展示了从源域到目标域实现 TL 的不同方法

图片来源

应用迁移学习

什么

了解源和目标域/任务之间的共同知识,以提高目标任务的性能。

什么时候

如果您的目标数据集与训练数据集(ImageNet)不同,则建议不要使用 TL,考虑到图像的多样性,通常情况并非如此。这种类型的知识迁移称为负迁移。如果目标图像超出其范围,例如医学图像或望远镜图像,ImageNet 权重将无济于事。

如何

当源域和目标域和任务相关时,识别不同的迁移学习技术。

按照下表并满足您的要求。

图片来源

现在您将学习如何将这些 TL 技术应用于深度学习。

迁移学习在深度学习中的应用

预训练模型

与机器学习(计算机视觉)相比,深度学习需要大量的训练时间和数据。你可以使用预先训练的模型来提取特征、微调权重、保存它们并让其他人使用,从而节省一些时间。这也称为深度迁移学习

以下是一些可在Pytorch API下载的著名预训练模型类型。

  1. 残差网络
  2. 密集网络
  3. VGG-16
  4. 移动网络

预先训练的模型将带来高精度和高速度的优势,从而节省您数周从头开始训练和创建这些模型的工作量。

微调

预训练模型的较深层用于学习特征并进行微调。为了实现带微调的迁移学习,在添加可训练层时会替换最后的层。

图片来源

即使数据较新且较小,较早的层也更具通用性。即使冻结初始层并保留其余层,结果也绝对会很好。对于较大的数据集,您可以保留具有初始权重的完整网络。

本指南将使用 DenseNet121 预训练模型作为特征提取器。数据有一个限制,即每个类别的训练样本较少。即使输入图像是新的并且从未在 ImageNet 中存在过,模型也必须提取适当的特征并预测结果。

Python 中的实现

导入重要的库。

      import torchvision 
import torch.nn as nn 
import torch 
import torch.nn.functional as F 
from torchvision import transforms,models,datasets 
import matplotlib.pyplot as plt 
from PIL import Image 
import numpy as np 
from torch import optim
    

调用图像并使用transform.Compose函数进行转换。

      train_data_dir = '/input/cat-and-dog/training_set/training_set' 
 
transform = transforms.Compose([transforms.Resize(255), 
    transforms.CenterCrop(224), 
    transforms.ToTensor()]) 
 
dataset = torchvision.datasets.ImageFolder(train_data_dir, transform= transform) 
train_loader = torch.utils.data.DataLoader(dataset, batch_size=400 ,shuffle=True) 
test_data_dir = '/input/cat-and-dog/test_set/test_set' 
 
transform = transforms.Compose([transforms.Resize(255), 
    transforms.CenterCrop(224), 
    transforms.ToTensor()]) 
 
test_dataset = torchvision.datasets.ImageFolder(test_data_dir, transform= transform) 
test_loader = torch.utils.data.DataLoader(dataset, batch_size=400 ,shuffle=True)
    
      def imshow(inp, title=None): 
    """Imshow for Tensor.""" 
    inp = inp.numpy().transpose((1, 2, 0)) 
    plt.figure(figsize=(20,150)) 
    plt.imshow(inp) 
 
inputs, classes = next(iter(train_loader)) 
 
# Make a grid from batch 
out = torchvision.utils.make_grid(inputs, scale_each= True) 
 
imshow(out)
    

下载预先训练的模型。

      model = models.densenet121(pretrained = True) 
model
    

使用Logsoftmax()的激活层更改输出层

      for params in model.parameters(): 
    params.requires_grad = False 

from collections import OrderedDict 
 
classifier = nn.Sequential(OrderedDict([ 
    ('fc1',nn.Linear(1024,500)), 
    ('relu',nn.ReLU()), 
    ('fc2',nn.Linear(500,2)), 
    ('Output',nn.LogSoftmax(dim=1)) 
])) 
 
model.classifier = classifier
    

训练模型。

      model = model.cuda() 
optimizer= optim.Adam(model.classifier.parameters()) 
criterian= nn.NLLLoss() 
list_train_loss=[] 
list_test_loss=[] 
 
for epoch in range(10): 
    train_loss= 0 
    test_loss= 0 
    for bat,(img,label) in enumerate(train_loader): 
        # moving batch and labels to gpu 
        img = img.to('cuda:0') 
        label = label.to('cuda:0') 
        model.train() 
        optimizer.zero_grad() 
 
        output = model(img) 
        loss = criterian(output,label) 
        loss.backward() 
        optimizer.step() 
        train_loss = train_loss+loss.item() 
 
    accuracy=0 
    for bat,(img,label) in enumerate(test_loader): 
        img = img.to('cuda:0') 
        label = label.to('cuda:0') 
        model.eval() 
        logps= model(img) 
        loss = criterian(logps,label) 
        test_loss+= loss.item() 
        ps=torch.exp(logps) 
        top_ps,top_class=ps.topk(1,dim=1) 
        equality=top_class == label.view(*top_class.shape) 
        accuracy +=torch.mean(equality.type(torch.FloatTensor)).item() 
 
    list_train_loss.append(train_loss/20) 
    list_test_loss.append(test_loss/20) 
    print('epoch: ',epoch,' train_loss: ',train_loss/20,' test_loss: ',test_loss/20,' accuracy: ', accuracy/len(test_loader))
    
      samples, _ = iter(test_loader).next() 
samples = samples.to('cuda:0') 
fig = plt.figure(figsize=(24, 16)) 
fig.tight_layout() 
output = model(samples[:24]) 
pred = torch.argmax(output, dim=1) 
pred = [p.item() for p in pred] 
ad = {0:'I guess it\'s a cat', 1:'I guess it\'s a dog'} 
for num, sample in enumerate(samples[:24]): 
    plt.subplot(4,6,num+1) 
    plt.title(ad[pred[num]]) 
    plt.axis('off') 
    sample = sample.cpu().numpy() 
    plt.imshow(np.transpose(sample, (1,2,0)))
    
<div class="code-b
以上内容来自杭州电子商务研究院推送
关注
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据