Python深度学习10——Keras实现迁移学习

 参考书目:陈允杰.TensorFlow与Keras——Python深度学习应用实战.北京:中国水利水电出版社,2021

本系列基本不讲数学原理,只从代码角度去让读者们利用最简洁的Python代码实现深度学习方法。


迁移学习是指将那些别人研究训练好的厉害的网络拿来直接用,在自己的数据集上简单训练微调一下就可以用来做自己的数据集分类。下面展示两个网络ResNet50和MobileNet在Cifar-10上的迁移学习。都是图片分类的案例。文本类型的模型也有,但是较为复杂,以后再出。


ResNet50迁移学习

首先导入包和数据

import numpy as np
from keras.datasets import cifar10
from tensorflow.keras.applications.resnet50 import ResNet50, preprocess_input
from tensorflow.keras.applications import MobileNet
from keras.models import Sequential
from keras.layers import Dense, Dropout, GlobalAveragePooling2D
from tensorflow.keras.utils import to_categorical
from PIL import Image
# 指定乱数种子
seed = 10
np.random.seed(seed)
# 载入数据集  
(X_train, Y_train), (X_test, Y_test) = cifar10.load_data()
# 打乱 2 个 Numpy 阵列
def randomize(a, b):
    permutation = list(np.random.permutation(a.shape[0]))
    shuffled_a = a[permutation]
    shuffled_b = b[permutation]
    return shuffled_a, shuffled_b

由于数据量太大,只取10%数据

X_train, Y_train = randomize(X_train, Y_train)
X_test, Y_test = randomize(X_test, Y_test)
#  取出10%训练, 10%测试
X_train = X_train[:5000]
Y_train = Y_train[:5000]
X_test = X_test[:1000]
Y_test = Y_test[:1000]
# One-hot编码
Y_train = to_categorical(Y_train, 10)
Y_test = to_categorical(Y_test, 10)

进行训练,将迁移模型对数据进行转化

#  载入ResNet50 模型
resnet_model = ResNet50(weights="imagenet",
                        include_top=False,
                        input_shape=(200, 200, 3))
# 调整X_train的图片尺寸
print("调整X_train的图片尺寸...")
X_train_new = np.array(
  [np.asarray(Image.fromarray(X_train[i]).resize(
          (200, 200))) for i in range(0, len(X_train))])
X_train_new = X_train_new.astype("float32")
# 训练数据的数据前处理
train_input = preprocess_input(X_train_new)
# 使用 ResNet50 模型预测训练数据的特征数据 
print("使用 ResNet50 模型预测训练数据的特征数据 ...")
train_features = resnet_model.predict(train_input)

测试集一样

# 调整X_test的图片尺寸 
print("调整X_test的图片尺寸...")
X_test_new = np.array([np.asarray(Image.fromarray(X_test[i]).resize((200, 200))) for i in range(0, len(X_test))])
X_test_new = X_test_new.astype("float32")
# 测试数据的数据前处理 
test_input = preprocess_input(X_test_new)
# 使用 ResNet50 模型预测测试数据的特征数据 
print("使用 ResNet50 模型预测测试数据的特征数据 ...")
test_features = resnet_model.predict(test_input)

构建并训练分类模型

# 定义模型
model = Sequential()
model.add(GlobalAveragePooling2D(
        input_shape=train_features.shape[1:]))
model.add(Dropout(0.5))
model.add(Dense(10, activation="softmax"))
#编译模型
model.compile(loss="categorical_crossentropy", optimizer="adam",metrics=["accuracy"])
#训练模型
history = model.fit(train_features, Y_train,validation_data=(test_features, Y_test), 
                    epochs=14, batch_size=32, verbose=1)

评估

# 评估模型
print("\nTesting ...")
loss, accuracy = model.evaluate(test_features, Y_test)
print("测试数据集的准确度 = {:.2f}".format(accuracy))

画损失变化

#显示图表来分析模型的训练过程
import matplotlib.pyplot as plt
# 显示训练和验证损失
loss = history.history["loss"]
epochs = range(1, len(loss)+1)
val_loss = history.history["val_loss"]
plt.plot(epochs, loss, "bo-", label="Training Loss")
plt.plot(epochs, val_loss, "ro--", label="Validation Loss")
plt.title("Training and Validation Loss")
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.legend()
plt.show()

画准确率变化

# 显示训练和验证准确度  
acc = history.history["accuracy"]
epochs = range(1, len(acc)+1)
val_acc = history.history["val_accuracy"]
plt.plot(epochs, acc, "bo-", label="Training Acc")
plt.plot(epochs, val_acc, "ro--", label="Validation Acc")
plt.title("Training and Validation Accuracy")
plt.xlabel("Epochs")
plt.ylabel("Accuracy")
plt.legend()
plt.show()

MobileNet迁移学习

前面预处理是一样的,就是模型预训练和定义不一样:

mobilenet_model = MobileNet(weights="imagenet",
                            include_top=False,
                            input_shape=(224, 224, 3))
#调整X_train的图片尺寸
print("调整X_train的图片尺寸...")
X_train_new = np.array(
  [np.asarray(Image.fromarray(X_train[i]).resize(
          (224, 224))) for i in range(0, len(X_train))])
X_train_new = X_train_new.astype("float32")
# 训练数据的数据前处理 
train_input = preprocess_input(X_train_new)
# 调整X_test的图片尺寸
print("调整X_test的图片尺寸...")
X_test_new = np.array(
  [np.asarray(Image.fromarray(X_test[i]).resize(
          (224, 224))) for i in range(0, len(X_test))])
X_test_new = X_test_new.astype("float32")
# 测试数据的数据前处理
test_input = preprocess_input(X_test_new)
# 定义模型
model = Sequential()
model.add(mobilenet_model)
model.add(Dropout(0.5))
model.add(GlobalAveragePooling2D())
model.add(Dropout(0.5))
model.add(Dense(10, activation="softmax"))
model.summary()   # 示模型摘要资讯 
# 冻结上层模型
mobilenet_model.trainable = False
# 编译模型
model.compile(loss="categorical_crossentropy", optimizer="adam",
              metrics=["accuracy"])

后面的评估也是一样的

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阡之尘埃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值