Tensorflow2 | 50行代码的迁移学习实例

1. 问题描述

在mnist数据集上,用0~4的图片训练得到一个模型,用它来进行迁移学习———根据这个模型和少量的训练数据,得到一个可以预测5~9的数字图片的模型。(在0~4上训练得到原模型时,训练集的规模可能是每类有大约6000张图片,在5~9上做迁移学习的时候,每一类训练集的规模小得多,例如100张)

不过值得一提的是,这个小例子里用迁移学习,效果明显不如普通训练方法(训练数据量相同的情况下),这可能也是个反面案例,告诉我们迁移学习也不总是效果显著。

2. TF2做迁移学习的关键技术点

2.1 导入模型

TF2比TF1在导入模型上方便的多,TF1还要先导入计算图,再导入参数,TF2只需要导入一个h5模型文件就搞定了。

下面这个模型是事先训练好的模型,在大约6000张0~4测试集上的accuracy是99.14% 。

best_model=tf.keras.models.load_model("chapter11/q8/models/chapter11_q8_bestmodel.h5")

best_model 是五个隐层,每层140个神经元。TF2在导入公开的知名的模型的时候(例如MobileNetV2),可以通过参数 include_top是True or False 来决定是否导入输出层。

2.2 复用、冻结、替换某些层

2.1中导入的模型best_model,可以很方便的对它及它的各层进行操作:

#返回每个隐层的对象,是个list
best_model.layers   
#将第一层参数设置为不可变
best_model.layers[0].trainable=False   
####复用和替换某些层
#复用原模型的前若干层
l_layer=len(best_model.layers)
new_model=Sequential(best_model.layers[0:(l_layer-1)])  
#构造新的输出层
new_output=Dense(5,activation=tf.nn.softmax,kernel_initializer=tf.initializers.Constant(0.01))
#用原模型的前若干层和新的输出层合成新模型
new_model.add(new_output)

3.例子完整代码

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.datasets import mnist
import numpy as np
import time

first_K0=100			##迁移学习的时候用first_K0张5~9的图片进行训练
def find_index(array,List=[],first_K=100):   ##从原mnist数据集中选取标签为5~9的图片的坐标
    index=[]
    for i in List:
        if first_K==-1:
            index.extend(list(np.where(array==i)[0]))
        else:
            index.extend(list(np.where(array==i)[0])[0:first_K])
    return(index)
####数据准备和处理
(train_x,train_y),(test_x,test_y)=mnist.load_data()
train_x=train_x.reshape([-1,28*28])/255.0
test_x=test_x.reshape([-1,28*28])/255.0
index_train=find_index(train_y,[5,6,7,8,9],first_K=first_K0)   ##每种图片用first_K0张
index_test=find_index(test_y,[5,6,7,8,9],first_K=-1)                 ##测试图片全用
train_x,train_y=train_x[index_train,:],train_y[index_train]-5
test_x,test_y=test_x[index_test,:],test_y[index_test]-5
####导入模型
best_model=tf.keras.models.load_model("chapter11/q8/models/chapter11_q8_bestmodel.h5")
####更改模型输出层,冻结其他层
l_layer=len(best_model.layers)
new_model=Sequential(best_model.layers[0:(l_layer-1)])
new_output=Dense(5,activation=tf.nn.softmax,kernel_initializer=tf.initializers.Constant(0.01))
new_model.add(new_output)
####控制哪些层重新训练
for i in range(l_layer-1):
    new_model.layers[i].trainable=False
####compile模型
new_model.compile(optimizor="adam",
                  loss=tf.losses.SparseCategoricalCrossentropy(),
                  metric=['accuracy'])
####训练模型,输出相关信息
time0=time.time()
new_model.fit(train_x,train_y,verbose=2,epochs=5)
time1=time.time()
print("first_K = %d"%first_K0)
print("cost time = %.4f second"%(time1-time0))
print(np.mean(new_model.predict_classes(test_x)==test_y))

实验结果显示,只修改输出层,100张图片,epoch=5,准确率大概80%左右。逐步减少冻结的层数,同样是100张图片,epoch=5的情况下,训练效果会越来越好。这说明这个例子里用迁移学习效果并不好。

4.参考资料

TF2:迁移学习官方资料

  • 3
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值