keras神经风格迁移_深度学习入门 | 第六章:经典卷积神经网络:迁移学习

keras神经风格迁移_深度学习入门 | 第六章:经典卷积神经网络:迁移学习_第1张图片

点击关注了解更多精彩内容!!

6.5  迁移学习

通过第5章和第6章的学习,我们掌握了很多新的深度学习模型的知识,这些都是前人智慧的结晶,可想而知,在未来还会有更多优秀的深度学习模型被开发出来,每个都学习显然不现实。此外,深度学习的训练又需要极其昂贵的硬件资源,这让很多科研工作者望而却步。因此为了解决人们在学习深度学习时遇到的种种困难,有人提出了迁移学习的概念,它能够帮助我们站在前人的肩膀上,继续前进。

本节将从深度学习面临的现实困难出发,说明迁移学习产生的原因,接着介绍迁移学习的原理,最后,通过一个实例介绍如何运用迁移学习。

6.5.1  深度学习的现实困难

深度学习的技术日新月异,但也存在一些现实的困难。

d52fbfcc81d456087b2d535f6d279428.gif

(1)经典的网络模型太多。

例如,有LeNet,AlexNet,VGG16,Inception.V1+V2+V3,ResNet+ResNext,DenseNet,MobileNet等,我们不知道今后还会提出哪些大放异彩的新模型。这些模型是科研工作者的智慧结晶,有非常多值得学习的地方。但是不得不承认,这也是一个非常让人糟心的地方。在传统的统计学模型学习中,大量的模型都可以规范成线性回归或逻辑回归问题。这说明统计学理论在模型方法上具有非常强的规范和抽象作用,这使得学习者能够先认真学习一个关键的基础理论知识,而后融会贯通,理解所有的东西。

但是深度学习在这方面很不一样,它更像工程。例如,前面我们学了很多基础的技巧,如卷积、池化、Batch normalization等。所有这些技巧,都不能称为模型,它们需要拼接在一起,才会成为一个模型。拼接的方式无穷多种,这就使得一部分特别勤奋聪明的学者,他们拼接出来的模型在数据上被广泛地验证是非常不错的。

d52fbfcc81d456087b2d535f6d279428.gif

(2)计算太昂贵,这里既包括硬件,也包括数据集。

在硬件方面,绝大多数普通人都只有能力接触到CPU,接触不到GPU,TPU可能就更难了。所以计算硬件资源对绝大多数学习者来说是非常昂贵的。在如此昂贵的硬件资源上,训练一个特别大的数据集,如ImageNet,则资源消耗是非常大的,绝大多数普通人甚至高校都做不到。根据笔者的了解,在很多非常好的大学中,也只有计算机专业的学生在进入教师的实验室之后,才有能力接触到GPU这样的计算资源。

基于以上两个现实困难,有没有巧妙的办法,让我们站在前人的肩膀上,借助他们过去研究沉淀下来的力量,往前走一步?这就产生了人们对迁移学习的一个最原始的需求。

6.5.2  迁移学习原理

迁移学习(Transfer Learning)是指将某个领域或任务上学习到的知识或模式应用到不同,但相关的领域或问题中。通过一个简单的例子来介绍什么是迁移学习。如图6.18所示,假设现在有两个任务,一个是TASK A,一个是TASK B。其中TASK B是我们的目标任务,进行猫狗分类,TASK A是其他学者做出来的。A和B的主要区别如下。

keras神经风格迁移_深度学习入门 | 第六章:经典卷积神经网络:迁移学习_第2张图片

图6.18  迁移学习理论图示

(1)A可能是个非常大的任务,如它是在ImageNet上训练出的ResNet。TASK A对数据、计算资源和时间的要求都非常高,但好处是,这些是别人已经训练好的任务。

(2)TASK B是我们的目标任务,这个任务没有那么大,因为它的样本量只有几万张图像,没有到上千万这样的级别。样本量小带来的好处是计算量小,但坏处是如果需要训练一个更加复杂模型时,样本量就不够了。

这时候,一个想法是能否把TASK A训练好的模型结构和权重直接应用到TASK B上,这就有点像果树嫁接。答案当然是可以的,但是需要注意以下两个问题。

