keras 迁移学习 50% — at least 70%

1、从模型中间层级获取特征向量

# Step 1 , train a model and 
# model.save("demo.h5")

# Step 2 , load model and watch the coresponding layer name
base_model = load_model('demo.h5')
print(model.summary())
'''
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
reshape_1 (Reshape)          (None, 128, 128, 3)       0
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 128, 128, 32)      896
_________________________________________________________________
activation_1 (Activation)    (None, 128, 128, 32)      0
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 64, 64, 32)        0
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 64, 64, 32)        9248
_________________________________________________________________
activation_2 (Activation)    (None, 64, 64, 32)        0
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 32, 32, 32)        0
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 32, 32, 64)        18496
_________________________________________________________________
activation_3 (Activation)    (None, 32, 32, 64)        0
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 16, 16, 64)        0
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 16, 16, 64)        36928
_________________________________________________________________
activation_4 (Activation)    (None, 16, 16, 64)        0
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 8, 8, 64)          0
_________________________________________________________________
flatten_1 (Flatten)          (None, 4096)              0
_________________________________________________________________
dense_1 (Dense)              (None, 11)                45067
=================================================================
'''

# Step 3 , output the coresponding layer feature
model = Model(inputs=base_model.input, outputs=base_model.get_layer('flatten_1').output)
''' the following has the same influence
model = Model(inputs=base_model.input, outputs=base_model.get_layer(index=13).output)
'''
pred = model.predict(valid_x)
print(pred)

''' 打印所有 层的 name
for i, layer in enumerate(base_model.layers):
   print(i, layer.name)
'''

2、泛型式模型接口

# Keras的泛型模型为Model,即广义的拥有输入和输出的模型,我们使用Model来初始化一个泛型模型

from keras.models import Model
from keras.layers import Input, Dense

a = Input(shape=(32,))
b = Dense(32)(a)
model = Model(input=a, output=b)

3、VGG16迁移学习

###不迁移学习Valid最大准确率为50%,平均也就35-40之间,是11种事物的分类,每一种事物大概100张图片,数据集太少了,而且每一类食物的类型比较多,比如水果有苹果,香蕉,西瓜之类的。

import os
import cv2
import numpy as np
from keras.applications.vgg16 import VGG16
from sklearn.preprocessing import LabelBinarizer, MultiLabelBinarizer
from keras.layers import MaxPooling2D, Dense, Flatten , GlobalAveragePooling2D
from keras.preprocessing import image
from keras.optimizers import SGD
from keras.models import load_model
from keras.models import Model

def load_train_data_and_labels(dataSet= "./training"):
	images = []
	imagespaths = [str(dataSet + "/" + jpg) for jpg in os.listdir(dataSet)]
	labels = [jpg.split("_")[0]  for jpg in os.listdir(dataSet)]

	for imagePath in imagespaths:
		image = cv2.imread(imagePath)
		image = cv2.resize(image, (128, 128))
		images.append(image)

	labels = np.array(LabelBinarizer().fit_transform(labels) )
	images = np.array(images)
	return images, labels

def add_new_layer(base_model): # layer 19 - 22
	x = base_model.output
	x = MaxPooling2D()(x)
	x = Flatten()(x)
	# x = GlobalAveragePooling2D()(x)
	x = Dense(128, activation='relu')(x)
	predictions = Dense(11, activation='softmax')(x)
	return predictions

# create the base pre-trained model #defalut input 224 * 224 
base_model = VGG16(weights='imagenet', input_shape=(128, 128, 3), include_top=False) # 18 layers

# add new layer for TL
new_model = add_new_layer(base_model)

# the latest model
model = Model(inputs=base_model.input, outputs=new_model)

for layer in model.layers[:19]:
   layer.trainable = True
for layer in model.layers[19:]:
   layer.trainable = True

train_x, train_y = load_train_data_and_labels()

model.compile(optimizer=SGD(lr=0.0001), loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(train_x, train_y, batch_size=8, epochs=20, validation_split=0.1)

#经过迁移学习正确率第一次epoch的val_acc可以达到70%

猜你喜欢

转载自blog.csdn.net/qq_36336522/article/details/106871340
今日推荐