keras提供了VGG19在ImageNet上的预训练权重模型文件,其他可用的模型还有VGG16、Xception、ResNet50、InceptionV3 4个。
VGG19在keras中的定义:
-
def VGG19(include_top=True, weights='imagenet',
-
input_tensor=None, input_shape=None,
-
pooling=None,
-
classes=1000)
-
参数介绍:
include_top: 是否包含最后的3个全连接层
weights: 定义为‘imagenet’,表示加载在imagenet数据库上训练的预训练权重,定义为None则不加载权重,参数随机初始化
1)使用VGG19预训练模型分类图片的例子
-
# coding: utf-8
-
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', include_top=True)
-
img_path = 'cat.jpg'
-
img = image.load_img(img_path, target_size=(224, 224)) # 加载图像,归一化大小
-
x = image.img_to_array(img) # 序列化
-
x = np.expand_dims(x, axis=0) # 扩展维度[batch_size,H,W,Channel]
-
x = preprocess_input(x) # 预处理,默认mode="caffe"
-
"""
-
def preprocess_input(x, data_format=None, mode='caffe'):
-
Preprocesses a tensor or Numpy array encoding a batch of images.
-
-
# Arguments
-
x: Input Numpy or symbolic tensor, 3D or 4D.
-
data_format: Data format of the image tensor/array.
-
mode: One of "caffe", "tf".
-
- caffe: will convert the images from RGB to BGR,
-
then will zero-center each color channel with
-
respect to the ImageNet dataset,
-
without scaling.
-
- tf: will scale pixels between -1 and 1,
-
sample-wise.
-
-
# Returns
-
Preprocessed tensor or Numpy array.
-
-
# Raises
-
ValueError: In case of unknown `data_format` argument.
-
"""
-
out = base_model.predict(x) # 预测结果,1000维的向量
-
print(out.shape) # 预测结果out是一个1000维的向量,代表了预测结果分别属于10000个分类的概率,形状是(1,1000)
2) 使用VGG19预训练模型提取VGG19网络中任意层的输出特征的例子
上个例子可以看到keras对VGG网络的封装异常好,简单几行代码就可以分类图片。keras中VGG预训练参数模型另一个更常用的应用是可以提取VGG网络中任意一层的特征。
以下例子提取的是VGG19网络中第5个卷积层的输出特征(也是第1个全连接层的输入特征)
-
# coding: utf-8
-
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', include_top=False)
-
model = Model(inputs=base_model.input, outputs=base_model.get_layer('block5_pool').output)
-
img_path = 'cat.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)
-
block5_pool_features = model.predict(x)
-
print(block5_pool_features.shape) #(1, 7, 7, 512)
也可以设置为加载最后3个全连接层的VGG19网络,就可以获取最后3个全连接层的输出了:
-
# coding: utf-8
-
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', include_top=True)
-
model = Model(inputs=base_model.input, outputs=base_model.get_layer('fc2').output)
-
img_path = 'cat.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)
-
fc2 = model.predict(x)
-
print(fc2.shape) #(1, 4096)
加了全连接层,所以base_model.get_layer('fc2') 里参数也可以是 flatten、fc1、fc2和predictions 。
VGG19各个模块在keras中定义的名称可以通过以下代码获得,然后根据名称可以轻松获取该层特征::
-
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
-
import os
-
import tensorflow as tf
-
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
-
gpu_options = tf.GPUOptions(allow_growth=True)
-
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))
-
from keras.utils import plot_model
-
from matplotlib import pyplot as plt
-
-
#【0】VGG19模型,加载预训练权重
-
base_model = VGG19(weights='imagenet')
-
-
#【1】创建一个新model, 使得它的输出(outputs)是 VGG19 中任意层的输出(output)
-
model = Model(inputs=base_model.input, outputs=base_model.get_layer('block4_pool').output)
-
print(model.summary()) # 打印模型概况,如下所示
-
plot_model(model,to_file = 'a simple convnet.png') # 画出模型结构图,并保存成图片,如下图所示
-
"""
-
_________________________________________________________________
-
Layer (type) Output Shape Param #
-
=================================================================
-
input_1 (InputLayer) (None, 224, 224, 3) 0
-
_________________________________________________________________
-
block1_conv1 (Conv2D) (None, 224, 224, 64) 1792
-
_________________________________________________________________
-
block1_conv2 (Conv2D) (None, 224, 224, 64) 36928
-
_________________________________________________________________
-
block1_pool (MaxPooling2D) (None, 112, 112, 64) 0
-
_________________________________________________________________
-
block2_conv1 (Conv2D) (None, 112, 112, 128) 73856
-
_________________________________________________________________
-
block2_conv2 (Conv2D) (None, 112, 112, 128) 147584
-
_________________________________________________________________
-
block2_pool (MaxPooling2D) (None, 56, 56, 128) 0
-
_________________________________________________________________
-
block3_conv1 (Conv2D) (None, 56, 56, 256) 295168
-
_________________________________________________________________
-
block3_conv2 (Conv2D) (None, 56, 56, 256) 590080
-
_________________________________________________________________
-
block3_conv3 (Conv2D) (None, 56, 56, 256) 590080
-
_________________________________________________________________
-
block3_conv4 (Conv2D) (None, 56, 56, 256) 590080
-
_________________________________________________________________
-
block3_pool (MaxPooling2D) (None, 28, 28, 256) 0
-
_________________________________________________________________
-
block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160
-
_________________________________________________________________
-
block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808
-
_________________________________________________________________
-
block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808
-
_________________________________________________________________
-
block4_conv4 (Conv2D) (None, 28, 28, 512) 2359808
-
_________________________________________________________________
-
block4_pool (MaxPooling2D) (None, 14, 14, 512) 0
-
=================================================================
-
Total params: 10,585,152
-
Trainable params: 10,585,152
-
Non-trainable params: 0
-
_________________________________________________________________
-
-
"""
3)最终的特征提取代码
-
# -*- coding: UTF-8 -*-
-
#-------------------------------------------
-
#任 务:利用VGG19提取任意中间层特征
-
#数 据:网上下载的测试图片‘elephant.jpg’
-
#-------------------------------------------
-
-
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
-
import os
-
import tensorflow as tf
-
os.environ["CUDA_VISIBLE_DEVICES"] = "6"
-
gpu_options = tf.GPUOptions(allow_growth=True)
-
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))
-
from keras.utils import plot_model
-
from matplotlib import pyplot as plt
-
-
#【0】VGG19模型,加载预训练权重
-
base_model = VGG19(weights='imagenet')
-
-
#【1】创建一个新model, 使得它的输出(outputs)是 VGG19 中任意层的输出(output)
-
model = Model(inputs=base_model.input, outputs=base_model.get_layer('block4_pool').output)
-
print(model.summary()) # 打印模型概况
-
plot_model(model,to_file = 'a simple convnet.png') # 画出模型结构图,并保存成图片
-
-
'''
-
_________________________________________________________________
-
Layer (type) Output Shape Param #
-
=================================================================
-
input_1 (InputLayer) (None, 224, 224, 3) 0
-
_________________________________________________________________
-
block1_conv1 (Conv2D) (None, 224, 224, 64) 1792
-
_________________________________________________________________
-
block1_conv2 (Conv2D) (None, 224, 224, 64) 36928
-
_________________________________________________________________
-
block1_pool (MaxPooling2D) (None, 112, 112, 64) 0
-
_________________________________________________________________
-
block2_conv1 (Conv2D) (None, 112, 112, 128) 73856
-
_________________________________________________________________
-
block2_conv2 (Conv2D) (None, 112, 112, 128) 147584
-
_________________________________________________________________
-
block2_pool (MaxPooling2D) (None, 56, 56, 128) 0
-
_________________________________________________________________
-
block3_conv1 (Conv2D) (None, 56, 56, 256) 295168
-
_________________________________________________________________
-
block3_conv2 (Conv2D) (None, 56, 56, 256) 590080
-
_________________________________________________________________
-
block3_conv3 (Conv2D) (None, 56, 56, 256) 590080
-
_________________________________________________________________
-
block3_conv4 (Conv2D) (None, 56, 56, 256) 590080
-
_________________________________________________________________
-
block3_pool (MaxPooling2D) (None, 28, 28, 256) 0
-
_________________________________________________________________
-
block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160
-
_________________________________________________________________
-
block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808
-
_________________________________________________________________
-
block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808
-
_________________________________________________________________
-
block4_conv4 (Conv2D) (None, 28, 28, 512) 2359808
-
_________________________________________________________________
-
block4_pool (MaxPooling2D) (None, 14, 14, 512) 0
-
=================================================================
-
Total params: 10,585,152
-
Trainable params: 10,585,152
-
Non-trainable params: 0
-
_________________________________________________________________
-
-
'''
-
-
#【2】从网上下载一张图片,保存在当前路径下
-
img_path = 'elephant.jpg'
-
img = image.load_img(img_path, target_size=(224, 224)) # 加载图片并resize成224x224
-
-
#【3】将图片转化为4d tensor形式
-
x = image.img_to_array(img)
-
x = np.expand_dims(x, axis=0)
-
-
#【4】数据预处理
-
x = preprocess_input(x) #去均值中心化,preprocess_input函数详细功能见注释
-
"""
-
def preprocess_input(x, data_format=None, mode='caffe'):
-
Preprocesses a tensor or Numpy array encoding a batch of images.
-
-
# Arguments
-
x: Input Numpy or symbolic tensor, 3D or 4D.
-
data_format: Data format of the image tensor/array.
-
mode: One of "caffe", "tf".
-
- caffe: will convert the images from RGB to BGR,
-
then will zero-center each color channel with
-
respect to the ImageNet dataset,
-
without scaling.
-
- tf: will scale pixels between -1 and 1,
-
sample-wise.
-
-
# Returns
-
Preprocessed tensor or Numpy array.
-
-
# Raises
-
ValueError: In case of unknown `data_format` argument.
-
"""
-
#【5】提取特征
-
block4_pool_features = model.predict(x)
-
print(block4_pool_features.shape) #(1, 14, 14, 512)
示例图片: