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

本文介绍了如何利用迁移学习,特别是通过Keras库结合VGG16模型对CIFAR10数据集进行图像识别。通过移除VGG16的顶层并保留预训练权重,添加新的分类层进行训练,实现高效且准确的图像分类。案例包括VGG16和VGG19与CIFAR10的结合应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

迁移学习:将一个领域的已经成熟的知识应用到其他的场景中,例如图像识别中最常见的例子,训练一个神经网络。来识别不同的品种的猫,你若是从头开始训练,你需要百万级的带标注数据,海量的显卡资源。而若是使用迁移学习,你可以使用Google发布的Inception或VGG16这样成熟的物品分类的网络,只训练最后的softmax层,你只需要几千张图片,使用普通的CPU就能完成,而且模型的准确性不差。

案例一

框架: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') 

å¨è¿éæå¥å¾çæè¿°å¨è¿éæå¥å¾çæè¿°

②识别代码

#-*- 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.识别结果:

å¨è¿éæå¥å¾çæè¿°

å¨è¿éæå¥å¾çæè¿°

案例二

from keras.applications.vgg16 import VGG16
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.applications.vgg16 import preprocess_input
from keras.applications.vgg16 import decode_predictions
import keras
import tensorflow as tf

# 模型手动下载然后放到目录C:\Users\用户名\.keras\models下,下载地址如下:
# https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels.h5
# https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5

# 载入模型并打印
model = VGG16()
print(model.summary())

# 加载一副测试图片
image = load_img("dog.jpg", target_size=(224, 224))

# 转为数组
image = img_to_array(image)

# 重塑成4D
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))

# 预处理图片
image = preprocess_input(image)

# 预测
predict_result = model.predict(image)

# 解析预测结果
label = decode_predictions(predict_result)

# 打印出三个概率最大的分类
for idx in range(0, 3):
    print("类别:%s        概率:%0.4f"%(label[0][idx][1], label[0][idx][2]))

# 清理
keras.backend.clear_session()
tf.reset_default_graph()

案例三

1、VGG19 + cifar10 

# -*- coding:utf-8 -*-  
import tensorflow as tf
import numpy as np
import time
import os
import sys
import random
import cPickle as pickle


class_num = 10
image_size = 32
img_channels = 3
iterations = 200
batch_size = 250
total_epoch = 164
weight_decay = 0.0003
dropout_rate = 0.5
momentum_rate = 0.9
log_save_path = './vgg_19_logs'
model_save_path = './model/'


def download_data():
    dirname = 'cifar10-dataset'
    origin = 'http://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz'
    fname = './CAFIR-10_data/cifar-10-python.tar.gz'
    fpath = './' + dirname

    download = False
    if os.path.exists(fpath) or os.path.isfile(fname):
        download = False
        print("DataSet already exist!")
    else:
        download = True
    if download:
    
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一摩尔自由

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值