matterport / Mask_RCNN

Mask R-CNN for object detection and instance segmentation on Keras and TensorFlow
Other
24.58k stars 11.69k forks source link

Who convert the .h5 to .pb? I use model.save() take place Error! #1936

Open gaowq2017 opened 4 years ago

gaowq2017 commented 4 years ago

Hi everyone: In recently, I want convert the .h5 to .pb, but the result is model.save_weights() only save the parameters. So i changed as follow: keras.callbacks.ModelCheckpoint(self.checkpoint_path, verbose=0, save_weights_only=False),
but there are the error after one epoch, what can i do? Thank you very much!!!

ArashHosseini commented 4 years ago

@hellolaogao check https://github.com/matterport/Mask_RCNN/issues/1569#issuecomment-569908346

gaowq2017 commented 4 years ago

@hellolaogao check #1569 (comment)

Thank you very much!!!

gaowq2017 commented 4 years ago

Yes, i haved resolved it! You can check at https://github.com/matterport/Mask_RCNN/issues/1569#issuecomment-569908346, best!

At 2020-04-24 05:43:34, "naserpiltan" notifications@github.com wrote:

@gaowq2017 i have same problem.did you solve the problem ?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

naserpiltan commented 4 years ago

Thank you. Finally i could to convert my keras .h5 model to tensorflow .pb with your solution. Did you do inference with this model in tensorflow ? Did you get the same results as keras ?

On Fri, Apr 24, 2020 at 7:41 AM gaowq2017 notifications@github.com wrote:

Yes, i haved resolved it! You can check at https://github.com/matterport/Mask_RCNN/issues/1569#issuecomment-569908346, best!

At 2020-04-24 05:43:34, "naserpiltan" notifications@github.com wrote:

@gaowq2017 i have same problem.did you solve the problem ?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/matterport/Mask_RCNN/issues/1936#issuecomment-618777357, or unsubscribe https://github.com/notifications/unsubscribe-auth/AH7FYWIATBQVFOKIUBE3WPLROD7M5ANCNFSM4KAISW5Q .

HKun1997 commented 4 years ago

@gaowq2017 Hello,did you try to use .pb model to detect in Opencv?

gaowq2017 commented 4 years ago

Hi@naserpiltan HKun1997, I have inferenced it based on example of TensorRT in C++ environment. Thank you!

HKun1997 commented 4 years ago

Hi@naserpiltan HKun1997, I have inferenced it based on example of TensorRT in C++ environment. Thank you!

Ok,got it!Thank you!

naserpiltan commented 4 years ago

@gaowq2017 thanks for your answer.can you share your code with me ?

naserpiltan commented 4 years ago

@HKun1997 did you can use your .pb model in opencv ? can you share your solution ?

HKun1997 commented 4 years ago

@HKun1997 did you can use your .pb model in opencv ? can you share your solution ?

I tried. Unfortunately, it failed. The error is "can't open .pbtxt file". And now i just know .pb file and .pbtxt file(which are trained in tensorflow OD API) can be used in opencv!

HKun1997 commented 4 years ago

@gaowq2017 Hi! Now I want to inference the model in TensorRT(C++) environment. Would you like to share your solution? Thanks again!

gaowq2017 commented 4 years ago

@HKun1997 Hi, you can do it by the file of Readme in sampleUffMaskRCNN. Note the number of catgories! best

HKun1997 commented 4 years ago

@HKun1997 Hi, you can do it by the file of Readme in sampleUffMaskRCNN. Note the number of catgories! best

Ok! Thanks!

ZouJiu1 commented 4 years ago

convert-to pb file

#!encoding=utf-8
'''
#-----------------
Authors:邹九
Time:2019-11-21
#-----------------
'''
"""
Copyright (c) 2019, by the Authors: Amir H. Abdi
This script is freely available under the MIT Public License.
Please see the License file in the root for details.

The following code snippet will convert the keras model files
to the freezed .pb tensorflow weight file. The resultant TensorFlow model
holds both the model architecture and its associated weights.
"""

import tensorflow as tf
from tensorflow.python.framework import graph_util
from tensorflow.python.framework import graph_io
from pathlib import Path
from absl import app
from absl import flags
from absl import logging
from mrcnn import model as modellib
from mrcnn.config import Config
import keras
import os
from keras import backend as K
from keras.models import model_from_json, model_from_yaml
from keras.utils.vis_utils import plot_model

COCO_MODEL_PATH = r'../logs/shapes20191113T1540_mask_rcnn_shapes_0199.h5'

K.set_learning_phase(0)
FLAGS = flags.FLAGS

flags.DEFINE_string('input_model', default=r'', help='Path to the input model.')
flags.DEFINE_string('input_model_json', None, 'Path to the input model '
                                              'architecture in json format.')
flags.DEFINE_string('input_model_yaml', None, 'Path to the input model architecture in yaml format.')
flags.DEFINE_string('output_model', default=r'./shapes20191113T1540_mask_rcnn_shapes_0199.pb', help='Path where the converted model will be stored.')
flags.DEFINE_boolean('save_graph_def', False,
                     'Whether to save the graphdef.pbtxt file which contains '
                     'the graph definition in ASCII format.')
flags.DEFINE_string('output_nodes_prefix', None,
                    'If set, the output nodes will be renamed to '
                    '`output_nodes_prefix`+i, where `i` will numerate the '
                    'number of of output nodes of the network.')
flags.DEFINE_boolean('quantize', False,
                     'If set, the resultant TensorFlow graph weights will be '
                     'converted from float into eight-bit equivalents. See '
                     'documentation here: '
                     'https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/graph_transforms')
flags.DEFINE_boolean('channels_first', False,
                     'Whether channels are the first dimension of a tensor. '
                     'The default is TensorFlow behaviour where channels are '
                     'the last dimension.')
