简体   繁体   English

如何将具有自定义 keras 层(.h5)的 keras 模型冻结到张量流图(.pb)?

[英]How to freeze a keras model with custom keras layers(.h5) to tensorflow graph(.pb)?

I am trying to implement a Faster-RCNN model for object detection written by Yinghan Xu .我正在尝试实现由 Yinghan Xu 编写的用于对象检测的 Faster-RCNN 模型。 After I have trained and saved the model with model_all.save('filename.h5') , I am trying to freeze the Keras model as TensorFlow graph (as .pb ) for inference using keras_to_tensorflow.py written by Amir Abdi.在我使用model_all.save('filename.h5')训练并保存模型后,我尝试使用 Amir Abdi 编写的keras_to_tensorflow.pyKeras模型冻结为 TensorFlow 图(作为.pb )以进行推理。 But when I try to convert it, I get a ValueError: Unknown layer: roipoolingconv due to a custom RoiPoolingConv layer:但是当我尝试转换它时,由于自定义RoiPoolingConv层,我得到一个ValueError: Unknown layer: roipoolingconv :

class RoiPoolingConv(Layer):
'''ROI pooling layer for 2D inputs.
See Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition,
K. He, X. Zhang, S. Ren, J. Sun
# Arguments
    pool_size: int
        Size of pooling region to use. pool_size = 7 will result in a 7x7 region.
    num_rois: number of regions of interest to be used
# Input shape
    list of two 4D tensors [X_img,X_roi] with shape:
    X_img:
    `(1, rows, cols, channels)`
    X_roi:
    `(1,num_rois,4)` list of rois, with ordering (x,y,w,h)
# Output shape
    3D tensor with shape:
    `(1, num_rois, channels, pool_size, pool_size)`
'''
def __init__(self, pool_size, num_rois, **kwargs):

    self.dim_ordering = K.image_dim_ordering()
    self.pool_size = pool_size
    self.num_rois = num_rois

    super(RoiPoolingConv, self).__init__(**kwargs)

def build(self, input_shape):
    self.nb_channels = input_shape[0][3]   

def compute_output_shape(self, input_shape):
    return None, self.num_rois, self.pool_size, self.pool_size, self.nb_channels

def call(self, x, mask=None):

    assert(len(x) == 2)

    # x[0] is image with shape (rows, cols, channels)
    img = x[0]

    # x[1] is roi with shape (num_rois,4) with ordering (x,y,w,h)
    rois = x[1]

    input_shape = K.shape(img)

    outputs = []

    for roi_idx in range(self.num_rois):

        x = rois[0, roi_idx, 0]
        y = rois[0, roi_idx, 1]
        w = rois[0, roi_idx, 2]
        h = rois[0, roi_idx, 3]

        x = K.cast(x, 'int32')
        y = K.cast(y, 'int32')
        w = K.cast(w, 'int32')
        h = K.cast(h, 'int32')

        # Resized roi of the image to pooling size (7x7)
        rs = tf.image.resize_images(img[:, y:y+h, x:x+w, :], (self.pool_size, self.pool_size))
        outputs.append(rs)


    final_output = K.concatenate(outputs, axis=0)

    # Reshape to (1, num_rois, pool_size, pool_size, nb_channels)
    # Might be (1, 4, 7, 7, 3)
    final_output = K.reshape(final_output, (1, self.num_rois, self.pool_size, self.pool_size, self.nb_channels))

    # permute_dimensions is similar to transpose
    final_output = K.permute_dimensions(final_output, (0, 1, 2, 3, 4))

    return final_output


