tensorflow/keras 2 ncnn
以resnet50为例,记录tensorflow和keras模型转ncnn的过程
resnet50 模型定义
def identity_block(input_tensor, kernel_size, filters, stage, block):nb_filter1, nb_filter2, nb_filter3 = filtersif K.image_dim_ordering() == 'tf':bn_axis = 3else:bn_axis = 1conv_name_base = 'res' + str(stage) + block + '_branch'bn_name_base = 'bn' + str(stage) + block + '_branch'x = Convolution2D(nb_filter1, 1, 1, name=conv_name_base + '2a')(input_tensor)x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)x = Activation('relu')(x)x = Convolution2D(nb_filter2, kernel_size, kernel_size,border_mode='same', name=conv_name_base + '2b')(x)x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)x = Activation('relu')(x)x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)x = merge([x, input_tensor], mode='sum')x = Activation('relu')(x)return xdef conv_block(input_tensor, kernel_size, filters, stage, block, strides=(2, 2)):nb_filter1, nb_filter2, nb_filter3 = filtersif K.image_dim_ordering() == 'tf':bn_axis = 3else:bn_axis = 1conv_name_base = 'res' + str(stage) + block + '_branch'bn_name_base = 'bn' + str(stage) + block + '_branch'x = Convolution2D(nb_filter1, 1, 1, subsample=strides,name=conv_name_base + '2a')(input_tensor)x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2a')(x)x = Activation('relu')(x)x = Convolution2D(nb_filter2, kernel_size, kernel_size, border_mode='same',name=conv_name_base + '2b')(x)x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2b')(x)x = Activation('relu')(x)x = Convolution2D(nb_filter3, 1, 1, name=conv_name_base + '2c')(x)x = BatchNormalization(axis=bn_axis, name=bn_name_base + '2c')(x)shortcut = Convolution2D(nb_filter3, 1, 1, subsample=strides,name=conv_name_base + '1')(input_tensor)shortcut = BatchNormalization(axis=bn_axis, name=bn_name_base + '1')(shortcut)x = merge([x, shortcut], mode='sum')x = Activation('relu')(x)return ximg_input = Input(shape=(image_width, image_height, 3))x = ZeroPadding2D((3, 3))(img_input)
x = Convolution2D(64, 7, 7, subsample=(2, 2), name='conv1')(x)
x = BatchNormalization(axis=3, name='bn_conv1')(x)
x = Activation('relu')(x)
x = MaxPooling2D((3, 3), strides=(2, 2))(x)x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1))
x = identity_block(x, 3, [64, 64, 256], stage=2, block='b')
x = identity_block(x, 3, [64, 64, 256], stage=2, block='c')x = conv_block(x, 3, [128, 128, 512], stage=3, block='a')
x = identity_block(x, 3, [128, 128, 512], stage=3, block='b')
x = identity_block(x, 3, [128, 128, 512], stage=3, block='c')
x = identity_block(x, 3, [128, 128, 512], stage=3, block='d')x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a')
x = identity_block(x, 3, [256, 256, 1024], stage=4, block='b')
x = identity_block(x, 3, [256, 256, 1024], stage=4, block='c')
x = identity_block(x, 3, [256, 256, 1024], stage=4, block='d')
x = identity_block(x, 3, [256, 256, 1024], stage=4, block='e')
x = identity_block(x, 3, [256, 256, 1024], stage=4, block='f')x = conv_block(x, 3, [512, 512, 2048], stage=5, block='a')
x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b')
x = identity_block(x, 3, [512, 512, 2048], stage=5, block='c')x = AveragePooling2D((7, 13), name='avg_pool')(x)
x = Flatten()(x)
x = Dropout(0.5)(x)
x = Dense(1, activation='sigmoid', name='output')(x)model = Model(input=img_input, output=x)
数据
目录树如下:
datasets
– mytrain
---- cls1
---- cls2
– myvalid
---- cls1
---- cls2
– mytest
---- cls1
---- cls2
from keras.preprocessing.image import ImageDataGenerator
image_width = 224
image_height = 398 #224
image_size = (image_width, image_height)train_datagen = ImageDataGenerator(rescale=1.0/255)train_generator = train_datagen.flow_from_directory('datasets/mytrain', # this is the target directorytarget_size=image_size, # all images will be resized to 224x224batch_size=16,class_mode='binary')validation_datagen = ImageDataGenerator(rescale=1.0/255)
validation_generator = validation_datagen.flow_from_directory('datasets/myvalid', # this is the target directorytarget_size=image_size, # all images will be resized to 224x224batch_size=16,class_mode='binary')test_datagen = ImageDataGenerator(rescale=1.0/255)
test_datagen = validation_datagen.flow_from_directory('datasets/mytest/', # this is the target directorytarget_size=image_size, # all images will be resized to 224x224batch_size=1,class_mode='binary')
模型训练和保存
- case1:模型保存为.h5文件(keras)
model.compile(loss='binary_crossentropy', optimizer=Adam(lr=1e-3), metrics=['accuracy'])
from keras.callbacks import ModelCheckpoint, TensorBoard
best_model = ModelCheckpoint("resnet_best.h5", monitor='val_acc', verbose=0, save_best_only=True)
model.fit_generator(train_generator,samples_per_epoch=2145,nb_epoch=40,validation_data=validation_generator,nb_val_samples=270,callbacks=[best_model, TensorBoard(log_dir='./logs', histogram_freq=0)])
- case2: 保存为ckpt文件(tensorflow)(ckpt.index, ckpt.data, ckpt.meta)
(略)
模型文件转为.pb文件
- case 1: .h5文件
import sys
from keras.models import load_model
import tensorflow as tf
import os
import os.path as osp
from keras import backend as K
from tensorflow.python.framework.graph_util import convert_variables_to_constantsdef freeze_session(session, keep_var_names=None, output_names=None, clear_devices=True):# 将会话状态冻结为已删除的计算图,创建一个新的计算图,其中变量节点由在会话中获取其当前值的常量替换.# session要冻结的TensorFlow会话,keep_var_names不应冻结的变量名列表,或者无冻结图中的所有变量# output_names相关图输出的名称,clear_devices从图中删除设备以获得更好的可移植性graph = session.graphwith graph.as_default():freeze_var_names = list(set(v.op.name for v in tf.global_variables()).difference(keep_var_names or []))output_names = output_names or []output_names += [v.op.name for v in tf.global_variables()]input_graph_def = graph.as_graph_def()# 从图中删除设备以获得更好的可移植性if clear_devices:for node in input_graph_def.node:node.device = ""# 用相同值的常量替换图中的所有变量frozen_graph = convert_variables_to_constants(session, input_graph_def, output_names, freeze_var_names)return frozen_graphoutput_fld = 'tmp/'
if not os.path.isdir(output_fld):os.mkdir(output_fld)
weight_file_path = 'resnet50_best.h5'
K.set_learning_phase(0)
net_model = load_model(weight_file_path)print('input is :', net_model.input.name)
print ('output is:', net_model.output.name)# 获得当前图
sess = K.get_session()
# 冻结图
frozen_graph = freeze_session(sess, output_names=[net_model.output.op.name])from tensorflow.python.framework import graph_io
graph_io.write_graph(frozen_graph, output_fld, 'resnet50_best.pb', as_text=False)
- case2: .ckpt文件
#encoding: utf-8
import tensorflow as tf
import argparse
from tensorflow.python.tools import freeze_graphdef load_model(model):# Check if the model is a model directory (containing a metagraph and a checkpoint file)# or if it is a protobuf file with a frozen graph# load pretrained modelif model:print('Restoring pretrained model: %s' % model)saver = tf.train.import_meta_graph(model + '.meta')saver.restore(tf.get_default_session(), model)else:raise ValueError("Pretrained_model not found: ", model)if __name__ == '__main__':with tf.Graph().as_default():with tf.Session() as sess:# os.environ["CUDA_VISIBLE_DEVICES"] = "0"model_path = '/path/to/xxx.ckpt'load_model(model_path)#保存图graph_pb_name = 'model_graph.pb'model_pb_name = 'model_frozen.pb'tf.train.write_graph(sess.graph_def, './model_files', graph_pb_name)#把图和参数结构一起# 1、input_graph:(必选)模型文件,可以是二进制的pb文件,或文本的meta文件,用input_binary来指定区分(见下面说明)# 2、input_saver:(可选)Saver解析器。保存模型和权限时,Saver也可以自身序列化保存,以便在加载时应用合适的版本。主要用于版本不兼容时使用。可以为空,为空时用当前版本的Saver。# 3、input_binary:(可选)配合input_graph用,为true时,input_graph为二进制,为false时,input_graph为文件。默认False# 4、input_checkpoint:(必选)检查点数据文件。训练时,给Saver用于保存权重、偏置等变量值。这时用于模型恢复变量值。# 5、output_node_names:(必选)输出节点的名字,有多个时用逗号分开。用于指定输出节点,将没有在输出线上的其它节点剔除。# 6、restore_op_name:(可选)从模型恢复节点的名字。升级版中已弃用。默认:save/restore_all# 7、filename_tensor_name:(可选)已弃用。默认:save/Const:0# 8、output_graph:(必选)用来保存整合后的模型输出文件。# 9、clear_devices:(可选),默认True。指定是否清除训练时节点指定的运算设备(如cpu、gpu、tpu。cpu是默认)# 10、initializer_nodes:(可选)默认空。权限加载后,可通过此参数来指定需要初始化的节点,用逗号分隔多个节点名字。# 11、variable_names_blacklist:(可先)默认空。变量黑名单,用于指定不用恢复值的变量,用逗号分隔多个变量名字。freeze_graph.freeze_graph(input_graph='./model_files/' + graph_pb_name, input_saver='',input_binary=False, input_checkpoint=args.model, output_node_names='embeddings', restore_op_name='save/restore_all',filename_tensor_name='save/Const:0',output_graph='./model_files/' + model_pb_name,clear_devices=True,initializer_nodes="")print("done")
测试.pb文件(可忽略)
#!/usr/bin/python
# coding:utf8
import tensorflow as tf
import numpy as np
import os
import cv2predictions = np.zeros((test_datagen.samples), dtype=np.float32)
labels = np.zeros((test_datagen.samples), dtype=np.float32)pb_path = 'tmp/resnet50_best.pb'
with tf.Graph().as_default():output_graph_def = tf.GraphDef()with open(pb_path, "rb") as f:output_graph_def.ParseFromString(f.read())tensors = tf.import_graph_def(output_graph_def, name="")with tf.Session() as sess:init = tf.global_variables_initializer()sess.run(init)sess.graph.get_operations()input_x = sess.graph.get_tensor_by_name("input_1_1:0") # 具体名称看上一段代码的input.nameout_softmax = sess.graph.get_tensor_by_name("output_2/Sigmoid:0") # 具体名称看上一段代码的output.namefor i in range(test_datagen.samples):x, y = test_datagen.next()predictions[i] = sess.run(out_softmax,feed_dict={input_x: x})label_matrix[i] = ypred_bool = predictions > 0.5
num_tp = np.sum(pred_bool * label_matrix + (1.0 - pred_bool) * (1.0 - label_matrix))
acc = num_tp / test_datagen.samples
print(acc)
.pb文件转ncnn模型(.param,.bin)
tensorflow2ncnn项目地址:https://github.com/jiangxiluning/ncnn-tensorflow,编译得到可执行文件tensorflow2ncnn
./tensorflow2ncnn tmp/resnet50_best.pb tmp/resnet50_best.param tmp/resnet50_best.bin
测试ncnn模型
todo
tensorflow/keras 2 ncnn相关推荐
- TensorFlow Keras API用法
TensorFlow Keras API用法 Keras 是与 TensorFlow 一起使用的更高级别的作为后端的 API.添加层就像添加一行代码一样简单.在模型架构之后,使用一行代码,可以编译和拟 ...
- 常用深度学习框——Caffe/TensorFlow / Keras/ PyTorch/MXNet
常用深度学习框--Caffe/TensorFlow / Keras/ PyTorch/MXNet 一.概述 近几年来,深度学习的研究和应用的热潮持续高涨,各种开源深度学习框架层出不穷,包括Tensor ...
- 解决tensorflow报错:AttributeError: module ‘tensorflow.keras.backend‘ has no attribute ‘get_session‘ 问题
欢迎大家关注笔者,你的关注是我持续更博的最大动力 原创文章,转载告知,盗版必究 解决tensorflow报错:AttributeError: module 'tensorflow.keras.back ...
- How HBO’s Silicon Valley built “Not Hotdog” with mobile TensorFlow, Keras React Native
The HBO show Silicon Valley released a real AI app that identifies hotdogs - and not hotdogs - like ...
- 成功解决tensorflow.keras: AttributeError: ‘str‘ object has no attribute ‘decode‘
tensorflow.keras: AttributeError: 'str' object has no attribute 'decode' 出现该问题,解决分两步首先检测自身的版本是否对应, 然 ...
- tensorflow环境下的识别食物_在TensorFlow+Keras环境下使用RoI池化一步步实现注意力机制...
在本文中,作者解释了感兴趣区域池化(RoI 池化)的基本概念和一般用法,以及如何使用它来实现注意力机制.他一步步给出了在 Keras 和 TensorFlow 环境下使用 RoI 池化的实现. 选自 ...
- 【Python学习】 - TensorFlow.keras 不显示epochs进度条的方法
一.概述 在我们使用TensorFlow进行神经网络的搭建时,难免遇到需要训练很多次来拟合数据的情况,假设需要拟合1000次数据,那么可能前800次的拟合效果都不是很好,所以显示进度条就会使得输出面板 ...
- [深度学习-实践]GAN入门例子-利用Tensorflow Keras与数据集CIFAR10生成新图片
系列文章目录 深度学习GAN(一)之简单介绍 深度学习GAN(二)之基于CIFAR10数据集的例子; 深度学习GAN(三)之基于手写体Mnist数据集的例子; 深度学习GAN(四)之PIX2PIX G ...
- 【Keras】Win10系统 + Anaconda+TensorFlow+Keras 环境搭建教程
1. 安装 Anaconda 打开 Anaconda 的官方下载地址:https://www.anaconda.com/download/ 选择 Python 对应的version 下载.下载完成后直 ...
最新文章
- HTTP_响应消息_响应行_状态码
- redis集群的三种模式
- 计算机组成原理实验串行口,计算机组成原理实验2.ppt
- 线程、多线程和线程池,看完这些你就能全部搞懂了
- onnx 测试_YOLOv5来了!Pytorch实现,支持ONNX和CoreML
- Git中的“起源”是什么?
- 一文让你读懂Macbook的使用技巧及命令
- 我从可用性测试中学到的五件事
- 排序算法专题-归并排序
- unity天空盒渐变_在Unity3D中使用天空盒
- 如何将Vue中表格数据,以Excel格式导出?报saveAs错误如何解决?
- paddlepaddle(六)模型保存与载入
- LeetCode 0417「太平洋大西洋水流问题」
- 找不到com.sun.beans.introspect.PropertyInfo的类文件问题
- 把路由器变成音乐播放器和网络收音机,支持摇控
- 世界顶级思维(必须收藏)
- 股票交易日(动态规划)----美团2016研发工程师编程题(二)
- 计算机管理找不到文件怎么办,Windows找不到文件怎么办
- linux不能强制显卡分辨率,Linux系统装显卡驱动及分辨率不正常的解决方法
- mysql中的gpl是什么意思_GPL是什么意思?急