迁移学习:keras + vgg16 + cifar10 实现图像识别

框架:keras
数据集:CIFAR10
模型:vgg16
注:vgg16模型的输入图像尺寸至少为 48*48

思路:去掉vgg16的顶层,保留其余的网络结构与训练好的权重。然后添加模型结构,进而训练CIFAR10。

1.模型结构

在这里插入图片描述

2.具体代码以及注释

①训练代码

# -*- coding: utf-8 -*-
#迁移学习,vgg16+cifar10
from keras.applications.vgg16 import VGG16
from keras.layers import Dense, Flatten, Dropout
from keras.models import Model
from keras.optimizers import Adam
from keras.datasets import cifar10
import cv2                                       #加载opencv,为了后期的图像处理
from keras import datasets
import  h5py as h5py
import numpy as np
import matplotlib.pyplot as plt
import keras
from keras.utils import  plot_model
import matplotlib.pyplot as plt
from keras.callbacks import ModelCheckpoint
ishape = 64
model_vgg = VGG16(include_top=False, weights='imagenet', input_shape=(ishape,ishape, 3))
for layers in model_vgg.layers:
    layers.trainable = False
model = Flatten()(model_vgg.output)
model = Dense(4096, activation='relu',name='fc1')(model)
model = Dropout(0.5)(model)
model = Dense(4096, activation='relu',name='fc2')(model)
model = Dropout(0.5)(model)
model = Dense(10, activation='softmax',name='prediction')(model)
model_vgg_cifar10_pretrain = Model(inputs=model_vgg.input, outputs=model, name='vgg16_pretrain')
model_vgg_cifar10_pretrain.summary()
model_vgg_cifar10_pretrain.compile(optimizer='sgd', loss='categorical_crossentropy',
                                 metrics=['accuracy'])
(X_train,y_train),(X_test,y_test) = cifar10.load_data()
X_train = [cv2.resize(i,(ishape,ishape)) for i in X_train]
X_test = [cv2.resize(i,(ishape,ishape)) for i in X_test]
X_train  = np.concatenate([arr[np.newaxis] for arr in X_train] ).astype('float32')
X_test  = np.concatenate([arr[np.newaxis] for arr in X_test] ).astype('float32')
print(X_train[0].shape)
print(y_train[0])
 
X_train = X_train/255
X_test = X_test/255
 
np.where(X_train[0] != 0)
 
#哑编码
def train_y(y):
    y_one = np.zeros(10)
    y_one[y] = 1
    return y_one
    
y_train_one = np.array([train_y(y_train[i]) for i in range(len(y_train))])
y_test_one  = np.array([train_y(y_test [i]) for i in range(len(y_test ))])
 
#迭代训练(注意这个地方要加入callbacks)
history=model_vgg_cifar10_pretrain.fit(X_train, y_train_one,
                                       validation_data=(X_test, y_test_one), 
                                       epochs=100, batch_size=128,
                                       validation_split=0.1,
                                       verbose=1, 
                                       shuffle=True)
                                       
import matplotlib.pyplot as plt
fig = plt.figure()#新建一张图
plt.plot(history.history['acc'],label='training acc')
plt.plot(history.history['val_acc'],label='val acc')
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(loc='lower right')
fig.savefig('trans_VGG16'+'acc.png')fig = plt.figure()
plt.plot(history.history['loss'],label='training loss')
plt.plot(history.history['val_loss'], label='val loss')
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(loc='upper right')
fig.savefig('VGG16'+'loss.png')

model_vgg_cifar10_pretrain.save('transfer_cifar10.h5') 

在这里插入图片描述在这里插入图片描述可以看到,在使用迁移学习后,准确率能够达到83%.

②识别代码

#-*- coding: utf-8 -*-
import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.image as processimage 
from keras.models import load_model
from scipy import misc
import scipy

#load trained model
model = load_model('transfer_cifar10.h5')			#导入模型
class MainPredictImg(object):
    def __init__(self):
        pass
    def pre(self,filename):
        pred_img = processimage.imread(filename)#read image 
        pred_img = np.array(pred_img) #transfer to array np 
        pred_img = scipy.misc.imresize(pred_img,size = (64, 64))      #将任意尺寸的图片resize成网络要求的尺寸
        pred_img = pred_img.reshape(-1, 64, 64, 3)
        prediction = model.predict(pred_img) #predict
        labels =  ['airplane','automobile','bird','cat','deer','dog','frog','horse','ship','truck']
        Final_prediction = [result.argmax() for result in prediction][0]
        Final_prediction = labels[Final_prediction]
        a = 0
        for i in prediction[0]:
            print labels[a]
            print 'Percent:{:.30%}'.format(i) # 30%输出小数点后30位
            a = a+1
        return Final_prediction
def main():
    Predict = MainPredictImg()
    res = Predict.pre('airplant.jpg')												#导入要识别的图片
    print 'your picture is :-->',res
if __name__ == '__main__':
    main()

3.识别结果:

在这里插入图片描述
在这里插入图片描述
参考书籍:
《Keras快速上手:基于Python的深度学习实战(谢梁等)》

猜你喜欢

转载自blog.csdn.net/weixin_41735859/article/details/87950969