在这篇文章中,我们将简要解释什么是迁移学习,以及如何使用它。什么是迁移学习?迁移学习是使用预训练模型解决深度学习问题的艺术。迁移学习是一种机器学习技术,您可以使用预训练的神经网络来解决与网络最初训练要解决的问题类似的问题。例如,您可以使用为识别狗品种而构建的深度学习模型对狗和猫进行分类,而不是构建自己的模型。这让你免去了寻找高效神经网络架构的痛苦,节省了你训练的时间,并保证了良好的结果。也就是说,您可以花费很长时间来制作一个50层的CNN来最好地区分您的猫和狗,或者您可以简单地使用一些预训练的图像分类模型。使用预训练模型的三种不同方式重新调整预训练模型的用途主要有三种不同的方式。它们是,特征提取。复制预训练网络的架构。冻结一些层并训练其他层。特征提取:我们在这里需要做的就是更改输出层以给出猫和狗的概率(或者你的模型试图将事物分类到的类的数量)而不是最初训练的数千个将事物分类到类中的概率。当我们尝试在与预训练模型最初训练的数据非常相似并且数据集大小很小的数据上训练模型时,这是理想的。这种机制称为固定特征提取。我们只在我们添加的新输出层上重新训练,并保持每一层的权重。复制预训练网络的架构:在这里,我们定义了一个与预训练模型具有相同架构的机器学习模型,该模型在与我们试图实现的任务类似的任务上显示出优异的结果,并从头开始训练它。我们从预训练模型中丢弃每一层的权重,然后在我们的数据上重新训练整个模型。当我们有大量数据要训练时,我们会使用这种方法,但它与预训练模型训练的数据不太相似。冻结一些层并训练其他层:我们可以选择冻结预训练模型的初始k层,只训练前n-k层。我们保持权重的初始值和预训练模型一样不改变,重新训练数据的上层。当数据集较小,数据相似度较低时使用该方法。较低层侧重于可以从数据中提取的最基本信息,因此它可以用于其他问题,因为基本信息级别通常是相同的。另一种常见的情况是数据相似度很高,数据集也很大。在这种情况下,我们保留模型的架构和模型的初始权重。然后我们重新训练整个模型以更新预训练模型的权重以更好地适应我们的特定问题。这是使用迁移学习的理想情况。下图显示了根据数据集大小和数据相似性采取的方法。PyTorch中的迁移学习PyTorch中的torchvision.models模块下有八种不同的预训练模型。它们是:AlexNetVGGRESNETSqueezeNetDenseNetInceptionv3GoogLeNetShuffleNetv2这些是为图像分类构建的卷积神经网络,在ImageNet数据集上训练。ImageNet是一个按照WordNet层次结构组织的图像数据库,包含属于21841个类别的14,197,122张图像。由于PyTorch中的所有预训练模型都是针对同一任务在同一数据集上训练的,因此我们选择哪一个并不重要。让我们选择一个ResNet网络,看看它如何用于前面讨论的不同场景。ResNet或DeepResidualLearningforImageRecognition在pytorch中有五个版本,ResNet-18、ResNet-34、ResNet-50、ResNet-101和ResNet-152。让我们从torchvision下载ResNet-18。importtorchvision.modelsasmodelsmodel=models.resnet18(pretrained=True)下面是我们刚刚下载的模型。现在,让我们来看看如何在四个不同的问题上训练这个模型。数据集小,数据相似度高考虑这个kaggle数据集(https://www.kaggle.com/mriganksingh/cat-images-dataset)。这包括猫的图像和其他非猫的图像。它有209张64*64*3像素的训练图像和50张测试图像。这显然是一个非常小的数据集,但我们知道ResNet是在大量动物和猫的图像上训练的,因此我们可以使用ResNet作为我们的猫与非猫问题的固定特征提取器。num_ftrs=model.fc.in_featuresnum_ftrsOut:512model.fc.out_featuresOut:1000我们需要冻结除最后一层以外的所有网络。我们需要设置requires_grad=False来冻结参数,这样梯度就不会在backward()中计算。新构建模块的参数默认为requires_grad=True。forparaminmodel.parameters():param.requires_grad=False由于我们只需要第一层提供两个概率,即图片是不是猫的概率,我们可以重新定义最后一层的输出特征个数。model.fc=nn.Linear(num_ftrs,2)这是我们模型的新架构。我们现在要做的就是训练模型的最后一层,我们将能够使用我们的重定向vgg16来预测图像是否是猫,只需很少的数据和训练时间。数据量小,数据相似度低考虑到(https://www.kaggle.com/kvinicki/canine-coccidiosis),该数据集包含H.canine和H.canineoocystsHeterosporumoocysts的图像和标签,一种可以感染狗肠道的球虫寄生虫。它是由萨格勒布兽医学院创建的。它包含两种寄生虫的341张图像。这个数据集很小,不是Imagenet中的一个类。在这种情况下,我们保留预训练的模型架构,冻结较低层并保持它们的权重,并训练较低层更新它们的权重以适应我们的问题。count=0forchildinmodel.children():count+=1print(count)输出:10ResNet18一共10层。让我们冻结前6层。count=0forchildinmodel.children():count+=1ifcount<7:forparaminchild.parameters():param.requires_grad=False现在我们已经冻结了前6层,让我们重新定义最后的输出层只给出2个输出,而不是1000.model.fc=nn.Linear(num_ftrs,2)这是更新后的架构。现在,为了训练这个机器学习模型,更新第***4层的权重。数据集的大小很大,但数据相似性很低考虑这个来自kaggle的数据集,SkinCancerMNIST:HAM10000,它有超过10015个属于7个不同类别的皮肤镜图像。这不是我们可以在Imagenet中找到的那种数据。这是我们只保留模型架构而不是预训练模型的任何权重的地方。让我们重新定义输出层,将项目分为7类。model.fc=nn.Linear(num_ftrs,7)这个模型在没有GPU的机器上训练需要几个小时,但如果你运行了足够多的epoch,你仍然会得到很好的结果,而不必定义你自己的模型架构。数据量大且数据相似度高考虑来自kaggle(https://www.kaggle.com/alxmamaev/flowers-recognition)的花卉数据集。它包含4242个花卉图像。图片分为洋甘菊、郁金香、玫瑰、向日葵、蒲公英五类。每个班级大约有800张照片。这是应用迁移学习的理想情况。我们保留预训练模型的架构和每一层的权重,并训练模型更新权重以匹配我们的特定问题。model.fc=nn.Linear(num_ftrs,5)best_model_wts=copy.deepcopy(model.state_dict())我们从预训练模型中复制权重并初始化我们的模型。我们使用训练和测试阶段来更新这些权重。forepochinrange(num_epochs):print('Epoch{}/{}'.format(epoch,num_epochs—1))print('-'*10)forphasein['train','test']:ifphase=='train':scheduler.step()model.train()else:model.eval()running_loss=0.0running_corrects=0forinputs,labelsindataloaders[phase]:inputs=inputs.to(device)labels=labels.to(device)optimizer.zero_grad()withtorch.set_grad_enabled(phase=='train'):outputs=model(inputs)_,preds=torch.max(outputs,1)loss=criterion(outputs,labels)ifphase=='train':loss.backward()optimizer.step()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))ifphase=='test'andepoch_acc>best_acc:best_acc=epoch_accbest_model_wts=copy.deepcopy(model.state_dict())print(‘BestvalAcc:{:4f}'.format(best_acc))model.load_state_dict(best_model_wts)这个机器学习模型也需要几个小时来训练,但即使只有一个训练周期也能产生很好的结果。您可以按照相同的原则在任何其他平台上与任何其他预训练网络一起执行迁移学习。本文随机选取了Resnet和pytorch。任何其他CNN都会给出类似的结果。希望这可以节省您使用计算机视觉解决现实世界问题的痛苦时间。
