Keras(二)Application中五款已训练模型、VGG16框架解读
原文链接:http://www.one2know.cn/keras3/
Application的五款已训练模型 + H5py简述
- Keras的应用模块Application提供了带有预训练权重的Keras模型,这些模型可以用来进行预测、特征提取和finetune。
后续还有对以下几个模型的参数介绍:
Xception
VGG16
VGG19
ResNet50
InceptionV3
所有的这些模型(除了Xception)都兼容Theano和Tensorflow,并会自动基于~/.keras/keras.json的Keras的图像维度进行自动设置。例如,如果你设置data_format=”channel_last”,则加载的模型将按照TensorFlow的维度顺序来构造,即“Width-Height-Depth”的顺序。
模型的官方下载路径:
https://github.com/fchollet/deep-learning-models/releases - th与tf的区别
Keras提供了两套后端,Theano和Tensorflow
th和tf的大部分功能都被backend统一包装起来了,但二者还是存在不小的冲突,有时候你需要特别注意Keras是运行在哪种后端之上,它们的主要冲突有:
dim_ordering,也就是维度顺序。比方说一张224×224的彩色图片,theano的维度顺序是(3,224,224),即通道维在前。而tf的维度顺序是(224,224,3),即通道维在后。
数据格式的区别,channels_last”对应原本的“tf”,“channels_first”对应原本的“th”。以128x128的RGB图像为例,“channels_first”应将数据组织为(3,128,128),而“channels_last”应将数据组织为(128,128,3) - notop模型
是否包含最后的3个全连接层,用来做微调(fine-tuning)专用,专门开源了这类模型 - H5py简述
keras的已训练模型是H5PY格式的,后缀是h5
h5py.File类似Python的词典对象,因此我们可以查看所有的键值
输入:
import h5py
file=h5py.File('.../notop.h5','r')
查看键值:
f = file.attrs['nb_layers']
f.key()
查看到f中各个层内有些什么:
for name in f:
print(name)
- 官方案例:利用ResNet50网络进行ImageNet分类
识别大象的品种:
from keras.applications.resnet50 import ResNet50
from keras.preprocessing import image
from keras.applications.resnet50 import preprocess_input,decode_predictions
import numpy as np
model = ResNet50(weights=r'..\Model\resnet50_weights_tf_dim_ordering_tf_kernels.h5')
img_path = 'elephant.jpg'
img = image.load_img(img_path,target_size=(224,224))
# 现有模型输入shape为 (224, 224, 3)
x = image.img_to_array(img)
x = np.expand_dims(x,axis=0)
x = preprocess_input(x)
preds = model.predict(x)
print('Predicted:',decode_predictions(preds,top=3)[0])
输出:
Predicted: [('n02504458', 'African_elephant', 0.603124), ('n02504013', 'Indian_elephant', 0.334439), ('n01871265', 'tusker', 0.062180385)]
- 五个模型
1.Xception模型:仅能以TensorFlow为后端使用,目前该模型只支持channels_last的维度顺序(width, height, channels)
默认输入图片大小为299x299
keras.applications.xception.Xception(include_top=True,weights='imagenet',input_tensor=None, input_shape=None,pooling=None, classes=1000)
2.VGG16模型:在Theano和TensorFlow后端均可使用,并接受channels_first和channels_last两种输入维度顺序
默认输入图片大小为224x224
keras.applications.vgg16.VGG16(include_top=True, weights='imagenet',input_tensor=None, input_shape=None,pooling=None,classes=1000)
3.VGG19模型
在Theano和TensorFlow后端均可使用,并接受channels_first和channels_last两种输入维度顺序
默认输入图片大小为224x224
keras.applications.vgg19.VGG19(include_top=True, weights='imagenet', input_tensor=None, input_shape=None,pooling=None,classes=1000)
4.ResNet50模型
在Theano和TensorFlow后端均可使用,并接受channels_first和channels_last两种输入维度顺序
默认输入图片大小为224x224
keras.applications.resnet50.ResNet50(include_top=True,weights='imagenet',input_tensor=None, input_shape=None,pooling=None,classes=1000)
5.InceptionV3模型
在Theano和TensorFlow后端均可使用,并接受channels_first和channels_last两种输入维度顺序
默认输入图片大小为299x299
keras.applications.inception_v3.InceptionV3(include_top=True,weights='imagenet',input_tensor=None,input_shape=None,pooling=None,classes=1000)
keras-applications-VGG16解读:函数式
- VGG16默认的输入数据格式应该是:channels_last
from __future__ import print_function
import numpy as np
import warnings
from keras.models import Model
from keras.layers import Flatten,Dense,Input,Conv2D
from keras.layers import MaxPooling2D,GlobalMaxPooling2D,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 = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels.h5'
WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/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 = get_file('vgg16_weights_tf_dim_ordering_tf_kernels.h5',
WEIGHTS_PATH,
cache_subdir='models')
else:
weights_path = get_file('vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5',
WEIGHTS_PATH_NO_TOP,
cache_subdir='models')
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
if __name__ == '__main__':
model = VGG16(include_top=True, weights='imagenet')
img_path = 'elephant.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))
# decode_predictions 输出5个最高概率:(类名, 语义概念, 预测概率)
输出:
Input image shape: (1, 224, 224, 3)
Predicted: [[('n02504458', 'African_elephant', 0.62728244), ('n02504013', 'Indian_elephant', 0.19092941), ('n01871265', 'tusker', 0.18166111), ('n02437312', 'Arabian_camel', 4.5080957e-05), ('n07802026', 'hay', 1.7709652e-05)]]
- 将model下载到本地,修改下载的代码
注释掉下面两行:
WEIGHTS_PATH = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels.h5'
WEIGHTS_PATH_NO_TOP = 'https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5'
修改下面两行:
weights_path = get_file('vgg16_weights_tf_dim_ordering_tf_kernels.h5',WEIGHTS_PATH,cache_subdir='models')
weights_path = get_file('vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5',WEIGHTS_PATH_NO_TOP,cache_subdir='models') - 几个layer中的新用法
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,将图像变为数组
(1)decode_predictions用在最后输出结果上,比较好用【print(‘Predicted:’, decode_predictions(preds))】;
(2)preprocess_input,改变编码,【preprocess_input(x)】;
(3)_obtain_input_shape
相当于caffe中的transform,在预测的时候,需要对预测的图片进行一定的预处理。
input_shape = _obtain_input_shape(input_shape,default_size=224,min_size=48,data_format=K.image_data_format(),include_top=include_top)
min_size=48,模型所能接受的最小长宽
data_format=K.image_data_format(),数据的使用格式 - 当include_top=True时
fc_model = VGG16(include_top=True)
notop_model = VGG16(include_top=False)
用VGG16做fine-tuning的时候,得到的notop_model就是没有全连接层的模型,然后再去添加自己的层。
当是健全的网络结构的时候,fc_model需要添加以下的内容以补全网络结构:
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)
pool层之后接一个flatten层,修改数据格式,然后接两个dense层,最后有softmax的Dense层
- channels_first转成channels_last格式
maxpool = model.get_layer(name='block5_pool')
# model.get_layer()依据层名或下标获得层对象
shape = maxpool.output_shape[1:]
# 获取block5_pool层输出的数据格式
dense = model.get_layer(name='fc1')
layer_utils.convert_dense_weights_data_format(dense, shape, 'channels_first')
convert_dense_weights_data_format将convnet的权重从一种数据格式移植到另一种数据格式时,如果convnet包含一个平坦层(应用于最后一个卷积特征映射),然后是一个密集层,则应更新该密集层的权重,以反映新的维度顺序。
Keras(二)Application中五款已训练模型、VGG16框架解读的更多相关文章
- keras系列︱Application中五款已训练模型、VGG16框架(Sequential式、Model式)解读(二)
引自:http://blog.csdn.net/sinat_26917383/article/details/72859145 中文文档:http://keras-cn.readthedocs.io/ ...
- 我的Keras使用总结(4)——Application中五款预训练模型学习及其应用
本节主要学习Keras的应用模块 Application提供的带有预训练权重的模型,这些模型可以用来进行预测,特征提取和 finetune,上一篇文章我们使用了VGG16进行特征提取和微调,下面尝试一 ...
- 来,带你鸟瞰 Java 中4款常用的并发框架!
1. 为什么要写这篇文章 几年前 NoSQL 开始流行的时候,像其他团队一样,我们的团队也热衷于令人兴奋的新东西,并且计划替换一个应用程序的数据库. 但是,当深入实现细节时,我们想起了一位智者曾经说过 ...
- Linux系统中五款好用的日志分析工具
监控网络活动是一项繁琐的工作,但有充分的理由这样做.例如,它允许你查找和调查工作站和连接到网络的设备及服务器上的可疑登录,同时确定管理员滥用了什么.你还可以跟踪软件安装和数据传输,以实时识别潜在问题, ...
- 五款好玩又好用的Linux网络测试和监控工具
五款好玩又好用的Linux网络测试和监控工具 [51CTO精选译文]在这篇介绍几款Linux网络测试实用工具的文章中,我们使用Bandwidthd.Speedometer.Nethogs.Darkst ...
- 【JavsScript】推荐五款流行的JavaScript模板引擎
摘要:Javascript模板引擎作为数据与界面分离工作中最重要一环,受到开发者广泛关注.本文通过开发实例解析五款流行模板引擎:Mustache.Underscore Templates.Embedd ...
- 8个实用的SVG工具,20 个有用的 SVG 工具,五款超实用的开源SVG工具
8个实用的SVG工具 [导读] 你还在为没有好用的SVG工具而发愁吗?开发人员的福音来啦!小编为大家收集罗列了8款实用的SVG工具,让我们一起来看看吧! SVG可缩放矢量图形(Scalable Vec ...
- Android Application中的Context和Activity中的Context的异同
一.Context是什么: 1.Context是维持Android程序中各组件能够正常工作的一个核心功能类,我们选中Context类 ,按下快捷键F4,右边就会出现一个Context类的继承结构图啦, ...
- 五款app原型设计工具对比
五款app原型设计工具对比 Proto.io, Pixate, Origami, Framer & Form 本文由Panblack 翻译,原文作者 Tes Mat 我用五款“高保真”原型设计 ...
随机推荐
- IO流总结1
一.什么是流? 流就是字节序列的抽象概念,能被连续读取数据的数据源和能被连续写入数据的接收端就是流,流机制是Java及C++中的一个重要机制,通过流我们可以自由地控制文件.内存.IO设备等数据的流向. ...
- shiro 和 spring boot 的集成
1 添加依赖 使用 shiro-spring-boot-web-starter 在 spring boot 中集成 shiro 只需要再添加一个依赖 <dependency> <gr ...
- NPM - 检查并更新项目依赖的版本
原文地址:https://acme.top/nodejs-npm-check-updates 前言 经常会遇到 package.json 中的库有更新,但是太多一个一个的来很费事,幸好有个工具 npm ...
- [Spring cloud 一步步实现广告系统] 14. 全量索引代码实现
上一节我们实现了索引基本操作的类以及索引缓存工具类,本小节我们开始实现加载全量索引数据,在加载全量索引数据之前,我们需要先将数据库中的表数据导出到一份文件中.Let's code. 1.首先定义一个常 ...
- 转载 | textarea 在浏览器中固定大小和禁止拖动
HTML 标签 textarea 在大部分浏览器中只要指定行(rows)和列(cols)属性,就可以规定 textarea 的尺寸,大小就不会改变,不过更好的办法是使用 CSS 的 height 和 ...
- ccf 201903-5 317号子任务(60分)
看到这题,第一印象,用dijkstra算法求n次单源最短路,时间复杂度O(n^3),超时30分妥妥的. 于是用优先队列优化,O(n*mlogm),快很多,但依然30. 那么不妨换一种思路,题目要求的是 ...
- C++这么难,为什么还要学习C++呢?如何学?
在大多数开发或者准开发人员的认识中,C/C++ 是一门非常难的编程语言,很多人知道它的强大,但因为认为“难”造成的恐惧让很多人放弃. 这个世界本来就是残酷的,所以你不能怪C++向你展示了世界的本质 大 ...
- WebSphere MQ性能调优浅谈
导读:目前随着我们在中国的WebSphere MQ(MQSeries)用户数量越来越多,越来越多的用户开始对MQ使用时的性能优化问题提出要求,我根据日常积累的经验谈一谈在MQ性能优化方面应该考虑的因素 ...
- android ——滑动菜单
一.DrawerLayout是一个拥有两个子控件的布局,第一个子控件是主屏幕中显示的内容,第二个子控件是滑动菜单中显示的内容: <android.support.v4.widget.Drawer ...
- linux之用户和用户组管理详解
#############用户和用户组管理###################linux只认识UID和GID #可在/etc/passwd 和/etc/group中找到 ##/etc/passwd ...