模型文件点这里下载
https://github.com/fchollet/deep-learning-models
权重文件点这里下载
https://github.com/fchollet/deep-learning-models/releases
下载好文件之后只需要在文件中将原本要从网络上下载的语句注释掉,文件路径换成自己下载好的权重文件。
#WEIGHTS_PATH = 'D:/C/pythonEX/VGG16/vgg16_weights_tf_dim_ordering_tf_kernels.h5'
#WEIGHTS_PATH_NO_TOP = 'D:/C/pythonEX/VGG16/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5'
if weights == 'imagenet':
if include_top:
weights_path = 'D:/C/pythonEX/VGG16/vgg16_weights_tf_dim_ordering_tf_kernels.h5'
else:
weights_path = 'D:/C/pythonEX/VGG16/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5'
model.load_weights(weights_path)
其他的部分不变,要做fine-tuning的话,不要加载最后的全连接层,自己在输出层上重新定义网络。
完整代码:
from __future__ import print_function
import numpy as np
import warnings
from keras.models import Model
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers import Input
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import GlobalMaxPooling2D
from keras.layers import GlobalAveragePooling2D
from keras.preprocessing import image
from keras.utils import layer_utils
from keras.utils.data_utils import get_file
from keras import backend as K
from keras.applications.imagenet_utils import decode_predictions
# decode_predictions 输出5个最高概率:(类名, 语义概念, 预测概率) decode_predictions(y_pred)
from keras.applications.imagenet_utils import preprocess_input
# 预处理 图像编码服从规定,譬如,RGB,GBR这一类的,preprocess_input(x)
from keras.applications.imagenet_utils import _obtain_input_shape
# 确定适当的输入形状,相当于opencv中的read.img,将图像变为数组
from keras.engine.topology import get_source_inputs
#WEIGHTS_PATH = 'D:/C/pythonEX/VGG16/vgg16_weights_tf_dim_ordering_tf_kernels.h5'
#WEIGHTS_PATH_NO_TOP = 'D:/C/pythonEX/VGG16/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5'
def VGG16(include_top=True, weights='imagenet',
input_tensor=None, input_shape=None,
pooling=None,
classes=1000):
# 检查weight与分类设置是否正确
if weights not in {'imagenet', None}:
raise ValueError('The `weights` argument should be either '
'`None` (random initialization) or `imagenet` '
'(pre-training on ImageNet).')
if weights == 'imagenet' and include_top and classes != 1000:
raise ValueError('If using `weights` as imagenet with `include_top`'
' as true, `classes` should be 1000')
# 设置图像尺寸,类似caffe中的transform
# Determine proper input shape
input_shape = _obtain_input_shape(input_shape,
default_size=224,
min_size=48,
# 模型所能接受的最小长宽
data_format=K.image_data_format(),
# 数据的使用格式
require_flatten=include_top)
#是否通过一个Flatten层再连接到分类器
# 数据简单处理,resize
if input_tensor is None:
img_input = Input(shape=input_shape)
# 这里的Input是keras的格式,可以用于转换
else:
if not K.is_keras_tensor(input_tensor):
img_input = Input(tensor=input_tensor, shape=input_shape)
else:
img_input = input_tensor
# 如果是tensor的数据格式,需要两步走:
# 先判断是否是keras指定的数据类型,is_keras_tensor
# 然后get_source_inputs(input_tensor)
# 编写网络结构,prototxt
# Block 1
x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv1')(img_input)
x = Conv2D(64, (3, 3), activation='relu', padding='same', name='block1_conv2')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool')(x)
# Block 2
x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv1')(x)
x = Conv2D(128, (3, 3), activation='relu', padding='same', name='block2_conv2')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool')(x)
# Block 3
x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv1')(x)
x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv2')(x)
x = Conv2D(256, (3, 3), activation='relu', padding='same', name='block3_conv3')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool')(x)
# Block 4
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv1')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv2')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block4_conv3')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool')(x)
# Block 5
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv1')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv2')(x)
x = Conv2D(512, (3, 3), activation='relu', padding='same', name='block5_conv3')(x)
x = MaxPooling2D((2, 2), strides=(2, 2), name='block5_pool')(x)
if include_top:
# Classification block
x = Flatten(name='flatten')(x)
x = Dense(4096, activation='relu', name='fc1')(x)
x = Dense(4096, activation='relu', name='fc2')(x)
x = Dense(classes, activation='softmax', name='predictions')(x)
else:
if pooling == 'avg':
x = GlobalAveragePooling2D()(x)
elif pooling == 'max':
x = GlobalMaxPooling2D()(x)
# 调整数据
# Ensure that the model takes into account
# any potential predecessors of `input_tensor`.
if input_tensor is not None:
inputs = get_source_inputs(input_tensor)
# get_source_inputs 返回计算需要的数据列表,List of input tensors.
# 如果是tensor的数据格式,需要两步走:
# 先判断是否是keras指定的数据类型,is_keras_tensor
# 然后get_source_inputs(input_tensor)
else:
inputs = img_input
# 创建模型
# Create model.
model = Model(inputs, x, name='vgg16')
# 加载权重
# load weights
if weights == 'imagenet':
if include_top:
weights_path = 'D:/C/pythonEX/VGG16/vgg16_weights_tf_dim_ordering_tf_kernels.h5'
else:
weights_path = 'D:/C/pythonEX/VGG16/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5'
model.load_weights(weights_path)
if K.backend() == 'theano':
layer_utils.convert_all_kernels_in_model(model)
if K.image_data_format() == 'channels_first':
if include_top:
maxpool = model.get_layer(name='block5_pool')
shape = maxpool.output_shape[1:]
dense = model.get_layer(name='fc1')
layer_utils.convert_dense_weights_data_format(dense, shape, 'channels_first')
if K.backend() == 'tensorflow':
warnings.warn('You are using the TensorFlow backend, yet you '
'are using the Theano '
'image data format convention '
'(`image_data_format="channels_first"`). '
'For best performance, set '
'`image_data_format="channels_last"` in '
'your Keras config '
'at ~/.keras/keras.json.')
return model
model = VGG16(include_top=True, weights='imagenet')
img_path = 'D:/C/pythonEX/VGG16/1.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)
print('Input image shape:', x.shape)
preds = model.predict(x)
print('Predicted:', decode_predictions(preds))