五分类-迁移学习

由于移动云的图像分类效果不太理想,我将采用一种巧妙的方法——迁移学习来实现。即在预训练模型的基础上,采用101层的深度残差网络ResNet-101。

迁移学习

(1) 迁移学习简介

什么是迁移学习呢?百度词条给出了一个简明的定义:迁移学习是一种机器学习方法,就是把为任务 A 开发的模型作为初始点,重新使用在为任务 B 开发模型的过程中。以我们的图像分类任务为例:

假如任务A的任务是猫狗分类,任务B是要对老虎、狮子进行分类。可以发现,任务 A 和任务 B 存在大量的共享知识,比如这些动物都可以从毛发,体型,形态等方面进行辨别。因此在已经存在一个针对任务A训练好的模型前提下,在训练任务B的模型时,我们可以不从零开始训练,而是基于在任务 A 上获得的知识再进行训练。在这里,针对A任务已经训练好的模型参数称之为:预训练模型。

我的训练模型代码

from tensorflow.keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
from model import resnet101
import tensorflow as tf
import json
import os
import PIL.Image as im
import numpy as np
image_path =  "./Datasets/CIFAR100/"  # 数据集的路径
train_dir = image_path + "train"
validation_dir = image_path + "test"
im_height = 224
im_width = 224
batch_size =64
epochs = 5

_R_MEAN = 123.68
_G_MEAN = 116.78
_B_MEAN = 103.94

def pre_function(img):  # 图像预处理
    img = img - [_R_MEAN, _G_MEAN, _B_MEAN]
    return img
train_image_generator = ImageDataGenerator(horizontal_flip=True,
                                           preprocessing_function=pre_function)
train_data_gen = train_image_generator.flow_from_directory(directory=train_dir,
                                                           batch_size=batch_size,
                                                           shuffle=True,
                                                           target_size=(im_height, im_width),
                                                           class_mode='binary')
total_train = train_data_gen.n  # 训练集样本总数
validation_image_generator = ImageDataGenerator(preprocessing_function=pre_function)
val_data_gen = validation_image_generator.flow_from_directory(directory=validation_dir,
                                                              batch_size=batch_size,
                                                              shuffle=False,
                                                              target_size=(im_height, im_width),
                                                              class_mode='binary')
# img, _ = next(train_data_gen)
total_val = val_data_gen.n  # 验证集样本总数
class_indices = train_data_gen.class_indices
# 转换类别字典中键和值的位置
inverse_dict = dict((val, key) for key, val in class_indices.items())
# 将数字标签字典写入json文件:class_indices.json
json_str = json.dumps(inverse_dict, indent=4)
with open('class_indices.json', 'w') as json_file:
    json_file.write(json_str)

feature = resnet101(num_classes=3, include_top=False)
feature.load_weights('./model-resnet/pretrain_weights.ckpt')  # 加载预训练模型
feature.trainable = False  # 训练时冻结与训练模型参数
feature.summary()  # 打印预训练模型参数
model = tf.keras.Sequential([feature,
                             tf.keras.layers.GlobalAvgPool2D(),
                             tf.keras.layers.Dropout(rate=0.5),
                             tf.keras.layers.Dense(1024),
                             tf.keras.layers.Dropout(rate=0.5),
                             tf.keras.layers.Dense(105),
                             tf.keras.layers.Softmax()])
# model.build((None, 224, 224, 3))
model.summary()  # 打印增加层的参数
model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.001),
              loss='sparse_categorical_crossentropy',
              metrics=['acc'])
              
history = model.fit(
    train_data_gen,
    steps_per_epoch=100,
    epochs=100,
    validation_data=val_data_gen,
    validation_steps=100)

运行结果

posted @ 2021-05-26 22:33  晨起  阅读(210)  评论(0编辑  收藏  举报