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. 一些例子
-
使用 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)]
-
使用 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)
-
從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)
-
在新類上微調 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(...)
-
通過自定義輸入 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 准確率 | 參數數量 | 深度 |
---|---|---|---|---|---|
Xception | 88 MB | 0.790 | 0.945 | 22,910,480 | 126 |
VGG16 | 528 MB | 0.715 | 0.901 | 138,357,544 | 23 |
VGG19 | 549 MB | 0.727 | 0.910 | 143,667,240 | 26 |
ResNet50 | 99 MB | 0.759 | 0.929 | 25,636,712 | 168 |
InceptionV3 | 92 MB | 0.788 | 0.944 | 23,851,784 | 159 |
InceptionResNetV2 | 215 MB | 0.804 | 0.953 | 55,873,736 | 572 |
MobileNet | 17 MB | 0.665 | 0.871 | 4,253,864 | 88 |
DenseNet121 | 33 MB | 0.745 | 0.918 | 8,062,504 | 121 |
DenseNet169 | 57 MB | 0.759 | 0.928 | 14,307,880 | 169 |
DenseNet201 | 80 MB | 0.770 | 0.933 | 20,242,984 | 201 |
-
Top-1 准確率和 Top-5 准確率都是在 ImageNet 驗證集上的結果。
-
Xception:
- 在 ImageNet 上預訓練的 Xception V1 模型
- 注意,該模型目前僅能在 TensorFlow 后端使用,因為它依賴
SeparableConvolution
層,目前該層只支持channels_last
的維度順序(高度、寬度、通道)。模型默認圖片輸入尺寸是 299x299。
-
VGG16:
- VGG16 模型,權值由 ImageNet 訓練(不是預訓練)而來。
- 該模型在
Theano
和TensorFlow
后端均可使用,並接受channels_first
和channels_last
兩種輸入維度順序(高度,寬度,通道)。模型默認輸入尺寸是 224x224。 - 預訓練權值由 VGG at Oxford 發布的預訓練權值移植而來,基於 Creative Commons Attribution License。
-
VGG19:
- VGG19 模型,權值由 **ImageNet ** 訓練而來。
- 該模型在
Theano
和TensorFlow
后端均可使用,並接受channels_first
和channels_last
兩種輸入維度順序(高度,寬度,通道)。模型默認輸入尺寸是 224x224。 - 預訓練權值由 VGG at Oxford 發布的預訓練權值移植而來,基於 Creative Commons Attribution License。
-
ResNet50:
- ResNet50 模型,權值由 ImageNet 訓練而來。
- 該模型在
Theano
和TensorFlow
后端均可使用,並接受channels_first
和channels_last
兩種輸入維度順序(高度,寬度,通道)。模型默認輸入尺寸是 224x224。 - 預訓練權值由 Kaiming He 發布的預訓練權值移植而來,基於 MIT license。
-
InceptionV3:
- nception V3 模型,權值由 ImageNet 訓練而來。
- 該模型在
Theano
和TensorFlow
后端均可使用,並接受channels_first
和channels_last
兩種輸入維度順序(高度,寬度,通道)。模型默認輸入尺寸是 299x299。 - 預訓練權值基於 Apache License。
-
InceptionResNetV2:
- Inception-ResNet V2 模型,權值由 ImageNet 訓練而來。
- 該模型在
Theano
和TensorFlow
后端均可使用,並接受channels_first
和channels_last
兩種輸入維度順序(高度,寬度,通道)。模型默認輸入尺寸是 299x299。 - 預訓練權值基於 Apache License。
-
MobileNet:
-
在 ImageNet 上預訓練的 MobileNet 模型。
-
注意,該模型目前僅能在 TensorFlow 后端使用,因為它依賴
SeparableConvolution
層,目前該層只支持channels_last
的維度順序(高度、寬度、通道)。要通過load_model
載入 MobileNet 模型,你需要導入自定義對象relu6
和DepthwiseConv2D
並通過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。