python深度学习 微调模型与冻结部分层

       特征微调有助于提高深度学习的精度,而将卷积基(就是预先训练好的卷积模型)的前面大部分层冻结,只微调(此时的学习率也应该相应的调低)顶部更抽象的层---可以理解为更细节的特征

这样可以在一定程度上提高模型的识别精度,我的实验结果比原有的精度提高了4个点左右,从90%提高到94%

下面是全部的代码,很简单.

不过有个疑问:训练出来的验证精度达不到书上说的97%,有解决的同学请留言告知一下,不慎感激!!!

#即可单独安装keras,也可以用tensorflow自带的keras
try:
    from keras.applications import VGG16
    from keras.preprocessing.image import ImageDataGenerator
    from keras import models
    from keras import layers
    from keras import optimizers
except ModuleNotFoundError:
    import tensorflow as tf
    VGG16 = tf.keras.applications.VGG16
    ImageDataGenerator = tf.keras.preprocessing.image.ImageDataGenerator
    models = tf.keras.models
    layers = tf.keras.layers
    optimizers = tf.keras.optimizers
import os,sys
sys.path.append( os.pardir )  #为了找到上级目录common,import里面的工具
from common.file_arrange import get_dirs  #自定义的小工具
import numpy as np 
import matplotlib.pyplot as plt 

def get_convBase( input_shape=None ): 
    '''
    input_shape: tuple ,example:( 150,150,3 )
    从网络上下载已训练的模型
    '''
    return VGG16(
        weights='imagenet',
        include_top=False,
        input_shape=input_shape
    )

def get_generators( directorys,target_size,batch_size ):
    '''
    directory: tuple ("train_path","validation_path") 分别是两个目录,一个训练样本目录,一个测试样本目录
    target_size: "tuple" 缩放大小 example:( 150,150 )  所有图像缩放成150*150像素
    batch_size: "int"  每次在样本中抽取的批次大小
    '''
    #初始化一个训练generator对象(工厂) 使用数据增强
    train_datagen = ImageDataGenerator(
        rescale=1./255,
        zoom_range=0.2,
        rotation_range=40,
        width_shift_range=0.2,
        height_shift_range=0.2,
        shear_range=0.2,
        horizontal_flip=True,
        fill_mode='nearest'
    )
    #初始化一个测试generator实例,因为是验证推理的成功率,所以不使用数据增强
    val_datagen = ImageDataGenerator( rescale=1./255 )

    #得到一个用于训练的ImageDataGenerator实例
    train_generator = train_datagen.flow_from_directory(
        directorys[0],
        target_size=target_size,
        batch_size=batch_size,
        interpolation='nearest',
        class_mode='binary'
    )
    #得到一个用于验证的ImageDataGenerator实例
    val_generator = val_datagen.flow_from_directory(
        directorys[1],
        target_size=target_size,
        batch_size=batch_size,
        interpolation='nearest',
        class_mode='binary'
    )

    return train_generator,val_generator

def run_network():
    
    train_gener, test_gener = get_generators( ( get_dirs()['train'], get_dirs()['test'] ), (150,150), 20 )
    #生成一个欲训练模型
    conv_base = get_convBase( ( 150,150,3 ) )
    #冻结卷积层的可训练 权重
    conv_base.trainable =False

    model = models.Sequential()
    #将预训练的模型添加到新建模型里
    model.add( conv_base )
    model.add( layers.Flatten() )
    
    model.add( layers.Dense( 256,activation='relu' ) )#注意,这里不是第一层网络,所以不需要input_shape参数
    #model.add( layers.Dropout(0.5) )
    model.add( layers.Dense( 1,activation='sigmoid' ) )


    #配置训练模型
    model.compile( 
        optimizer=optimizers.RMSprop(lr = 2e-5),
        metrics=['acc'],
        loss='binary_crossentropy',
     )
     #将训练图片生成器.测试图片生成器送入fit_generator,并以设定的次数训练模型
    history=model.fit_generator(  
        train_gener,
        steps_per_epoch=100,
        epochs=30,
        validation_data=test_gener,
        validation_steps=50        
    )
    #微调模型
    conv_base.trainable=True
    set_trainable = False
    for layer in conv_base.layers:
        if layer.name == 'block5_conv1':  #block5_conv1后面的层都设为可训练
            set_trainable = True
        if set_trainable:
            layer.trainable = True
        else:
            layer.trainable = False
    model.compile(
        optimizer=optimizers.RMSprop(lr=1e-5), #以一个较小的学习率微调
        loss='binary_crossentropy',
        metrics=['acc']
    )
    history = model.fit_generator(
        train_gener,
        steps_per_epoch=100,
        epochs=77,
        validation_data=test_gener,
        validation_steps=50
    )

    epochs = range( 1, len( history.history['acc'] ) + 1 )

    plt.plot(epochs, history.history['acc'],'bo',label = 'train_acc' )
    plt.plot( epochs,history.history['val_acc'], 'b',label = 'validation_Acc' )
    plt.title( 'Training and validation Accuracy' )
    plt.legend()

    plt.figure()
    plt.plot( epochs,history.history['loss'],'bo',label='Train_loss' )
    plt.plot( epochs,history.history['val_loss'],'b',label='Validation_loss' )
    plt.legend()

    plt.show()

if __name__ == '__main__':
    run_network()
    #model = get_convBase( (150,150,3) )
    #model.summary()

python深度学习 微调模型与冻结部分层_第1张图片

python深度学习 微调模型与冻结部分层_第2张图片

python深度学习 微调模型与冻结部分层_第3张图片

你可能感兴趣的:(deep,learning,python,python,深度学习,图像识别)