keras_12_keras自带的Applications

1. 关于Application

  • Keras 的应用模块(keras.applications)提供了带有预训练权值的深度学习模型,这些模型可以用来进行预测、特征提取和微调(fine-tuning)。当你初始化一个预训练模型时,会自动下载权值到 ~/.keras/models/ 目录下。

2. keras内置的Model

  • 在 ImageNet 上预训练过的用于图像分类的模型:
VGG16
VGG19
Xception
ResNet50
InceptionV3
InceptionResNetV2
MobileNet
DenseNet
NASNet
  • 所有的这些模型(除了 Xception 和 MobileNet 外)都兼容Theano和Tensorflow,并会自动按照位于 ~/.keras/keras.json 的配置文件中设置的图像数据格式来构建模型。举个例子,如果你设置 image_data_format=channels_last,则加载的模型将按照 TensorFlow 的维度顺序来构造,即“高度-宽度-深度”(Height-Width-Depth)的顺序。
  • Xception 模型仅适用于 TensorFlow,因为它依赖于 SeparableConvolution 层。MobileNet 模型仅适用于 TensorFlow,因为它依赖于 DepthwiseConvolution 层。

3. 一些例子

  1. 使用 ResNet50 进行 ImageNet 分类

    from keras.applications.resnet50 import ResNet50
    from keras.preprocessing import image
    from keras.applications.resnet50 import preprocess_input, decode_predictions
    import numpy as np
    
    model = ResNet50(weights='imagenet')
    
    img_path = 'elephant.jpg'
    img = image.load_img(img_path, target_size=(224, 224))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)
    
    preds = model.predict(x)
    # decode the results into a list of tuples (class, description, probability)
    # (one such list for each sample in the batch)
    print('Predicted:', decode_predictions(preds, top=3)[0])
    # Predicted: [(u'n02504013', u'Indian_elephant', 0.82658225), (u'n01871265', u'tusker', 0.1122357), (u'n02504458', u'African_elephant', 0.061040461)]
    
  2. 使用 VGG16 提取特征

    from keras.applications.vgg16 import VGG16
    from keras.preprocessing import image
    from keras.applications.vgg16 import preprocess_input
    import numpy as np
    
    model = VGG16(weights='imagenet', include_top=False)
    
    img_path = 'elephant.jpg'
    img = image.load_img(img_path, target_size=(224, 224))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)
    
    features = model.predict(x)
    
  3. 从VGG19的任意中间层中抽取特征

    from keras.applications.vgg19 import VGG19
    from keras.preprocessing import image
    from keras.applications.vgg19 import preprocess_input
    from keras.models import Model
    import numpy as np
    
    base_model = VGG19(weights='imagenet')
    model = Model(inputs=base_model.input, outputs=base_model.get_layer('block4_pool').output) # 自定义用于输出中间层的Model
    
    img_path = 'elephant.jpg'
    img = image.load_img(img_path, target_size=(224, 224))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)
    
    block4_pool_features = model.predict(x)
    
  4. 在新类上微调 InceptionV3

    from keras.applications.inception_v3 import InceptionV3
    from keras.preprocessing import image
    from keras.models import Model
    from keras.layers import Dense, GlobalAveragePooling2D
    from keras import backend as K
    
    # 构建不带分类器的预训练模型
    base_model = InceptionV3(weights='imagenet', include_top=False) # include_top ?
    
    # 添加全局平均池化层
    x = base_model.output
    x = GlobalAveragePooling2D()(x)
    
    # 添加一个全连接层
    x = Dense(1024, activation='relu')(x)
    
    # 添加一个分类器,假设我们有200个类
    predictions = Dense(200, activation='softmax')(x)
    
    # 构建我们需要训练的完整模型
    model = Model(inputs=base_model.input, outputs=predictions)
    
    # 首先,我们只训练顶部的几层(随机初始化的层)
    # 锁住所有 InceptionV3 的卷积层
    for layer in base_model.layers:
        layer.trainable = False
    
    # 编译模型(一定要在锁层以后操作)
    model.compile(optimizer='rmsprop', loss='categorical_crossentropy')
    
    # 在新的数据集上训练几代
    model.fit_generator(...)
    
    # 现在顶层应该训练好了,让我们开始微调 Inception V3 的卷积层。
    # 我们会锁住 Inception V3 中底下的几层,然后训练其余的顶层。(因为底层都是低级语义,可共享)
    
    # 让我们看看每一层的名字和层号,看看我们应该锁多少层呢:
    for i, layer in enumerate(base_model.layers):
       print(i, layer.name)
    
    # 我们选择训练最上面的两个 Inception block
    # 也就是说锁住前面249层,然后放开之后的层。
    for layer in model.layers[:249]:
       layer.trainable = False
    for layer in model.layers[249:]:
       layer.trainable = True
    
    # 我们需要重新编译模型,才能使上面的修改生效
    # 让我们设置一个很低的学习率,使用 SGD 来微调
    from keras.optimizers import SGD
    model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy')
    
    # 我们继续训练模型,这次我们训练最后两个 Inception block
    # 和两个全连接层
    model.fit_generator(...)
    
  5. 通过自定义输入 tensor 构建 InceptionV3

    from keras.applications.inception_v3 import InceptionV3
    from keras.layers import Input
    
    # this could also be the output a different Keras model or layer
    input_tensor = Input(shape=(224, 224, 3))  # this assumes K.image_data_format() == 'channels_last'
    
    model = InceptionV3(input_tensor=input_tensor, weights='imagenet', include_top=True)
    

