【火炉炼AI】深度学习010-Keras微调提高性能(多分类问题)

【火炉炼AI】深度学习010-Keras微调提高性能(多分类问题)

(本文所使用的Python库和版本号: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2, Keras 2.1.6, Tensorflow 1.9.0)git

前面的文章(【火炉炼AI】深度学习007-Keras微调进一步提高性能)咱们对二分类问题用Keras进行了Fine-tune,使得模型的准确率进一步提高,此处咱们看看对于多分类问题,怎么使用Fine-tune来提高性能。github


1. 准备数据集

和文章【火炉炼AI】深度学习008-Keras解决多分类问题如出一辙,在使用flow_from_directory时须要将class_mode修改成'categorical'。网络


2. 对VGG16的后半部分进行Fine-tune

此处咱们创建的模型是使用VGG16的身子(inclue_top=False)做为特征提取器,和咱们本身定义的头(前面文章【火炉炼AI】深度学习009-用Keras迁移学习提高性能(多分类问题)中训练的模型和weights),这篇文章中已经达到了0.96的准确率。可是在前面这篇文章的迁移学习中,咱们并无修改VGG16这个网络的weights参数,而是直接拿来提取特征,此处的Fine-tune就是要调整VGG16网络的较高层的卷积层的weights,使其更加适用于咱们本身的项目。app

以下是模型构建的函数:函数

# 4,构建模型
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense
from keras import applications
from keras import optimizers
from keras.models import Model
def build_model():
    base_model = applications.VGG16(weights='imagenet', include_top=False,input_shape=(IMG_W, IMG_H,IMG_CH))
    # 此处咱们只须要卷积层不须要全链接层,故而inclue_top=False,必定要设置input_shape,不然后面会报错
    # 这一步使用applications模块自带的VGG16函数直接加载了模型和参数,做为咱们本身模型的“身子”
    
    # 下面定义咱们本身的分类器,做为咱们本身模型的“头”
    top_model = Sequential()
    top_model.add(Flatten(input_shape=base_model.output_shape[1:])) 
    top_model.add(Dense(256, activation='relu'))
    top_model.add(Dropout(0.5))
    top_model.add(Dense(class_num, activation='softmax')) # 多分类问题
    
    top_model.load_weights(os.path.join(save_folder,'top_FC_model')) 
    # 上面定义了模型结构,此处要把训练好的参数加载进来,
    
    my_model = Model(inputs=base_model.input, outputs=top_model(base_model.output)) # 将“身子”和“头”组装到一块儿
    # my_model就是咱们组装好的完整的模型,也已经加载了各自的weights
    
    # 普通的模型须要对全部层的weights进行训练调整,可是此处咱们只调整VGG16的后面几个卷积层,因此前面的卷积层要冻结起来
    for layer in my_model.layers[:15]: # 15层以前都是不需训练的
        layer.trainable = False
        
    # 模型的配置
    my_model.compile(loss='categorical_crossentropy',
                  optimizer=optimizers.SGD(lr=1e-4, momentum=0.9), # 使用一个很是小的lr来微调
                  metrics=['accuracy'])
    return my_model
复制代码

-------------------------------------输---------出--------------------------------性能

start to fine-tune my model Epoch 1/50 8/8 [==============================] - 124s 16s/step - loss: 0.0170 - acc: 0.9950 - val_loss: 0.2767 - val_acc: 0.9700 Epoch 2/50 8/8 [==============================] - 131s 16s/step - loss: 3.2684e-04 - acc: 1.0000 - val_loss: 0.2694 - val_acc: 0.9700 Epoch 3/50 8/8 [==============================] - 131s 16s/step - loss: 0.0175 - acc: 0.9950 - val_loss: 0.2593 - val_acc: 0.9700学习

。。。大数据

Epoch 48/50 8/8 [==============================] - 132s 16s/step - loss: 0.0025 - acc: 1.0000 - val_loss: 0.2758 - val_acc: 0.9700 Epoch 49/50 8/8 [==============================] - 130s 16s/step - loss: 0.0080 - acc: 0.9950 - val_loss: 0.2922 - val_acc: 0.9700 Epoch 50/50 8/8 [==============================] - 131s 16s/step - loss: 4.7076e-04 - acc: 1.0000 - val_loss: 0.2875 - val_acc: 0.9700优化

--------------------------------------------完-------------------------------------ui

acc 和loss图为:

能够看出,test acc的准确率一直在0.97附近,在训练开始和结束时的acc和loss变化不大,说明对于这个项目,微调的性能提高并不明显,这是由于本项目所用的数据集过小,容易发生过拟合,经过增大数据集能够解决这些问题。

########################小**********结###############################

1,使用Fine-Tune来解决多分类问题时,须要将loss改为categorical_crossentropy,而且使用SGD优化器,使用很是小的learning rate,防止lr太大使得前面的卷积层网络结构发生较大改变。

#################################################################


注:本部分代码已经所有上传到(个人github)上,欢迎下载。

相关文章
相关标签/搜索