迁移学习---inceptionV3

一.迁移学习的概述

迁移学习是指将一个在某领域完成学习任务的网络应用到新的领域来进行学习任务。

基于卷积网络实现迁移学习

对于已经训练完毕的网络模型来说,通常该网络模型的前几层学习到的是通用特征,随着网络层次的加深,更深次的网络层更偏重于学习特定的特征,因此可将通用特征迁移到其他领域。对于深度卷积网络来说,经过预训练的网络模型可以实现网络结构与参数信息的分离,在保证网络结构一致的前提下,便可以利用经过预训练得到的权重参数初始化新的网络,这种方式可以极大地减少训练时间。

具体步骤如下:

①选定基于ImageNet训练完毕的网络模型

②用自己搭建的全连接层替换所选定网络模型的全连接层,得到新网络模型。

③新网络模型中固定所需层数的参数,在新的小样本下训练余下参数。

④新网络模型训练完毕

这种方式又称为微调,上述步骤的训练避免了网络模型针对新任务从头开始训练网络的环节,可节省时间。基于ImageNet训练完毕的网络模型泛华能力非常强,无形中扩充了训练数据,使得新网络模型提升了训练精度,泛化能力更好,鲁棒性更好。

二.InceptionV3实现迁移学习

inceptionV3结构是从GoogleNet中的inception结构演变而来,相比传统的inception结构,inceptionv3有如下改进:

①将大的卷积核分解为小的卷积核,如用两个3*3的卷积核代替5*5的卷积核,卷积运算次数得到减少。

②在辅助分类器中增加BN层有助于提高精度,起到正则化的效果。

③将inception block 中最后一层中的stride 设置为2来实现feature map size 的衰减。

inceptionV3将基于微调的方式实现迁移学习,在获取基于ImageNet预训练完毕的inception v3模型后,用自己搭建的全连接层(包括输出层)代替inception V3模型的全连接层和输出层,得到一个新的网络模型,进而固定新网络模型的部分参数,使其不参与训练,基于mnist数据集训练余下未固定的参数。

代码实现:

基于keras框架

from keras.datasets import mnist
from keras.applications.inception_v3 import InceptionV3
from keras.utils import np_utils
from keras.models import Model
from keras.layers import Dense,Dropout,Conv2D,MaxPooling2D,GlobalAveragePooling2D,Input,UpSampling3D
from matplotlib import pyplot as plt
import numpy as np

(X_train,Y_train),(X_test,Y_test)=mnist.load_data()
X_test1=X_test
Y_test1=Y_test
X_train=X_train.reshape(-1,28,28,1).astype("float32")/255.0
X_test=X_test.reshape(-1,28,28,1).astype("float32")/255.0
Y_test=np_utils.to_categorical(Y_test,10)
Y_train=np_utils.to_categorical(Y_train,10)
print(X_train.shape)
print(Y_train.shape)

#采用keras中函数api模型搭建新型网络即base_model
#weight="imagenet",xcception权重使用基于imagenet训练获得的权重,include_to=false代表不包含顶层的全连接层
base_model=InceptionV3(weights="imagenet",include_top=False)
input_inception=Input(shape=(28,28,1),dtype="float32",name="inceptionv3")
#对输入数据上采样
x=UpSampling3D(size=(3,3,3),data_format="channels_last")(input_inception)
#将数据送入model模型
x=base_model(x)
#此时模型没有全连接层,需要自己搭建全连接层
#通过GlobalAveragePooling2D对每张二维特征图进行全局平均池化,输出对应一维数值
x=GlobalAveragePooling2D()(x)
#搭建全连接层
x=Dense(1024,activation="relu")(x)
x=Dropout(0.5)(x)
pre=Dense(10,activation="softmax")(x)
#调用model模型,定义新的模型inceptionv3的输入层,输出层
inceptionv3_model=Model(inputs=input_inception,outputs=pre)
#打印base_model模型的各层名称和对应层数
for i,layer in enumerate(base_model.layers):
    print(i,layer.name)
#固定base_model前64层的参数使其不参与训练
for layer in base_model.layers[:64]:
    layer.trainable=False
#查看网络模型摘要
inceptionv3_model.summary()

#编译
inceptionv3_model.compile(
    loss="categorical_crossentropy",
    optimizer="adam",
    metrics=["accuracy"]
)
#训练
n_epoch=5
n_batches=64
training=inceptionv3_model.fit(
    X_train,
    Y_train,
    epochs=n_epoch,
    batch_size=n_batches,
    validation_split=0.2,
    verbose=1
)
#模型评估
test=inceptionv3_model.evaluate(X_test,Y_test,verbose=1)
print("误差:",test[0])
print("准确率:",test[1])

#画出inceptionv3_model模型的随时期epochs变化曲线
def plot_history(training_history,train,validation):
    plt.plot(training.history[train],linestyle="--",color="b")
    plt.plot(training.history[validation],linestyle="-",color="r")
    plt.title("training history")
    plt.xlabel("epochs")
    plt.ylabel("accuracy")
    plt.legend(["train","validation"],loc="lower right")
    plt.show()
plot_history(training,"accuracy","val_accuracy")

def plot_history1(training_history,train,validation):
    plt.plot(training.history[train],linestyle="--",color="b")
    plt.plot(training.history[validation],linestyle="-",color="r")
    plt.title("training history")
    plt.xlabel("epochs")
    plt.ylabel("loss")
    plt.legend(["train","validation"],loc="upper right")
    plt.show()
plot_history1(training,"loss","val_loss")

#预测
prediction=inceptionv3_model.predict(X_test)

#打印原图像
def plot_image(image):
    fig=plt.gcf()
    fig.set_size_inches(2,2)
    plt.imshow(image,cmap="binary")
    plt.show()
def pre_result(i):
    plot_image(X_test1[i])
    print("真实值:",Y_test[i])
    print("预测值:",np.argmax(prediction[i]))
pre_result(0)
pre_result(1)
pre_result(2)

 

 

 

你可能感兴趣的:(深度学习,keras)