【Keras版本】:2.2.2,推荐阅读下官方中文网站的 Demo :https://keras-cn.readthedocs.io/en/latest/other/application/#inceptionv3
【适用场合】:
没有硬件:例如众所周知的Inception v3模型,此模型在一台配有 8 Tesla K40 GPUs,大概价值$30,000的野兽级计算机上,训练了几个星期。你有这样的硬件么?
没有数据:针对特定问题,训练模型的前提是数据!以太阳能电池板隐裂缺陷检测为例,太阳能电池板整体缺陷率为0.2%左右,包括10+种缺陷,训练一个能满足工业需求的模型需要多少数据?1千,1万,10万还是多少,假设需要1000张缺陷数据,那就要从至少50万片图像中选取,你能得到这么多数据么?
那怎么办?——用别人训练好的模型+少量数据进行模型训练,在短时间内训练得出满意的效果。这便是迁移学习。
【迁移学习分类】:分为两种
1 第一种 Transfer Learning:训练时,移掉最顶层,换上新的顶层,比如输出为10的全连接层。训练时只训练最后两层,其它层设置为不可训练,把下载的模型当成一个特征提取器。
【疑问】:传言具有相同分布的数据可以使用迁移学习获得很好的效果,不同分布效果不好!那么,怎么判断数据具有相同分布?
2 第二种 Fine Tune,换一个新的顶层,但在训练的过程中,所有的或大部分层都会经过训练。
【迁移学习的基本过程】
典型的迁移学习过程:首先通过Transfer Learning对新的数据集进行训练,训练过一定epoch之后,改用Fine Tune方法继续训练,同时降低学习率。
这样做是因为如果一开始就采用Fine Tune方法的话,后段网络还没有适应新的数据,那么在进行参数更新的时候,比较大的梯度可能会导致原本训练的比较好的参数被污染,反而导致效果下降。
【导入相应的模块】
1 import keras 2 from keras.datasets import cifar10 3 from keras.preprocessing.image import ImageDataGenerator #导入图像数据预处理模块中的图像增强类 ImageDataGenerator 4 from keras.applications.inception_v3 import InceptionV3 5 from keras.layers import Dense, Input, GlobalAveragePooling2D 6 from keras.models import Model
【数据增强与准备数据集】:下载地址:https://download.csdn.net/download/tsyccnh/10641502 ,网友辛苦整理的,我就不把我下载的分享了
当数据集较大时,不适合一次将全部数据载入到内存中,所以使用了Keras 框架中图像增强部分的ImageDataGenerator
类的flow_from_directory方法构建了一个生成器,按批次从硬盘读取图像数据,并实时进行图像增强。
flow_from_directory以文件夹路径为参数,生成经过数据提升/归一化后的数据,在一个无限循环中无限产生batch数据。
1 #数据增强设置 2 train_datagen = ImageDataGenerator( 3 rescale=1./255, 4 shear_range=0.2, 5 zoom_range=0.2, 6 horizontal_flip=True) 7 vali_datagen = ImageDataGenerator(rescale=1./255) 8 9 #使用文件夹下的数据作为数据集 10 train_generator = train_datagen.flow_from_directory(directory=r'C:\Users\Administrator\Downloads\flowers17\train', 11 target_size=(299,299),#Inception V3规定大小 12 batch_size=64) 13 vali_generator = vali_datagen.flow_from_directory(directory=r'C:\Users\Administrator\Downloads\flowers17\validation', 14 target_size=(299,299), 15 batch_size=64)
【模式设置】:GAP_LAYER 设置请参考 https://blog.csdn.net/tsyccnh/article/details/78889838
1 #两种模式 2 #设置模型参数不可更新 3 def set_model_to_transfer_learning(model,base_model):#base_model 4 for layer in base_model.layers: 5 layer.trainable = False 6 #from keras.optimizers import SGD 7 #model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy') #官方示例工程中设置的优化器 8 model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy']) 9 #***********************************************************************# 10 # 编译时指定优化器 11 # 优化器可以定制,学习率在优化器定制时可以设置 12 #***********************************************************************# 13 #设置模型为全局调优 14 def set_model_to_fine_tune(model,base_model): 15 GAP_LAYER = 17 # max_pooling_2d_2 16 for layer in base_model.layers[:GAP_LAYER+1]: 17 layer.trainable = False 18 for layer in base_model.layers[GAP_LAYER+1:]: 19 layer.trainable = True 20 model.compile(optimizer=Adagrad(lr=0.0001),loss='categorical_crossentropy',metrics=['accuracy'])
【定义模型】
1 #构建定制的Inception v3 模型:分三步 2 3 #第一步:导入基础模型和模型参数 4 5 #前方高能,下载超慢!80多兆,我这要下载34小时! 6 #解决办法,使用迅雷下载下来,替换掉 C:\Users\Administrator\.keras\models下的同名文件 7 #下载路径会在下载超时报错时显示 8 base_model = InceptionV3(weights='imagenet',include_top=False) #加载模型,weights 表示下载模型参数,include 设置表示不包含顶层,即后面的全连接层 9 #base_model.summary();#先看下basemodel的结构 10 11 #第二步:更改最后几层 12 # 增加新的输出层 13 # 首先获得base_model的输出 14 # 增加 15 base_output = base_model.output 16 global_average= GlobalAveragePooling2D()(base_output) # 全局平均池化[*]这里会将前面 M*N*C 的张量转变为1*N的张量。全局平均池化的目的是为了替换全连接层,简化模型 17 # 18 dense = Dense(1024,activation='relu')(global_average) 19 output = Dense(17,activation='softmax')(dense) 20 model = Model(inputs=base_model.input,outputs=output)# 创建最终的模型 21 # plot_model(model,'tlmodel.png')
【第一轮训练】
1 #首先:使用第一种迁移学习方式,base_model参数保持不变,只有增加的最后一层参数更新 2 set_model_to_transfer_learning(model,base_model) 3 #在新的数据集上迭代训练 4 model.fit_generator(generator=train_generator, 5 steps_per_epoch=800,#800 6 epochs=2,#2 7 validation_data=vali_generator, 8 validation_steps=12,#12 9 class_weight='auto' 10 )
【第二轮训练】
1 #然后:使用第二种迁移学习方式,全局调优 2 set_model_to_fine_tune(model,base_model) 3 #继续迭代训练 4 model.fit_generator(generator=train_generator, 5 steps_per_epoch=800, 6 epochs=2, 7 validation_data=vali_generator, 8 validation_steps=1, 9 class_weight='auto') 10 11 model.save('./flowers17_iv3_ft.h5') #保存模型
【注意】:CPU训练太慢,建议使用GPU训练