1. 程式人生 > >Keras遷移學習實現影象分類和特徵提取

Keras遷移學習實現影象分類和特徵提取

Kera的應用模組Application提供了帶有預訓練權重的Keras模型,這些模型可以用來進行預測、特徵提取和finetune

模型的預訓練權重將下載到~/.keras/models/並在載入模型時自動載入

可用的模型

所有的這些模型(除了Xception和MobileNet)都相容Theano和Tensorflow,並會自動基於~/.keras/keras.json的Keras的影象維度進行自動設定。例如,如果你設定data_format="channel_last",則載入的模型將按照TensorFlow的維度順序來構造,即“Width-Height-Depth”的順序

Xception模型僅在TensorFlow下可用,因為它依賴的SeparableConvolution層僅在TensorFlow可用。MobileNet僅在TensorFlow下可用,因為它依賴的DepethwiseConvolution層僅在TF下可用。

以上模型(暫時除了MobileNet)的預訓練權重可以在我的百度網盤下載,如果有更新的話會在這裡報告

圖片分類模型的示例

利用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)

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)

在新類別上fine-tune 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

# create the base pre-trained model
base_model = InceptionV3(weights='imagenet', include_top=False)

# add a global spatial average pooling layer
x = base_model.output
x = GlobalAveragePooling2D()(x)
# let's add a fully-connected layer
x = Dense(1024, activation='relu')(x)
# and a logistic layer -- let's say we have 200 classes
predictions = Dense(200, activation='softmax')(x)

# this is the model we will train
model = Model(inputs=base_model.input, outputs=predictions)

# first: train only the top layers (which were randomly initialized)
# i.e. freeze all convolutional InceptionV3 layers
for layer in base_model.layers:
    layer.trainable = False

# compile the model (should be done *after* setting layers to non-trainable)
model.compile(optimizer='rmsprop', loss='categorical_crossentropy')

# train the model on the new data for a few epochs
model.fit_generator(...)

# at this point, the top layers are well trained and we can start fine-tuning
# convolutional layers from inception V3. We will freeze the bottom N layers
# and train the remaining top layers.

# let's visualize layer names and layer indices to see how many layers
# we should freeze:
for i, layer in enumerate(base_model.layers):
   print(i, layer.name)

# we chose to train the top 2 inception blocks, i.e. we will freeze
# the first 249 layers and unfreeze the rest:
for layer in model.layers[:249]:
   layer.trainable = False
for layer in model.layers[249:]:
   layer.trainable = True

# we need to recompile the model for these modifications to take effect
# we use SGD with a low learning rate
from keras.optimizers import SGD
model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy')

# we train our model again (this time fine-tuning the top 2 inception blocks
# alongside the top Dense layers
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)

模型資訊

模型 大小 Top1準確率 Top5準確率 引數數目 深度
Xception 88MB 0.790 0.945 22,910,480 126
VGG16 528MB 0.715 0.901 138,357,544 23
VGG19 549MB 0.727 0.910 143,667,240 26
ResNet50 99MB 0.759 0.929 25,636,712 168
InceptionV3 92MB 0.788 0.944 23,851,784 159
IncetionResNetV2 215MB 0.804 0.953 55,873,736 572
MobileNet 17MB 0.665 0.871 4,253,864 88
MobileNetV2 14MB 0.713 0.901 3,538,984 88
DenseNet121 33MB 0.750 0.923 8,062,504 121
DenseNet169 57MB 0.762 0.932 14,307,880 169
DenseNet201 80MB 0.773 0.936 20,242,984 201
NASNetMobile 23MB 0.744 0.919 5,326,716 -
NASNetLarge 343MB 0.825 0.960 88,949,818 -