flags.DEFINE_boolean('output_meta_ckpt', False,
                     'If set to True, exports the model as .meta, .index, and '
                     '.data files, with a checkpoint file. These can be later '
                     'loaded in TensorFlow to continue training.')

flags.mark_flag_as_required('input_model')
flags.mark_flag_as_required('output_model')

def load_model(input_model_path, input_json_path=None, input_yaml_path=None):
    if not Path(input_model_path).exists():
        raise FileNotFoundError(
            'Model file `{}` does not exist.'.format(input_model_path))
    try:
        model = keras.models.load_model(input_model_path)
        return model
    except FileNotFoundError as err:
        logging.error('Input mode file (%s) does not exist.', FLAGS.input_model)
        raise err
    except ValueError as wrong_file_err:
        if input_json_path:
            if not Path(input_json_path).exists():
                raise FileNotFoundError(
                    'Model description json file `{}` does not exist.'.format(
                        input_json_path))
            try:
                model = model_from_json(open(str(input_json_path)).read())
                model.load_weights(input_model_path)
                return model
            except Exception as err:
                logging.error("Couldn't load model from json.")
                raise err
        elif input_yaml_path:
            if not Path(input_yaml_path).exists():
                raise FileNotFoundError(
                    'Model description yaml file `{}` does not exist.'.format(
                        input_yaml_path))
            try:
                model = model_from_yaml(open(str(input_yaml_path)).read())
                model.load_weights(input_model_path)
                return model
            except Exception as err:
                logging.error("Couldn't load model from yaml.")
                raise err
        else:
            logging.error(
                'Input file specified only holds the weights, and not '
                'the model definition. Save the model using '
                'model.save(filename.h5) which will contain the network '
                'architecture as well as its weights. '
                'If the model is saved using the '
                'model.save_weights(filename) function, either '
                'input_model_json or input_model_yaml flags should be set to '
                'to import the network architecture prior to loading the '
                'weights. \n'
                'Check the keras documentation for more details '
                '(https://keras.io/getting-started/faq/)')
            raise wrong_file_err

class ShapesConfig(Config):
    """Configuration for training on the toy shapes dataset.
    Derives from the base Config class and overrides values specific
    to the toy shapes dataset.
    """
    # Give the configuration a recognizable name
    NAME = "shapes"

    # Number of classes (including background)
    NUM_CLASSES = 1 + 14  # background + 15 object
    # Choose the number of GPU devices
    # os.environ['CUDA_VISIBLE_DEVICES'] = '0'

    # Use small images for faster training. Set the limits of the small side
    # the large side, and that determines the image shape.
    IMAGE_RESIZE_MODE = "square"
    IMAGE_MAX_DIM = 896

    RPN_ANCHOR_SCALES = (8 * 6, 16 * 6, 32 * 6, 64 * 6, 128 * 6)  # anchor side in pixels
    # RPN_ANCHOR_SCALES = (8*5, 16*5, 32*5, 64*5, 128*5)  # anchor side in pixels

    # Reduce training ROIs per image because the images are small and have
    # few objects. Aim to allow ROI sampling to pick 33% positive ROIs.
    TRAIN_ROIS_PER_IMAGE = 100

    # Use a small epoch since the data is simple
    # STEPS_PER_EPOCH = 1000
    STEPS_PER_EPOCH = 1000

    # use small validation steps since the epoch is small
    VALIDATION_STEPS = 25

def main(args):
    # If output_model path is relative and in cwd, make it absolute from root
    output_model = FLAGS.output_model
    if str(Path(output_model).parent) == '.':
        output_model = str((Path.cwd() / output_model))

    output_fld = Path(output_model).parent
    output_model_name = Path(output_model).name
    output_model_stem = Path(output_model).stem
    output_model_pbtxt_name = output_model_stem + '.pbtxt'

    # Create output directory if it does not exist
    Path(output_model).parent.mkdir(parents=True, exist_ok=True)

    if FLAGS.channels_first:
        K.set_image_data_format('channels_first')
    else:
        K.set_image_data_format('channels_last')

    # model = load_model(FLAGS.input_model, FLAGS.input_model_json, FLAGS.input_model_yaml)
    ##--------------------------------------------------------------------------------------#
    config = ShapesConfig()
    config.display()
    MODEL_DIR = r'E:\Desktop\Projects\Mask_RCNN-master\logs'
    model = modellib.MaskRCNN(mode="inference", config=config,\
                              model_dir=MODEL_DIR)
    model.load_weights(COCO_MODEL_PATH, by_name=True)#exclude=["mrcnn_class_logits", "mrcnn_bbox_fc",\
                                # "mrcnn_bbox", "mrcnn_mask"])
    # print(model.summary())
    # plot_model(model, to_file='model1.png', show_shapes=True)
    # model_json = model.to_json()
    # with open(r'./modle.json', 'w') as file:
    #     file.write(model_json)

    print('loaded model and saved json file')
    ##--------------------------------------------------------------------------------------#
    # TODO(amirabdi): Support networks with multiple inputs
    # orig_output_node_names = [node.op.name for node in model.outputs]
    orig_output_node_names = ['mrcnn_detection/Reshape_1', 'mrcnn_class/Softmax', 'mrcnn_bbox/Reshape',\
                              'mrcnn_mask/Sigmoid', 'ROI/packed_2', 'rpn_class/concat', 'rpn_bbox/concat']

    if FLAGS.output_nodes_prefix:
        num_output = len(orig_output_node_names)
        pred = [None] * num_output
        converted_output_node_names = [None] * num_output

        # Create dummy tf nodes to rename output
        for i in range(num_output):
            converted_output_node_names[i] = '{}{}'.format(
                FLAGS.output_nodes_prefix, i)
            pred[i] = tf.identity(model.outputs[i],
                                  name=converted_output_node_names[i])
    else:
        converted_output_node_names = orig_output_node_names
    logging.info('Converted output node names are: %s',
                 str(converted_output_node_names))

    sess = K.get_session()
    if FLAGS.output_meta_ckpt:
        saver = tf.train.Saver()
        saver.save(sess, str(output_fld / output_model_stem))

    if FLAGS.save_graph_def:
        tf.train.write_graph(sess.graph.as_graph_def(), str(output_fld),
                             output_model_pbtxt_name, as_text=True)
        logging.info('Saved the graph definition in ascii format at %s',
                     str(Path(output_fld) / output_model_pbtxt_name))

    if FLAGS.quantize:
        from tensorflow.tools.graph_transforms import TransformGraph
        transforms = ["quantize_weights", "quantize_nodes"]
        transformed_graph_def = TransformGraph(sess.graph.as_graph_def(), [],
                                               converted_output_node_names,
                                               transforms)
        constant_graph = graph_util.convert_variables_to_constants(
            sess,
            transformed_graph_def,
            converted_output_node_names)
    else:
        constant_graph = graph_util.convert_variables_to_constants(
            sess,
            sess.graph.as_graph_def(),
            converted_output_node_names)

    graph_io.write_graph(constant_graph, str(output_fld), output_model_name,
                         as_text=False)
    logging.info('Saved the freezed graph at %s',
                 str(Path(output_fld) / output_model_name))

