美文网首页
vgg16\inceptionv3迁移学习

vgg16\inceptionv3迁移学习

作者: sunnylxs | 来源:发表于2018-01-15 10:08 被阅读0次

    很久之前就做完了这个实验,今天有时间整理记录下来!!

    首先要去网上下载好vgg16\inceptionv3  ——notop.h5的权重,通过其提取特征,不用输出层如果有没有下载成功的可以给我留言我发给你哦!!然后用cp将其拷贝到~/.keras/models/里面,数据集用的是猫狗2分类(kaggle train2000  test 550)

    import numpy as np

    np.random.seed(1337)

    import matplotlib.pyplot as plt

    from keras.preprocessing.image import ImageDataGenerator

    from keras.models import Sequential

    from keras.models import Model

    from keras.layers import Activation,Dropout, Flatten, Dense,AveragePooling2D

    from keras.layers import Conv2D,MaxPooling2D,Input

    from keras.applications.vgg16 import VGG16

    from keras import backend as K

    import matplotlib.pyplot as plt

    import h5py

    import os

    from keras.utils.vis_utils import plot_model

    os.environ['TF_CPP_MIN_LOG_LEVEL']='2'

    if(K.image_dim_ordering()=='th'):

        input_tensor=Input(shape=(3,200,200))

    else:

        input_tensor=Input(shape=(200,200,3))

    base_model=VGG16(input_tensor=input_tensor,weights='imagenet',include_top=False)

    x=base_model.output

    x=AveragePooling2D((4,4),padding='valid',name='avg_pool')(x)

    x=Flatten()(x)

    x=Dense(64,activation='relu')(x)

    x=Dropout(0.4)(x)

    predictions=Dense(2,activation='softmax')(x)

    model=Model(inputs=base_model.input,outputs=predictions)

    for layer in base_model.layers:

        layer.trainable=False

    print('model.summary:')

    #model.summary()

    model.compile(loss='categorical_crossentropy',

                  optimizer='adam',

                  metrics=['accuracy'])

    train_datagen=ImageDataGenerator(

        rescale=1./255,

        data_format='channels_last')

    test_datagen=ImageDataGenerator(

        rescale=1./255,

        data_format='channels_last')

    train_generator=train_datagen.flow_from_directory(

        'train',

        target_size=(200,200),

        batch_size=32,

        class_mode='categorical')

    validation_generator=test_datagen.flow_from_directory(

        'test',

        target_size=(200,200),

        batch_size=32,

        class_mode='categorical')

    history=model.fit_generator(

        train_generator,

        steps_per_epoch=30,

        epochs=10,

        validation_data=validation_generator,

        validation_steps=10,verbose=1

        )

    plot_model(model,to_file='model.png',show_shapes=True)

    plt.figure(1)

    plt.plot(history.history['acc'])

    plt.plot(history.history['val_acc'])

    plt.title('model accuracy')

    plt.ylabel('accuracy')

    plt.xlabel('epoch')

    plt.legend(['train','test'],loc='upper left')

    plt.figure(2)

    plt.plot(history.history['loss'])

    plt.plot(history.history['val_loss'])

    plt.title('model loss')

    plt.ylabel('loss')

    plt.xlabel('epoch')

    plt.legend(['train','test'],loc='upper left')

    plt.show()

    训练集的准确率达到0.8927,测试集达到0.8906

    下面是inceptionv3迁移学习的代码:

    import numpy as np

    np.random.seed(1337)

    from keras.preprocessing.image import ImageDataGenerator,array_to_img,img_to_array,load_img

    from keras.applications.inception_v3 import InceptionV3

    from keras.models import Model

    from keras.layers import Dropout, Flatten, Dense,AveragePooling2D,Input

    from keras import backend as K

    import matplotlib.pyplot as plt

    import h5py

    from keras.utils.vis_utils import plot_model

    import os

    os.environ['TF_CPP_MIN_LOG_LEVEL']='2'

    train_datagen=ImageDataGenerator(

        rescale=1./255,

        data_format='channels_last')

    test_datagen=ImageDataGenerator(

        rescale=1./255,

        data_format='channels_last')

    #train_img='./data/train/'

    #validation_img='./data/validation/'

    if(K.image_dim_ordering()=='th'):

        input_tensor=Input(shape=(3,200,200))

    else:

        input_tensor=Input(shape=(200,200,3))

    base_model=InceptionV3(input_tensor=input_tensor,weights='imagenet',include_top=False)

    x=base_model.output

    x=AveragePooling2D((4,4),padding='valid',name='avg_pool')(x)

    x=Dropout(0.4)(x)

    x=Flatten()(x)

    x=Dense(64,activation='relu')(x)

    predictions=Dense(2,activation='softmax')(x)

    model=Model(inputs=base_model.input,outputs=predictions)

    for layer in base_model.layers:

        layer.trainable=False

    print('model.summary:')

    #model.summary()

    model.compile(loss='categorical_crossentropy',

                  optimizer='rmsprop',

                  metrics=['accuracy'])

    train_generator=train_datagen.flow_from_directory(

        'train',

        target_size=(200,200),

        batch_size=32,

        class_mode='categorical')

    validation_generator=test_datagen.flow_from_directory(

        'test',

        target_size=(200,200),

        batch_size=32,

        class_mode='categorical')

    history=model.fit_generator(

        train_generator,

        steps_per_epoch=40,

        epochs=10,

        validation_data=validation_generator,

        validation_steps=10,verbose=1

        )

    plot_model(model,to_file='modelincepv3.png',show_shapes=True)

    plt.figure(1)

    plt.plot(history.history['acc'])

    plt.plot(history.history['val_acc'])

    plt.title('model accuracy')

    plt.ylabel('accuracy')

    plt.xlabel('epoch')

    plt.legend(['train','test'],loc='upper left')

    plt.figure(2)

    plt.plot(history.history['loss'])

    plt.plot(history.history['val_loss'])

    plt.title('model loss')

    plt.ylabel('loss')

    plt.xlabel('epoch')

    plt.legend(['train','test'],loc='upper left')

    plt.show()

    训练集0.89

    测试集0.95  ,过程中出现了过拟合,有待解决!

    启发:根据论文:A Deep Convolutional Activation Feature for Generic  Visual Recognition中的结论:可以保留训练好的VGG/Incepv3所有卷积层的参数,只是替换最后一层全连接层,在最后这一层全连接层之前的网络层称为瓶颈层。一般来说,在数据量足够的情况下,迁移学习的效果不如完全重新训练,但是迁移学习所需要的训练时间和和训练样本数要远远小于训练完整的模型。

    fine-tuning:使用已用于其他目标,预训练好模型的权重或部分权重,作为初始值开始训练

    why用:首先自己从头开始训练CNN容易出现问题,其次fine-tuning能很快收敛到一个较为理想的状态

    怎么做:一般复用相同层的权重,新定义层权重取随机初始值,注意调大新定义层的学习率,调小复用层的学习率

    https://blog.csdn.net/cai13160674275/article/details/71078554:从keras看VGG16结构图,里面有详细的参数计算过程和结构

    def VGG_16(weights_path=None):

        model = Sequential()

        model.add(ZeroPadding2D((1,1),input_shape=(3,224,224)))#卷积输入层,指定了输入图像的大小

        model.add(Convolution2D(64, 3, 3, activation='relu'))#64个3x3的卷积核,生成64*224*224的图像,激活函数为relu

        model.add(ZeroPadding2D((1,1)))#补0,保证图像卷积后图像大小不变,其实用padding = 'valid'参数就可以了

        model.add(Convolution2D(64, 3, 3, activation='relu'))#再来一次卷积 生成64*224*224

        model.add(MaxPooling2D((2,2), strides=(2,2)))#pooling操作,相当于变成64*112*112

        model.add(ZeroPadding2D((1,1)))

        model.add(Convolution2D(128, 3, 3, activation='relu'))

        model.add(ZeroPadding2D((1,1)))

        model.add(Convolution2D(128, 3, 3, activation='relu'))

        model.add(MaxPooling2D((2,2), strides=(2,2)))#128*56*56

        model.add(ZeroPadding2D((1,1)))

        model.add(Convolution2D(256, 3, 3, activation='relu'))

        model.add(ZeroPadding2D((1,1)))

        model.add(Convolution2D(256, 3, 3, activation='relu'))

        model.add(ZeroPadding2D((1,1)))

        model.add(Convolution2D(256, 3, 3, activation='relu'))

        model.add(MaxPooling2D((2,2), strides=(2,2)))#256*28*28

        model.add(ZeroPadding2D((1,1)))

        model.add(Convolution2D(512, 3, 3, activation='relu'))

        model.add(ZeroPadding2D((1,1)))

        model.add(Convolution2D(512, 3, 3, activation='relu'))

        model.add(ZeroPadding2D((1,1)))

        model.add(Convolution2D(512, 3, 3, activation='relu'))

        model.add(MaxPooling2D((2,2), strides=(2,2)))#512*14*14

        model.add(ZeroPadding2D((1,1)))

        model.add(Convolution2D(512, 3, 3, activation='relu'))

        model.add(ZeroPadding2D((1,1)))

        model.add(Convolution2D(512, 3, 3, activation='relu'))

        model.add(ZeroPadding2D((1,1)))

        model.add(Convolution2D(512, 3, 3, activation='relu'))

        model.add(MaxPooling2D((2,2), strides=(2,2)))  #到这里已经变成了512*7*7

        model.add(Flatten())#压平上述向量,变成一维25088

        model.add(Dense(4096, activation='relu'))#全连接层有4096个神经核,参数个数就是4096*25088

        model.add(Dropout(0.5))#0.5的概率抛弃一些连接

        model.add(Dense(4096, activation='relu'))#再来一个全连接

        model.add(Dropout(0.5))

        model.add(Dense(1000, activation='softmax'))

        if weights_path:

            model.load_weights(weights_path)

        return model

    相关文章

      网友评论

          本文标题:vgg16\inceptionv3迁移学习

          本文链接:https://www.haomeiwen.com/subject/qlvkoxtx.html