(这篇博客其实很早之前就写过了,就是自己对当前学习pytorch的一个教程学习做了一个学习笔记,一直未发现,今天整理一下,发出来与前面基础形成连载,方便初学者看,但是可能部分pytorch和torchvision的API接口已经更新了,导致部分代码会产生报错,但是其思想还是可以借鉴的。

因为其中内容相对比较简单,而且目前其实torchvision中已经存在现成的VGG模型及其预训练模型,所以不建议看到这篇博客的盆友花费过多时间敲写学习)

========下面是5年前的正文:

  我们在前三篇博客学会了使用自己搭建的卷积神经网络模型解决手写图片识别的问题,因为卷积神经网络在解决计算机视觉问题上有着独特的优势,所以采用简单的神经网络模型就能使手写图片识别的准确率达到很高的水平。不过,用来训练和测试模型的手写图片数据的特征非常明显,所以也很容易被卷积神经网络模型捕获到。

  本次将搭建卷积神经网络模型对生活中普通图片进行分类,并进入迁移学习(Transfer Learning)方法。为了验证迁移学习方法的方便性和高效性,我们先使用自定义结构的卷积神经网络模型解决图片的分类问题,然后通过使用迁移学习方法得到的模型来解决同样的问题,以此来看看在效果上是传统的方法更出色还是迁移学习方法更出色。