if __name__ == "__main__":
    app.run(main)

load pb model

def load_detection_model(model):
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    detection_graph = tf.Graph()
    with detection_graph.as_default():
        od_graph_def = tf.GraphDef()
        with tf.gfile.GFile(model, 'rb') as fid:
            serialized_graph = fid.read()
            od_graph_def.ParseFromString(serialized_graph)
            tf.import_graph_def(od_graph_def, name='')
        input_image = tf.get_default_graph().get_tensor_by_name('input_image:0')
        input_image_meta = tf.get_default_graph().get_tensor_by_name('input_image_meta:0')
        input_anchors = tf.get_default_graph().get_tensor_by_name('input_anchors:0')
        detections = tf.get_default_graph().get_tensor_by_name('mrcnn_detection/Reshape_1:0')
        mrcnn_mask = tf.get_default_graph().get_tensor_by_name('mrcnn_mask/Sigmoid:0')
    sessd=tf.Session(config=config,graph=detection_graph)
    print('Loaded detection model from file "%s"' % model)
    return sessd, input_image, input_image_meta, input_anchors, detections, mrcnn_mask

sessd, input_image, input_image_meta, input_anchors, detections, mrcnn_mask = load_detection_model(model_path)
results = model.detect_pb([image], sessd, input_image, input_image_meta, input_anchors, detections, mrcnn_mask,verbose=1)

use model, add to mrcnn/model.py

    def detect_pb(self, images, sessd, input_image, input_image_meta, input_anchors, detections, mrcnn_mask, verbose=1):
        """Runs the detection pipeline.

        images: List of images, potentially of different sizes.

        Returns a list of dicts, one dict per image. The dict contains:
        rois: [N, (y1, x1, y2, x2)] detection bounding boxes
        class_ids: [N] int class IDs
        scores: [N] float probability scores for the class IDs
        masks: [H, W, N] instance binary masks
        """
        assert self.mode == "inference", "Create model in inference mode."
        assert len(
            images) == self.config.BATCH_SIZE, "len(images) must be equal to BATCH_SIZE"

        # if verbose:
        #     log("Processing {} images".format(len(images)))
        #     for image in images:
        #         log("image", image)

        # Mold inputs to format expected by the neural network
        molded_images, image_metas, windows = self.mold_inputs(images)

        # Validate image sizes
        # All images in a batch MUST be of the same size
        image_shape = molded_images[0].shape
        # print(image_shape, molded_images.shape)
        for g in molded_images[1:]:
            assert g.shape == image_shape,\
                "After resizing, all images must have the same size. Check IMAGE_RESIZE_MODE and image sizes."

        # Anchors
        anchors = self.get_anchors(image_shape)
        # Duplicate across the batch dimension because Keras requires it
        # TODO: can this be optimized to avoid duplicating the anchors?
        anchors = np.broadcast_to(anchors, (self.config.BATCH_SIZE,) + anchors.shape)

        # if verbose:
        #     log("molded_images", molded_images)
        #     log("image_metas", image_metas)
        #     log("anchors", anchors)
        # Run object detection
        # detections, _, _, mrcnn_mask, _, _, _ =\
        #     self.keras_model.predict([molded_images, image_metas, anchors], verbose=0)
        detectionsed, mrcnn_masked = sessd.run([detections, mrcnn_mask], feed_dict = {input_image: molded_images, \
                                                               input_image_meta: image_metas, \
                                                               input_anchors: anchors})
        mrcnn_masked = np.expand_dims(mrcnn_masked, 0)
        detections = np.array(detectionsed)
        mrcnn_mask = np.array(mrcnn_masked)
        # Process detections
        results = []
        for i, image in enumerate(images):
            xi = detections[i]
            yi = mrcnn_mask[i]
            moldedi = molded_images[i]
            windowsi = windows[i]
            final_rois, final_class_ids, final_scores, final_masks =\
                self.unmold_detections(detections[i], mrcnn_mask[i],
                                       image.shape, molded_images[i].shape,
                                       windows[i])
            results.append({
                "rois": final_rois,
                "class_ids": final_class_ids,
                "scores": final_scores,
                "masks": final_masks,
            })
        return results
chaojizhangdaxin commented 4 years ago

转换为PB文件

#!encoding = utf-8 
' ' '
#----------------- 
作者:邹九
时间:2019-11-21 
#------------ ----- 
' ' ' 
“ ” “
版权所有(c)2019,作者:Amir H. Abdi 
该脚本可根据MIT公共许可证免费获得。
有关详细信息,请参阅根目录中的许可证文件。