(1)输入。输入相对来说比较简单,无论哪个TASK,它的输入都是图像,我们只要保证两个任务中输入图像的像素相同即可。

(2)输出,这是关键。TASK A的输出可能是为了区分1 000类,但是我们的TASK B简单很多,只分为两类。所以TASK A的网络结构最上面几层作为输出时,它至少要输出1 000个节点,但是TASK B只需要输出两个节点。

如何解决输出问题?最简单的办法就是把TASK A整个模型中最Top的那几层输出(常常是全连接层),替换成TASK B想要的形式,例如,猫狗分类,只需要最终输出两个节点。这就是迁移学习的基本原理,站在前人的肩膀上,用别人的模型、参数。

6.5.3  Keras中的迁移学习模型

由于迁移学习要用到别人训练出的模型结构和参数估计,因此需要一个文件,这个文件不仅包含模型结构,还包含这个模型当时训练出来的所有参数,这些参数很可能来自一个巨大的数据集,如ImageNet,幸运的是,这些文件就在Keras上。截至本书写作,Keras支持的经典模型如图6.19所示,只需要认真学习一下想要迁移的模型的文档就可以了。学习文档是为了知道模型结构,例如输入图像的像素是多少,我们的输入就要和它保持一致。

keras神经风格迁移_深度学习入门 | 第六章:经典卷积神经网络:迁移学习_第3张图片

图6.19  Keras支持的迁移学习模型

6.5.4  迁移学习实战:Inception V3

d52fbfcc81d456087b2d535f6d279428.gif

1.验证数据与训练数据的生成

接下来迁移学习一个经典的模型inception_v3。首先需要一个验证数据的数据生成器,这个数据生成器和之前的构建有一点区别,因为inception_v3这个特定的模型对图像的预处理做了很多细致的要求,而这些操作都被集成在一个叫作preprocess_input的函数里,该函数可以从keras.applications.inception_v3直接导入。因此在ImageDataGenerator中,需要定义preprocessing_function=prepocess_input,表示当数据生成器生成新数据时,要从数据库中的指定位置找到图像,然后按照preprocess_input函数的要求对它进行预处理。这是迁移学习的第一个步骤,生成数据生成器。具体如代码示例6-21所示。

代码示例6-21:生成数据生成器

from keras.applications.inception_v3 import preprocess_input
from keras.preprocessing.image import ImageDataGenerator

IMSIZE=299

validation_generator = ImageDataGenerator(
     preprocessing_function=preprocess_input).flow_from_directory(
     './data_tl/CatDog/validation',
     target_size=(IMSIZE, IMSIZE),
     batch_size=100,
     class_mode='categorical')

同样的操作流程用于训练数据的数据生成器,此时,只有经过预处理的数据才是适用于想要迁移的模型inception_v3。具体如代码示例6-22所示。

代码示例6-22:生成训练数据集

train_generator = ImageDataGenerator(
     preprocessing_function=preprocess_input,
     shear_range=0.5,
     rotation_range=30,
     zoom_range=0.2, 
     width_shift_range=0.2,
     height_shift_range=0.2,
     horizontal_flip=True).flow_from_directory(
     './data_tl/CatDog/train',
     target_size=(IMSIZE, IMSIZE),
     batch_size=150,
     class_mode='categorical')
d52fbfcc81d456087b2d535f6d279428.gif

2.原始图像数据展示

直接展示训练数据生成器生成的图像时,程序会报错,这是因为当原始数据按照inception_v3的预处理函数处理之后,有些像素变成了负数,这时无法用imshow做图形化展示。解决办法是把图像的第一层像素,也就是第0层取出来,此时像素取值是正是负无所谓,Python都可以处理,但遗憾的是看不到彩色图像,即使这样,也能看到非常清晰的猫和狗。具体如代码示例6-23所示。

代码示例6-23:原始图像展示

from matplotlib import pyplot as plt

plt.figure()
fig,ax = plt.subplots(2,5)
fig.set_figheight(6)
fig.set_figwidth(15)
ax=ax.flatten()
X,Y=next(train_generator)
for i in range(10): ax[i].imshow(X[i,:,:,0])