一:迁移学习入门

  在开始之前,我们先来了解一下什么是迁移学习。在深度神经网络算法的应用过程中,如果我们面对的是数据规模较大的问题,那么在搭建好深度神经网络模型后,我们势必要花费大量的算力和时间去训练模型和优化参数,最后耗费了这么多资源得到的模型只能解决这一个问题,性价比非常低。如果我们用这么多资源训练的模型能够解决同一类问题,那么模型的性价比会提高很多,这就促使使用迁移模型解决同一类问题的方法出现。因为该方法的出现,我们通过对一个训练好的模型进行细微调整,就能将其应用到相似的问题中,最后还能取得很好的效果;另外,对于原始数据较少的问题,我们也能够通过采用迁移模型进行有效解决,所以,如果能够选取合适的迁移学习方法,则会对解决我们所面临的问题有很大的帮助。
  假如我们现在需要解决一个计算机视觉的图片分类问题,需要通过搭建一个模型对猫和狗的图片进行分类,并且提供了大量的猫和狗的图片数据集。假如我们选择使用卷积神经网络模型来解决这个图片分类问题,则首先要搭建模型,然后不断对模型进行训练,使其预测猫和狗的图片的准确性达到要求的阈值,在这个过程中会消耗大量的时间在参数优化和模型训练上。不久之后我们又面临另一个图片分类问题,这次需要搭建模型对猫和狗的图片进行分类,同样提供了大量的图片数据集,如果已经掌握了迁移学习方法,就不必再重新搭建一套全新的模型,然后耗费大量的时间进行训练了,可以直接使用之前已经得到的模型和模型的参数并稍加改动来满足新的需求。不过,对迁移的模型需要进行重新训练,这是因为最后分类的对象发生了变化,但是重新训练的时间和搭建全新的模型进行训练的时间相对很少,如果调整的仅仅是迁移模型的一小部分,那么重新训练所耗费的时间会更少。通过迁移学习可以节省大量的时间和精力,而且最终得到的结果不会太差,这就是迁移学习的优势和特点。
  需要注意的是,在使用迁移学习的过程中有时会导致迁移模型出现负迁移,我们可以将其理解为模型的泛化能力恶化。假如我们将迁移学习用于解决两个毫不相关的问题,则极有可能使最后迁移得到的模型出现负迁移。

  (下面迁移学习内容参考:https://my.oschina.net/u/876354/blog/1614883)

1.1,什么是迁移学习?

  迁移学习(Transfer Learning)是一种机器学习方法,是把一个领域(即源领域)的知识,迁移到另外一个领域(即目标领域),使得目标领域能够取得更好的学习效果。

  通过,源领域数据量充足,而目标领域数据量较小,这种场景就很适合做迁移学习,例如我们要对一个任务进行分类,但是此任务中数据不重复(目标域),然而却又大量的相关的训练数据(源域),但是此训练数据与所需进行的分类任务中的测试数据特征分布不同(例如语音情感识别中,一种语言的语音数据充足,然而所需进行分类任务的情况数据却极度缺乏),在这种情况下如果可以采用合适的迁移学习方法则可以大大提高样本不充足任务的分类识别结果。

1.2,为什么现在需要迁移学习?

  前百度首席科学家,斯坦福的教授吴恩达(Andrew Ng)在曾经说过:“迁移学习将会是继监督学习之后的下一个机器学习商业成功的驱动力”。

  在2016年的NIPS会议上,吴恩达给出了一个未来AI方向的技术发展图,还是很客观的:

深度学习之PyTorch实战(4)——迁移学习-LMLPHP

   毋庸置疑,监督学习是目前成熟度最高的,可以说已经成功商用,而下一个商用的技术将会是迁移学习(Transfer Learning),这也是Andrew 预测未来五年最有可能走向商用的 AI 技术。

  吴恩达在一次采访中,也提到迁移学习会是一个很有活力的领域,我们之所以对迁移学习感到兴奋,其原因在于现代深度学习的巨大价值是针对我们拥有海量数据的问题。但是,也有很多问题领域,我们没有足够数据。比如语音识别。在一些语言中,比如普通话,我们有很多数据,但是那些只有少数人说的语言,我们的数据就不够庞大。所以,为了针对数据量不那么多的中国少数人所说的方言进行语音识别,能将从学习普通话中得到的东西进行迁移吗?我们的技术确实可以做到这一点,我们也正在做,但是,这一领域的进步能让人工智能有能力解决广泛得多的问题。

1.3,传统机器学习和迁移学习有什么不同呢?

  在机器学习的经典监督学习场景中,如果我们要针对一些任务和域A训练一个模型,我们会假设被提供了针对同一个域和任务的标签数据。如下图所示,其中我们的模型A在训练数据和测试数据中的域和任务都是一样的。

深度学习之PyTorch实战(4)——迁移学习-LMLPHP

   即使是跟迁移学习比较相似的多任务学习,多任务学习是对目标域和源域进行共同学习,而迁移学习主要是对通过对源域的学习解决目标域的识别任务。下图就展示了传统的机器学习和迁移学习的区别:

深度学习之PyTorch实战(4)——迁移学习-LMLPHP

 1.4,什么适合迁移?

  在一些学习任务中有一些特征是个体所特有的,这些特征不可以迁移。而有些特征是所有的个体中具有贡献的,这些可以进行迁移。

  有些时候如果迁移的不合适则导致负迁移,例如当源域和目标域的任务毫不相关时有可能会导致负迁移。

1.5,迁移学习的分类

  根据 Sinno  Jialin Pan 和 Qiang Yang 在TKDE 2010上的文章,可将迁移学习算法,根据所需要的迁移知识表示形式(即 what to  transfer ),分为四类:

  • 1,基于实例的迁移学习(instance-based  transfer learning):源领域(source domain)中的数据(data)的某一部分可以通过 reweighting 的方法重用,用于 target domain 的学习。
  • 2,基于特征表示的迁移学习(feature-representation  transfer learning):通过 source domain 学习一个好的(good)的特征表示,把知识通过特征的形式进行编码,并从 source domain 传递到 target domain ,提升 target domain 任务效果。
  • 3,基于参数的迁移学习(parameter-transfer learning):target domain和source domain的任务之间共享相同的模型参数(model parameters)或者是服从相同的先验分布(prior distribution)。
  • 4,基于关系知识迁移学习(relational-knowledge transfer learning):相关领域之间的知识迁移,假设 source demain 和 target domain中,数据(data)之间联系关系是相同的。

  前三类迁移学习方式都要求数据(data)独立同分布假设。同时,四类迁移学习方式都要求选择 source domain和 target domain 相关。

  下表给出了迁移内容的迁移学习分类:

深度学习之PyTorch实战(4)——迁移学习-LMLPHP

1.6,迁移学习的应用与价值

1.6.1 迁移学习的应用

  用于情感分类,图像分类,命名实体识别,WiFi信号定位,自动化设计,中文到英文翻译等问题。

1.6.2 迁移学习的价值

  • 1,复用现有知识域数据,已有的大量的工作不至于完全丢弃
  • 2,不需要再去花费巨大代价去重新采集和标定庞大的新数据局,也有可能数据根本无法获取
  • 3,对于快速出现的新领域,能够快速迁移和应用,体现时效性优势

  总之,迁移学习将会成为接下来令人兴奋的研究方向,特别是许多应用需要能够将知识迁移到新的任务和域中的模型,将会成为人工智能的又一个重要助推力。

二:数据集处理

  本文使用的数据集来自Kaggle网站上的“Dogs vs.Cats”竞赛项目,可以通过网络免费下载这些数据集。在这个数据集的训练数据集中一共有25000张猫和狗的图片,其中包含12500张猫的图片和12500张狗的图片。在测试数据集中有12500张图片,不过其中的猫狗图片是无序混杂的,而且没有对应的标签。这些数据集将被用于对模型进行训练和对参数进行优化,以及在最后对模型的泛化能力进行验证。

官方下载地地址 https://www.kaggle.com/c/dogs-vs-cats/data

2.1 验证数据集和测试数据集

  在实践中,我们不会直接使用测试数据集对搭建的模型进行训练和优化,而是在训练数据集中划出一部分作为验证集,来评估在每个批次的训练后模型的泛化能力。这样做的原因是如果我们使用测试数据集进行模型训练和优化,那么模型最终会对测试数据集产生拟合倾向,换而言之,我们的模型只有在对测试数据集中图片的类别进行预测时才有极强的准确率,而在对测试数据集以外的图片类别进行预测时会出现非常多的错误,这样的模型缺少泛化能力。所以,为了防止这种情况的出
现,我们会把测试数据集从模型的训练和优化过程中隔离出来,只在每轮训练结束后使用。如果模型对验证数据集和测试数据集的预测同时具备高准确率和低损失值,就基本说明模型的参数优化是成功的,模型将具备极强的泛化能力。在本章的实践中我们分别从训练数据集的猫和狗的图片中各抽出 2500 张图片组成一个具有5000张图片的验证数据集。
  我们也可以将验证数据集看作考试中的模拟训练测试,将测试数据集看作考试中的最终测试,通过两个结果看测试的整体能力,但是测试数据集最后会有绝对的主导作用。不过本章使用的测试数据集是没有标签的,而且本章旨在证明迁移学习比传统的训练高效,所以暂时不使用在数据集中提供的测试数据集,我们进行的只是模型对验证数据集的准确性的横向比较。

2.2 数据预览

  在划分好数据集之后,就可以进行数据预览了,我们通过数据预览可以掌握数据的基本信息,从而更好地决定如何使用这些数据。

  开始的部分代码如下:

import torch 
import torchvision
from torchvision import datasets
from torchvision import transforms
import os
import matplotlib.pyplot as plt
import time
03-27 00:45