4. 内置模型的性能概览

模型大小Top-1 准确率Top-5 准确率参数数量深度
Xception88 MB0.7900.94522,910,480126
VGG16528 MB0.7150.901138,357,54423
VGG19549 MB0.7270.910143,667,24026
ResNet5099 MB0.7590.92925,636,712168
InceptionV392 MB0.7880.94423,851,784159
InceptionResNetV2215 MB0.8040.95355,873,736572
MobileNet17 MB0.6650.8714,253,86488
DenseNet12133 MB0.7450.9188,062,504121
DenseNet16957 MB0.7590.92814,307,880169
DenseNet20180 MB0.7700.93320,242,984201
  • Top-1 准确率和 Top-5 准确率都是在 ImageNet 验证集上的结果。

  • Xception:

    • ImageNet预训练的 Xception V1 模型
    • 注意,该模型目前仅能在 TensorFlow 后端使用,因为它依赖 SeparableConvolution 层,目前该层只支持 channels_last 的维度顺序(高度、宽度、通道)。模型默认图片输入尺寸是 299x299。
  • VGG16:

    • VGG16 模型,权值由 ImageNet训练(不是预训练)而来。
    • 该模型在 TheanoTensorFlow 后端均可使用,并接受 channels_firstchannels_last 两种输入维度顺序(高度,宽度,通道)。模型默认输入尺寸是 224x224。
    • 预训练权值VGG at Oxford 发布的预训练权值移植而来,基于 Creative Commons Attribution License
  • VGG19:

    • VGG19 模型,权值由 **ImageNet ** 训练而来。
    • 该模型在 TheanoTensorFlow 后端均可使用,并接受 channels_firstchannels_last 两种输入维度顺序(高度,宽度,通道)。模型默认输入尺寸是 224x224。
    • 预训练权值由 VGG at Oxford 发布的预训练权值移植而来,基于 Creative Commons Attribution License
  • ResNet50:

    • ResNet50 模型,权值由 ImageNet 训练而来。
    • 该模型在 TheanoTensorFlow 后端均可使用,并接受 channels_firstchannels_last 两种输入维度顺序(高度,宽度,通道)。模型默认输入尺寸是 224x224。
    • 预训练权值由 Kaiming He 发布的预训练权值移植而来,基于 MIT license
  • InceptionV3:

    • nception V3 模型,权值由 ImageNet 训练而来。
    • 该模型在 TheanoTensorFlow 后端均可使用,并接受 channels_firstchannels_last 两种输入维度顺序(高度,宽度,通道)。模型默认输入尺寸是 299x299。
    • 预训练权值基于 Apache License
  • InceptionResNetV2:

    • Inception-ResNet V2 模型,权值由 ImageNet 训练而来。
    • 该模型在 TheanoTensorFlow 后端均可使用,并接受 channels_firstchannels_last 两种输入维度顺序(高度,宽度,通道)。模型默认输入尺寸是 299x299。
    • 预训练权值基于 Apache License
  • MobileNet:

    • 在 ImageNet 上预训练的 MobileNet 模型。

    • 注意,该模型目前仅能在 TensorFlow 后端使用,因为它依赖 SeparableConvolution 层,目前该层只支持 channels_last 的维度顺序(高度、宽度、通道)。要通过 load_model 载入 MobileNet 模型,你需要导入自定义对象 relu6DepthwiseConv2D 并通过 custom_objects 传参。模型默认输入尺寸是 224x224.

      model = load_model('mobilenet.h5', custom_objects={
                         'relu6': mobilenet.relu6,
                         'DepthwiseConv2D': mobilenet.DepthwiseConv2D})
      
    • 预训练权值基于 Apache License

  • DenseNet:

    • 可以选择载入在 ImageNet 上的预训练权值。如果你在使用 TensorFlow 为了发挥最佳性能,请在 ~/.keras/keras.json 的 Keras 配置文件中设置 image_data_format='channels_last'

      模型和权值兼容 TensorFlow、Theano 和 CNTK。可以在你的 Keras 配置文件中指定数据格式。

    • 预训练权值基于 BSD 3-clause License

  • NASNet:

    • 在 ImageNet 上预训练的神经结构搜索网络模型(NASNet)。
    • 注意,该模型目前仅能在 TensorFlow 后端使用,因此它只支持 channels_last 的维度顺序(高度、宽度、通道),可以在 ~/.keras/keras.json Keras 配置文件中设置。NASNetLarge 默认的输入尺寸是 331x331,NASNetMobile 默认的输入尺寸是 224x224。
    • 预训练权值基于 Apache License