输出:

keras神经风格迁移_深度学习入门 | 第六章:经典卷积神经网络:迁移学习_第4张图片 d52fbfcc81d456087b2d535f6d279428.gif

3.建立Inception V3迁移学习模型

(1)从keras.applications.inception_v3导入Inception V3程序包。第一行base_model = Inception V3是基础模型,其中Inception V3是Keras的关键字,它表示这是一个提前训练好的Inception V3模型。其中有两个参数,第一个参数是weights='imagenet',表示模型的权重是从imagenet上训练出来的,第二个参数是include_top=False,表示没有迁移学习整个Inception V3模型,它的顶层输出神经元节点被砍掉。

(2)定义输入x=base_model.output,从这个位置开始,模型的底部是base_model,也就是Inception V3模型,从开始就是模型需要定义的。首先,对的每一个通道分别做一个GlobalAveragePooling。经过这个操作之后,变成一个向量,然后直接做一个以两神经元为输出节点的全连接层,把它赋给predictions变量。至此有了输入和输出,输入是base_model.  output,输出是predictions。

(3)将别人训练好的权重也迁移学习过来,此时只需要使用命令layer.Trainable=false即可,也就是不要再训练模型,这意味着当年在ImageNet上训练出来的权重都被继承下来了,使用model.summary()查看模型结构。具体如代码示例6-24所示。

代码示例6-24:迁移学习模型构建

from keras.applications.inception_v3 import InceptionV3
from keras.layers import GlobalAveragePooling2D, Dense, Activation
from keras import Model

base_model = InceptionV3(weights='imagenet', include_top=False)
x = base_model.output
x = GlobalAveragePooling2D()(x)
predictions = Dense(2,activation='softmax')(x)
model=Model(inputs=base_model.input, outputs=predictions)
for layer in base_model.layers:
     layer.trainable = False
model.summary()

输出:

keras神经风格迁移_深度学习入门 | 第六章:经典卷积神经网络:迁移学习_第5张图片 d52fbfcc81d456087b2d535f6d279428.gif

4.迁移模型的编译运行

模型的训练和拟合都和以前完全一样,尝试做10个epoch循环,学习率设置为0.001,可以看到外样本预测精度很快就达到98%左右,这就是迁移学习的魅力,我们站在前人的肩膀上,轻松获得了相当不错的结果。具体如代码示例6-25所示。

代码示例6-25:迁移学习模型的编译与拟合

from keras.optimizers import Adam
model.compile(loss='categorical_crossentropy',optimizer=Adam(lr=0.001),
metrics=['accuracy'])
model.fit_generator(train_generator,epochs=1,validation_data=validation_
generator)

输出:

keras神经风格迁移_深度学习入门 | 第六章:经典卷积神经网络:迁移学习_第6张图片 d52fbfcc81d456087b2d535f6d279428.gif

最后总结一下,由于深度学习面临很多现实的困难,如模型太多且计算资源昂贵,从而使初学者产生一个需求:是否可以利用前人沉淀下的研究结果来完成自己的任务,迁移学习因此产生。简单的说,迁移学习就是继承了前人的模型结构和参数训练结果,将其应用在自己的模型中,从而得到快速且相对准确的预测结果。在未来的学习中,读者可以不断尝试和感受迁移学习带来的便利性。

7b5b9bbf058006203ec03e719ecd6f84.png往期精彩第1章:深度学习简介第2章:神经网络基础(1)第2章:神经网络基础(2)第3章:神经网络的TensorFlow实现(1)第3章:神经网络的TensorFlow实现(2)第3章:神经网络的TensorFlow实现(3)第4章:卷积神经网络基础(1)第4章:卷积神经网络基础(2)第4章:卷积神经网络基础(3)第5章:经典卷积神经网络:LeNet+AlexNet第5章:经典卷积神经网络:VGG与Batch Normalization第6章:经典卷积神经网络:Inception第6章:经典卷积神经网络:ResNet第6章:经典卷积神经网络:DenseNet第6章:经典卷积神经网络:MobileNet点击“查看原文”获取更多

你可能感兴趣的:(keras神经风格迁移)