以下代码片段会将keras模型文件
转换为冻结的.pb tensorflow权重文件。生成的TensorFlow模型
同时包含模型架构及其关联的权重。
“ ” “

将tensorflow作为tf导入
从tensorflow.python.framework导入graph_util
从tensorflow.python.framework导入graph_io
从pathlib导入路径
从absl导入应用程序
从absl导入标志
从absl导入日志记录
从mrcnn导入模型作为modellib
从mrcnn.config导入配置
进口喀拉拉邦
导入操作系统
从keras导入后端为K
从keras.models导入model_from_json,model_from_yaml
从keras.utils.vis_utils导入plot_model

COCO_MODEL_PATH = r ' ../logs/shapes20191113T1540_mask_rcnn_shapes_0199.h5 '

K.set_learning_phase(0)
标志=标志。

flags.DEFINE_string(' input_model ',default = r ' ',help = '输入模型的路径。')
flags.DEFINE_string(' input_model_json ',None,'输入模型的
                                              路径' ' json格式的体系结构。')
flags.DEFINE_string(' input_model_yaml ',None,' yaml格式的输入模型架构的路径。')
flags.DEFINE_string(' output_model ',默认为r ' ./shapes20191113T1540_mask_rcnn_shapes_0199.pb ',help = '转换后的模型将被存储的路径。')
flags.DEFINE_boolean(' save_graph_def ',False,
                      '是否保存包含' 
                     '图形定义为ASCII格式的graphdef.pbtxt文件')。
flags.DEFINE_string(“ output_nodes_prefix ”,无,
                     “如果置位,输出节点将被重命名为” 
                    “ 'output_nodes_prefix` + i,其中`i`将且具的” 
                    “的网络的输出节点的数目。”)
flags.DEFINE_boolean(' quantize ',False,
                      '如果设置,将生成的TensorFlow图权重' 
                     '从float转换为等效的八位。请参见' 
                     '文档,在这里:' 
                     ' https : //github.com/tensorflow/ tensorflow /树/主/ tensorflow /工具/ graph_transforms ')
flags.DEFINE_boolean(' channels_first ',False,
                      '通道是否为张量的第一维。' 
                     '默认为TensorFlow行为,其中通道为' 
                     '最后维。')
flags.DEFINE_boolean(“ output_meta_ckpt ”,虚假,
                      “如果设置为True,出口模型.META,的.index,和” 
                     “数据文件,带有检查点文件。这可能是后来” 
                     '在TensorFlow装载继续训练。')

flags.mark_flag_as_required(' input_model ')
flags.mark_flag_as_required(' output_model ')

def load_model(input_model_path,input_json_path = None,input_yaml_path = None):
    如果不是Path(input_model_path).exists():
        引发FileNotFoundError(
            '模型文件`{}`不存在。' .format(input_model_path))
    尝试:
        模型= keras.models.load_model(input_model_path)
        退货模式
    除了FileNotFoundError作为err:
        logging.error('输入模式文件(%s)不存在。',FLAGS.input_model)
        提高错误
    除了ValueError作为rong_file_err:
        如果 input_json_path:
             如果不是Path(input_json_path).exists():
                引发FileNotFoundError(
                    '模型描述json文件`{}`不存在。' .format(
                        input_json_path))
            尝试:
                模型= model_from_json(open(str(input_json_path))。read())
                model.load_weights(input_model_path)
                退货模式
            例外为err:
                logging.error(“无法从json加载模型。”)
                提高错误
        elif input_yaml_path:
             如果不是Path(input_yaml_path).exists():
                引发FileNotFoundError(
                    '模型说明yaml文件`{}`不存在。' .format(
                        input_yaml_path))
            尝试:
                模型= model_from_yaml(open(str(input_yaml_path))。read())
                model.load_weights(input_model_path)
                退货模式
            例外为err:
                logging.error(“无法从Yaml加载模型。”)
                提高错误
        其他:
            记录错误(
                'Input file specified only holds the weights, and not '
                'the model definition. Save the model using '
                'model.save(filename.h5) which will contain the network '
                'architecture as well as its weights. '
                'If the model is saved using the '
                'model.save_weights(filename) function, either '
                'input_model_json or input_model_yaml flags should be set to '
                'to import the network architecture prior to loading the '
                'weights. \n'
                'Check the keras documentation for more details '
                '(https://keras.io/getting-started/faq/)')
            引发rong_file_err

ShapesConfig(Config)类:
    “ ” “配置为在玩具训练形状数据集。
    从基部配置类和覆盖值的特定导出
    到玩具形状数据集。
” “ ” #给的结构的识别的名称 
    NAME = “形状”    

    #类的数量(包括背景) 
    NUM_CLASSES = 1 + 14  #背景+ 15个对象
    #选择GPU设备的数量
    # os.environ ['CUDA_VISIBLE_DEVICES'] ='0'

    #使用较小的图像进行更快的训练。设置小边
    #的限制,确定大边,然后确定图像的形状。
    IMAGE_RESIZE_MODE = “正方形”
    IMAGE_MAX_DIM = 896

    RPN_ANCHOR_SCALES =(8 * 6,16 * 6,32 * 6,64 * 6,128 * 6)  #像素锚侧
    # RPN_ANCHOR_SCALES =(8 * 5,16 * 5,32 * 5,64 * 5,128 * 5)#锚定面(以像素为单位)

    #减少培训每个图像的ROI,因为图像是小的,
    #几个对象。旨在使ROI采样能够选择33%的正ROI。
    TRAIN_ROIS_PER_IMAGE = 100

    #使用小时期,因为数据是简单
    # STEPS_PER_EPOCH = 1000
    STEPS_PER_EPOCH = 1000

    #由于时间段较小,请使用小的验证步骤
    VALIDATION_STEPS = 25

def main(args):
    #如果output_model路径是相对路径并且在cwd中,请从根目录将其设为绝对路径
    output_model = FLAGS.output_model
    如果 str(Path(output_model).parent)== '。':
        output_model = str((Path.cwd()/ output_model))

    output_fld =路径(output_model).parent
    output_model_name =路径(output_model).name
    output_model_stem =路径(output_model).stem
    output_model_pbtxt_name = output_model_stem + '. pbtxt '

    #创建输出目录(如果不存在)
    路径(output_model).parent.mkdir(父母=真,exist_ok =真)

    如果 FLAGS.channels_first:
        K.set_image_data_format(' channels_first ')
    其他:
        K.set_image_data_format(' channels_last ')

    #模型= load_model(FLAGS.input_model,FLAGS.input_model_json,FLAGS.input_model_yaml) 
    ##------------------------------- -------------------------------------------------- -----# 
    config = ShapesConfig()
     config.display()
    MODEL_DIR = R ' E:\桌面\项目\ Mask_RCNN主\日志' 
    模型= modellib.MaskRCNN(模式= “推论”,配置=配置,\
                              model_dir = MODEL_DIR)
    model.load_weights(COCO_MODEL_PATH,by_name = TRUE) #排除= [ “mrcnn_class_logits”, “mrcnn_bbox_fc”,\ 
                                # “mrcnn_bbox”, “mrcnn_mask”]) 
    #打印(model.summary()) 
    # plot_model(型号,to_file =” model1.png 'show_shapes =真)
    # model_json = model.to_json() 
    #张开(R' ./ modle.json”, 'W'),为文件:
    #      file.write(model_json)

    打印(“加载模型和保存JSON文件”)
     ##------------------------------------- -------------------------------------------------#
    # TODO(amirabdi):具有多个输入端支持网络
    # orig_output_node_names = [node.op.name用于model.outputs节点] 
    orig_output_node_names = [ ' mrcnn_detection / Reshape_1 ',' mrcnn_class /使用SoftMax ',' mrcnn_bbox /重塑',\
                               ' mrcnn_mask / Sigmoid ',' ROI / packed_2 ',' rpn_class / concat ', ' rpn_bbox / concat ' ]

    如果 FLAGS.output_nodes_prefix:
        num_output = len(原始输出节点名称)
        pred = [无] * num_outputconvert_output_node_names 
        = [无] * num_output

        #创建虚设TF节点重命名输出
        为 我 在范围(num_output):convert_output_node_names 
            [i] = ' {} {} '. format(
                FLAGS.output_nodes_prefix,我)
            pred [i] = tf.identity(model.outputs [i],
                                  name = converted_output_node_names [i])
    其他:
        convert_output_node_names = orig_output_node_names
    logging.info('转换后的输出节点名称为:%s ',
                 str(已转换的输出节点名称)

    sess = K.get_session(),
     如果 FLAGS.output_meta_ckpt:
        saver = tf.train.Saver()
        saver.save(sess,str(output_fld / output_model_stem))

    如果 FLAGS.save_graph_def:
         tf.train.write_graph(sess.graph.as_graph_def(),str(output_fld),
                             output_model_pbtxt_name,as_text = True)
        logging.info('将图形定义以ascii格式保存在%s ',
                     str(路径(output_fld)/ output_model_pbtxt_name))

    如果 FLAGS.quantize:
        从tensorflow.tools.graph_transforms导入TransformGraph
        转换= [ “ quantize_weights ”,“ quantize_nodes ” ]
        transform_graph_def = TransformGraph(sess.graph.as_graph_def(),[],
                                               convert_output_node_names,
                                               转换)
        constant_graph = graph_util.convert_variables_to_constants(
            sess,
            Transformation_graph_def,
            convert_output_node_names)
    其他:
        constant_graph = graph_util.convert_variables_to_constants(
            sess,
            sess.graph.as_graph_def(),
            convert_output_node_names)

    graph_io.write_graph(constant_graph,str(output_fld),output_model_name,
                         as_text = False)
    logging.info('将冻结的图保存在%s ',
                 str(路径(output_fld)/ output_model_name))

如果 __name__ == “ __main__ ”:
    app.run(主)

负载铅模型

def load_detection_model(model):
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    detection_graph = tf.Graph()
    使用detection_graph.as_default():
        od_graph_def = tf.GraphDef()
        with tf.gfile.GFile(model, 'rb') as fid:
            serialized_graph = fid.read()
            od_graph_def.ParseFromString(serialized_graph)
            tf.import_graph_def(od_graph_def, name='')
        input_image = tf.get_default_graph().get_tensor_by_name('input_image:0')
        input_image_meta = tf.get_default_graph().get_tensor_by_name('input_image_meta:0')
        input_anchors = tf.get_default_graph().get_tensor_by_name('input_anchors:0')
        detections = tf.get_default_graph().get_tensor_by_name('mrcnn_detection/Reshape_1:0')
        mrcnn_mask = tf.get_default_graph().get_tensor_by_name('mrcnn_mask/Sigmoid:0')
    sessd=tf.Session(config=config,graph=detection_graph)
    print('Loaded detection model from file "%s"' % model)
    return sessd, input_image, input_image_meta, input_anchors, detections, mrcnn_mask

sessd, input_image, input_image_meta, input_anchors, detections, mrcnn_mask = load_detection_model(model_path)
results = model.detect_pb([image], sessd, input_image, input_image_meta, input_anchors, detections, mrcnn_mask,verbose=1)

use model, add to mrcnn/model.py

    def detect_pb(self, images, sessd, input_image, input_image_meta, input_anchors, detections, mrcnn_mask, verbose=1):
        """Runs the detection pipeline.

        images: List of images, potentially of different sizes.

        Returns a list of dicts, one dict per image. The dict contains:
        rois: [N, (y1, x1, y2, x2)] detection bounding boxes
        class_ids: [N] int class IDs
        scores: [N] float probability scores for the class IDs
        masks: [H, W, N] instance binary masks
        """
        assert self.mode == "inference", "Create model in inference mode."
        assert len(
            images) == self.config.BATCH_SIZE, "len(images) must be equal to BATCH_SIZE"

        # if verbose:
        #     log("Processing {} images".format(len(images)))
        #     for image in images:
        #         log("image", image)

        # Mold inputs to format expected by the neural network
        molded_images, image_metas, windows = self.mold_inputs(images)

        # Validate image sizes
        # All images in a batch MUST be of the same size
        image_shape = molded_images[0].shape
        # print(image_shape, molded_images.shape)
        for g in molded_images[1:]:
            assert g.shape == image_shape,\
                "After resizing, all images must have the same size. Check IMAGE_RESIZE_MODE and image sizes."

        # Anchors
        anchors = self.get_anchors(image_shape)
        # Duplicate across the batch dimension because Keras requires it
        # TODO: can this be optimized to avoid duplicating the anchors?
        anchors = np.broadcast_to(anchors, (self.config.BATCH_SIZE,) + anchors.shape)

        # if verbose:
        #     log("molded_images", molded_images)
        #     log("image_metas", image_metas)
        #     log("anchors", anchors)
        # Run object detection
        # detections, _, _, mrcnn_mask, _, _, _ =\
        #     self.keras_model.predict([molded_images, image_metas, anchors], verbose=0)
        detectionsed, mrcnn_masked = sessd.run([detections, mrcnn_mask], feed_dict = {input_image: molded_images, \
                                                               input_image_meta: image_metas, \
                                                               input_anchors: anchors})
        mrcnn_masked = np.expand_dims(mrcnn_masked, 0)
        detections = np.array(detectionsed)
        mrcnn_mask = np.array(mrcnn_masked)
        # Process detections
        results = []
        for i, image in enumerate(images):
            xi = detections[i]
            yi = mrcnn_mask[i]
            moldedi = molded_images[i]
            windowsi = windows[i]
            final_rois, final_class_ids, final_scores, final_masks =\
                self.unmold_detections(detections[i], mrcnn_mask[i],
                                       image.shape,molded_images [i] .shape,
                                       Windows [i])
            results.append({
                “ rois ”:final_rois,
                 “ class_ids ”:final_class_ids,
                 “ scores ”:final_scores,
                 “ masks ”:final_masks,
            })
        返回结果

Have you ever tried converting to.pb files in c++ qq:3232199602

chaojizhangdaxin commented 4 years ago

转换为PB文件

#!encoding = utf-8 
' ' '
#----------------- 
作者:邹九
时间:2019-11-21 
#------------ ----- 
' ' ' 
“ ” “
版权所有(c)2019,作者:Amir H. Abdi 
该脚本可根据MIT公共许可证免费获得。
有关详细信息,请参阅根目录中的许可证文件。

以下代码片段会将keras模型文件
转换为冻结的.pb tensorflow权重文件。生成的TensorFlow模型
同时包含模型架构及其关联的权重。
“ ” “

将tensorflow作为tf导入
从tensorflow.python.framework导入graph_util
从tensorflow.python.framework导入graph_io
从pathlib导入路径
从absl导入应用程序
从absl导入标志
从absl导入日志记录
从mrcnn导入模型作为modellib
从mrcnn.config导入配置
进口喀拉拉邦
导入操作系统
从keras导入后端为K
从keras.models导入model_from_json,model_from_yaml
从keras.utils.vis_utils导入plot_model

COCO_MODEL_PATH = r ' ../logs/shapes20191113T1540_mask_rcnn_shapes_0199.h5 '

K.set_learning_phase(0)
标志=标志。

flags.DEFINE_string(' input_model ',default = r ' ',help = '输入模型的路径。')
flags.DEFINE_string(' input_model_json ',None,'输入模型的
                                              路径' ' json格式的体系结构。')
flags.DEFINE_string(' input_model_yaml ',None,' yaml格式的输入模型架构的路径。')
flags.DEFINE_string(' output_model ',默认为r ' ./shapes20191113T1540_mask_rcnn_shapes_0199.pb ',help = '转换后的模型将被存储的路径。')
flags.DEFINE_boolean(' save_graph_def ',False,
                      '是否保存包含' 
                     '图形定义为ASCII格式的graphdef.pbtxt文件')。
flags.DEFINE_string(“ output_nodes_prefix ”,无,
                     “如果置位,输出节点将被重命名为” 
                    “ 'output_nodes_prefix` + i,其中`i`将且具的” 
                    “的网络的输出节点的数目。”)
flags.DEFINE_boolean(' quantize ',False,
                      '如果设置,将生成的TensorFlow图权重' 
                     '从float转换为等效的八位。请参见' 
                     '文档,在这里:' 
                     ' https : //github.com/tensorflow/ tensorflow /树/主/ tensorflow /工具/ graph_transforms ')
flags.DEFINE_boolean(' channels_first ',False,
                      '通道是否为张量的第一维。' 
                     '默认为TensorFlow行为,其中通道为' 
                     '最后维。')
flags.DEFINE_boolean(“ output_meta_ckpt ”,虚假,
                      “如果设置为True,出口模型.META,的.index,和” 
                     “数据文件,带有检查点文件。这可能是后来” 
                     '在TensorFlow装载继续训练。')

flags.mark_flag_as_required(' input_model ')
flags.mark_flag_as_required(' output_model ')

def load_model(input_model_path,input_json_path = None,input_yaml_path = None):
    如果不是Path(input_model_path).exists():
        引发FileNotFoundError(
            '模型文件`{}`不存在。' .format(input_model_path))
    尝试:
        模型= keras.models.load_model(input_model_path)
        退货模式
    除了FileNotFoundError作为err:
        logging.error('输入模式文件(%s)不存在。',FLAGS.input_model)
        提高错误
    除了ValueError作为rong_file_err:
        如果 input_json_path:
             如果不是Path(input_json_path).exists():
                引发FileNotFoundError(
                    '模型描述json文件`{}`不存在。' .format(
                        input_json_path))
            尝试:
                模型= model_from_json(open(str(input_json_path))。read())
                model.load_weights(input_model_path)
                退货模式
            例外为err:
                logging.error(“无法从json加载模型。”)
                提高错误
        elif input_yaml_path:
             如果不是Path(input_yaml_path).exists():
                引发FileNotFoundError(
                    '模型说明yaml文件`{}`不存在。' .format(
                        input_yaml_path))
            尝试:
                模型= model_from_yaml(open(str(input_yaml_path))。read())
                model.load_weights(input_model_path)
                退货模式
            例外为err:
                logging.error(“无法从Yaml加载模型。”)
                提高错误
        其他:
            记录错误(
                “输入文件中指定仅持有的权重,而不是” 
                '模型定义。保存使用模型“ 
                ” model.save(filename.h5),这将包含网络“ 
                ”的架构,以及其权重。“ 
                ”如果模型使用保存的“ 
                ” model.save_weights(文件名)函数,无论是“ 
                ” input_model_json或input_model_yaml标志应被设置为“ 
                ”到网络架构导入加载之前“ 
                ”的权重。\ n ' 
                '
                '(https://keras.io/getting-started/faq/)')
            引发rong_file_err

ShapesConfig(Config)类:
    “ ” “配置为在玩具训练形状数据集。
    从基部配置类和覆盖值的特定导出
    到玩具形状数据集。
” “ ” #给的结构的识别的名称 
    NAME = “形状”    

    #类的数量(包括背景) 
    NUM_CLASSES = 1 + 14  #背景+ 15个对象
    #选择GPU设备的数量
    # os.environ ['CUDA_VISIBLE_DEVICES'] ='0'

    #使用较小的图像进行更快的训练。设置小边
    #的限制,确定大边,然后确定图像的形状。
    IMAGE_RESIZE_MODE = “正方形”
    IMAGE_MAX_DIM = 896

    RPN_ANCHOR_SCALES =(8 * 6,16 * 6,32 * 6,64 * 6,128 * 6)  #像素锚侧
    # RPN_ANCHOR_SCALES =(8 * 5,16 * 5,32 * 5,64 * 5,128 * 5)#锚定面(以像素为单位)

    #减少培训每个图像的ROI,因为图像是小的,
    #几个对象。旨在使ROI采样能够选择33%的正ROI。
    TRAIN_ROIS_PER_IMAGE = 100

    #使用小时期,因为数据是简单
    # STEPS_PER_EPOCH = 1000
    STEPS_PER_EPOCH = 1000

    #由于时间段较小,请使用小的验证步骤
    VALIDATION_STEPS = 25

def main(args):
    #如果output_model路径是相对路径并且在cwd中,请从根目录将其设为绝对路径
    output_model = FLAGS.output_model
    如果 str(Path(output_model).parent)== '。':
        output_model = str((Path.cwd()/ output_model))

    output_fld =路径(output_model).parent
    output_model_name =路径(output_model).name
    output_model_stem =路径(output_model).stem
    output_model_pbtxt_name = output_model_stem + '. pbtxt '

    #创建输出目录(如果不存在)
    路径(output_model).parent.mkdir(父母=真,exist_ok =真)

    如果 FLAGS.channels_first:
        K.set_image_data_format(' channels_first ')
    其他:
        K.set_image_data_format(' channels_last ')

    #模型= load_model(FLAGS.input_model,FLAGS.input_model_json,FLAGS.input_model_yaml) 
    ##------------------------------- -------------------------------------------------- -----# 
    config = ShapesConfig()
     config.display()
    MODEL_DIR = R ' E:\桌面\项目\ Mask_RCNN主\日志' 
    模型= modellib.MaskRCNN(模式= “推论”,配置=配置,\
                              model_dir = MODEL_DIR)
    model.load_weights(COCO_MODEL_PATH,by_name = TRUE) #排除= [ “mrcnn_class_logits”, “mrcnn_bbox_fc”,\ 
                                # “mrcnn_bbox”, “mrcnn_mask”]) 
    #打印(model.summary()) 
    # plot_model(型号,to_file =” model1.png 'show_shapes =真)
    # model_json = model.to_json() 
    #张开(R' ./ modle.json”, 'W'),为文件:
    #      file.write(model_json)

    打印(“加载模型和保存JSON文件”)
     ##------------------------------------- -------------------------------------------------#
    # TODO(amirabdi):具有多个输入端支持网络
    # orig_output_node_names = [node.op.name用于model.outputs节点] 
    orig_output_node_names = [ ' mrcnn_detection / Reshape_1 ',' mrcnn_class /使用SoftMax ',' mrcnn_bbox /重塑',\
                               ' mrcnn_mask / Sigmoid ',' ROI / packed_2 ',' rpn_class / concat ', ' rpn_bbox / concat ' ]

    如果 FLAGS.output_nodes_prefix:
        num_output = len(原始输出节点名称)
        pred = [无] * num_outputconvert_output_node_names 
        = [无] * num_output

        #创建虚设TF节点重命名输出
        为 我 在范围(num_output):convert_output_node_names 
            [i] = ' {} {} '. format(
                FLAGS.output_nodes_prefix,我)
            pred [i] = tf.identity(model.outputs [i],
                                  name = converted_output_node_names [i])
    其他:
        convert_output_node_names = orig_output_node_names
    logging.info('转换后的输出节点名称为:%s ',
                 str(已转换的输出节点名称)

    sess = K.get_session(),
     如果 FLAGS.output_meta_ckpt:
        saver = tf.train.Saver()
        saver.save(sess,str(output_fld / output_model_stem))

    如果 FLAGS.save_graph_def:
         tf.train.write_graph(sess.graph.as_graph_def(),str(output_fld),
                             output_model_pbtxt_name,as_text = True)
        logging.info('将图形定义以ascii格式保存在%s ',
                     str(路径(output_fld)/ output_model_pbtxt_name))

    如果 FLAGS.quantize:
        从tensorflow.tools.graph_transforms导入TransformGraph
        转换= [ “ quantize_weights ”,“ quantize_nodes ” ]
        transform_graph_def = TransformGraph(sess.graph.as_graph_def(),[],
                                               convert_output_node_names,
                                               转换)
        constant_graph = graph_util.convert_variables_to_constants(
            sess,
            Transformation_graph_def,
            convert_output_node_names)
    其他:
        constant_graph = graph_util.convert_variables_to_constants(
            sess,
            sess.graph.as_graph_def(),
            convert_output_node_names)

    graph_io.write_graph(constant_graph,str(output_fld),output_model_name,
                         as_text = False)
    logging.info('将冻结的图保存在%s ',
                 str(路径(output_fld)/ output_model_name))

如果 __name__ == “ __main__ ”:
    app.run(主)

负载铅模型

def load_detection_model(model):
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    detection_graph = tf.Graph()
    使用detection_graph.as_default():
        od_graph_def = tf.GraphDef()
        使用tf.gfile.GFile(model,' rb ')作为fid:
            serialized_graph = fid.read()
            od_graph_def.ParseFromString(serialized_graph)
            tf.import_graph_def(od_graph_def,name = ' ')
        input_image = tf.get_default_graph().get_tensor_by_name(' input_image:0 ')
        input_image_meta = tf.get_default_graph().get_tensor_by_name(' input_image_meta:0 ')
        input_anchors = tf.get_default_graph().get_tensor_by_name(' input_anchors:0 ')
        检测= tf.get_default_graph().get_tensor_by_name(' mrcnn_detection / Reshape_1:0 ')
        mrcnn_mask = tf.get_default_graph().get_tensor_by_name(' mrcnn_mask / Sigmoid:0 ')
    sessd = tf.Session(config = config,graph = detection_graph)
    print('从文件“%s”加载检测模型'%模型)
     返回 sessd,input_image,input_image_meta,input_anchors,检测,mrcnn_mask

sessd,input_image,input_image_meta,input_anchors,检测,mrcnn_mask = load_detection_model(model_path)
结果= model.detect_pb([图像],sessd,input_image,input_image_meta,input_anchors,检测,mrcnn_mask,verbose = 1)

使用模型,添加到mrcnn / model.py

    DEF detect_pb(个体,图像,sessd,input_image,input_image_meta,input_anchors,检测,mrcnn_mask,详细= 1): “
        ” “运行的检测管道。

        图片:图片列表,可能大小不同。

        返回字典列表,每个图像一个字典。dict包含:
        rois:[N,(y1,x1,y2,x2)]检测边界框
        class_ids:[N] int类ID 
        得分:[N]类ID 
        掩码的
浮动概率得分:[H,W,N ]实例二进制掩码“ ” “ 
        assert self.mode == ” inference “,”以推理模式创建模型。”        
        断言len(
            images)== self.config.BATCH_SIZE,“ len(images)必须等于BATCH_SIZE ”

        #如果冗长:
        #      日志( “处理{}图像” .format(LEN(图像))) 
        #      用于图像的图像:
        #          日志( “图像”,图像)

        #将输入转换为神经网络期望的格式
        moulded_images,image_metas,windows = self.mold_inputs(images)

        #验证图像大小
        #批处理中的所有图像必须具有相同的大小
        image_shape = moulded_images [0] .shape
        #打印(image_shape,molded_images.shape)
        为 克 在 molded_images [1:]:
            断言g.shape == image_shape,\
                “调整大小后,所有图像都必须具有相同的大小。检查IMAGE_RESIZE_MODE和图像大小。”

        #锚
        锚点= self.get_anchors(image_shape)
        #跨批次尺寸复制,因为Keras需要它
        # TODO:可以在此进行优化,以避免重复锚?
        锚点= np.broadcast_to(锚点((self.config.BATCH_SIZE,)+ anchors.shape)

        #如果冗长:
        #      日志( “molded_images”,molded_images) 
        #      日志( “image_metas”,image_metas) 
        #      日志( “锚”,锚)
        #运行物体检测
        #检测,_,_,mrcnn_mask,_,_,_ = \ 
        #      self.keras_model.predict([molded_images,image_metas,anchors,verbose = 0)
        detectionsed,mrcnn_masked = sessd.run([detections,mrcnn_mask],feed_dict = {input_image:moulded_images,\
                                                               input_image_meta:image_metas,
                                                               input_anchors:anchor})
        mrcnn_masked = np.expand_dims(mrcnn_masked,0)
        检测数= np.array(检测到)
        mrcnn_mask = np.array(mrcnn_masked)
        #流程检测
        结果= []
        为 I,图像 在枚举(图像):
            xi =检测次数[i]
            yi = mrcnn_mask [i]
            mouldedi = moulded_images [i]
            Windowsi = Windows [i]
            final_rois,final_class_ids,final_scores,final_masks = \
                self.unmold_detections(detections [i],mrcnn_mask [i],
                                       image.shape,molded_images [i] .shape,
                                       Windows [i])
            results.append({
                “ rois ”:final_rois,
                 “ class_ids ”:final_class_ids,
                 “ scores ”:final_scores,
                 “ masks ”:final_masks,
            })
        返回结果

转换成功的.pb文件可以在c++中使用吗?qq3232199602