def get_config(self):
    config = {'pool_size': self.pool_size,
              'num_rois': self.num_rois}
    base_config = super(RoiPoolingConv, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

I have looked at most of the resources out there and almost all of them suggest to comment out this layer.我已经查看了那里的大部分资源,几乎所有资源都建议注释掉这一层。 But since this layer is important for object detection, I was wondering if a workaround is possible or not.但是由于这一层对于对象检测很重要,我想知道是否有可能的解决方法。

The complete traceback of error (note: I've saved filename as freezekeras.py , contents are same as keras_to_tensorflow.py ):错误的完整回溯(注:我已经保存的文件名作为freezekeras.py ,内容为相同keras_to_tensorflow.py ):

Using TensorFlow backend.
Traceback (most recent call last):


File "freezekeras.py", line 181, in <module>
    app.run(main)
  File "/usr/local/lib/python3.5/dist-packages/absl/app.py", line 300, in run
    _run_main(main, args)
  File "/usr/local/lib/python3.5/dist-packages/absl/app.py", line 251, in _run_main
    sys.exit(main(argv))
  File "freezekeras.py", line 127, in main
    model = load_model(FLAGS.input_model, FLAGS.input_model_json, FLAGS.input_model_yaml)
  File "freezekeras.py", line 105, in load_model
    raise wrong_file_err
  File "freezekeras.py", line 62, in load_model
    model = keras.models.load_model(input_model_path)
  File "/usr/local/lib/python3.5/dist-packages/keras/engine/saving.py", line 419, in load_model
    model = _deserialize_model(f, custom_objects, compile)
  File "/usr/local/lib/python3.5/dist-packages/keras/engine/saving.py", line 225, in _deserialize_model
    model = model_from_config(model_config, custom_objects=custom_objects)
  File "/usr/local/lib/python3.5/dist-packages/keras/engine/saving.py", line 458, in model_from_config
    return deserialize(config, custom_objects=custom_objects)
  File "/usr/local/lib/python3.5/dist-packages/keras/layers/__init__.py", line 55, in deserialize
    printable_module_name='layer')
  File "/usr/local/lib/python3.5/dist-packages/keras/utils/generic_utils.py", line 145, in deserialize_keras_object
    list(custom_objects.items())))
  File "/usr/local/lib/python3.5/dist-packages/keras/engine/network.py", line 1022, in from_config
    process_layer(layer_data)
  File "/usr/local/lib/python3.5/dist-packages/keras/engine/network.py", line 1008, in process_layer
    custom_objects=custom_objects)
  File "/usr/local/lib/python3.5/dist-packages/keras/layers/__init__.py", line 55, in deserialize
    printable_module_name='layer')
  File "/usr/local/lib/python3.5/dist-packages/keras/utils/generic_utils.py", line 138, in deserialize_keras_object
    ': ' + class_name)
ValueError: Unknown layer: RoiPoolingConv

Try to specify the custom layer explicitly:尝试明确指定自定义层:

model = load_model('my_model.h5', custom_objects={'RoiPoolingConv': RoiPoolingConv})

Obviously, you have to re-write the keras_to_tensorflow.py script.显然,您必须重新编写keras_to_tensorflow.py脚本。 See Handling custom layers (or other custom objects) in saved models section under Keras FAQ .请参阅Keras FAQ下的在保存的模型中处理自定义层(或其他自定义对象)部分。

Solution解决方案

  1. specify custom layer while loading model in keras_to_tensorflow.pykeras_to_tensorflow.py加载模型时指定自定义层
    model = keras.models.load_model(input_model_path, custom_objects={'RoiPoolingConv':RoiPoolingConv})
  1. import RoiPoolingConv.py to keras_to_tensorflow project将 RoiPoolingConv.py 导入 keras_to_tensorflow 项目
  2. specify default pool_size, num_rois for RoiPoolingConv为 RoiPoolingConv 指定默认 pool_size、num_rois
    def __init__(self, pool_size = 7, num_rois = 32, **kwargs):

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将 Keras.h5 导出为 tensorflow.pb? - How to export Keras .h5 to tensorflow .pb? 如何将预训练的 tensorflow pb 冻结图转换为可修改的 h5 keras 模型? - How to convert a pretrained tensorflow pb frozen graph into a modifiable h5 keras model? 无法将 keras/tensorflow h5/json 转换为 tensorflow pb - Trouble converting keras/tensorflow h5/json into tensorflow pb 将keras h5转换为tensorflow pb以进行批处理推断 - convert keras h5 to tensorflow pb for batch inference 加载 Tensorflow keras Model (.h5) 时出错 - Error loading Tensorflow keras Model (.h5) 如何将 .pb 文件转换为 .h5。 (Tensorflow 模型到 keras) - How to convert .pb file to .h5. (Tensorflow model to keras) Convert a Tensorflow model in SavedModel format (.pb file) saved with tf.saved_model.save to a Keras model (.h5 file) - Convert a Tensorflow model in SavedModel format (.pb file) saved with tf.saved_model.save to a Keras model (.h5 file) 如何在 TensorFlow 2.0 中冻结 keras model? (专门将一个保存的model格式冻结为.pb格式) - How to freeze a keras model in TensorFlow 2.0? (specifically freeze a saved model format to .pb format) keras.models.save_model 中的 saved_model.pb 是否与 tensorflow freeze_graph output.pb 文件相同? - Is saved_model.pb from keras.models.save_model the same with tensorflow freeze_graph output .pb file? keras模型H5在理论上如何工作 - How keras model H5 works in theory
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM