Python 如何将具有自定义keras图层(.h5)的keras模型冻结为tensorflow图(.pb)?

Python 如何将具有自定义keras图层(.h5)的keras模型冻结为tensorflow图(.pb)?,python,tensorflow,keras,Python,Tensorflow,Keras,我正在尝试实现一个更快的目标检测RCNN模型。在我使用model\u all.save('filename.h5')训练并保存模型后,我尝试将Keras模型冻结为TensorFlow图(as.pb),以便使用Amir Abdi编写的进行推理。但是当我尝试转换它时,由于自定义的roipoolgconv层,我得到了一个ValueError:Unknown层:roipoolgconv: class RoiPoolingConv(Layer): '''ROI pooling layer for 2D i

我正在尝试实现一个更快的目标检测RCNN模型。在我使用
model\u all.save('filename.h5')
训练并保存模型后,我尝试将Keras模型冻结为TensorFlow图(as
.pb
),以便使用Amir Abdi编写的进行推理。但是当我尝试转换它时,由于自定义的
roipoolgconv
层,我得到了一个
ValueError:Unknown层:roipoolgconv

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()))
我已经查看了大部分资源,几乎所有资源都建议对这一层进行注释。但是,由于这一层对于目标检测很重要,我想知道是否有一个解决办法

错误的完整回溯(注意:我已将文件名保存为
freezekeras.py
,内容与
keras\u to\u tensorflow.py
)相同:

使用TensorFlow后端。
回溯(最近一次呼叫最后一次):
文件“freezekeras.py”,第181行,在
应用程序运行(主)
文件“/usr/local/lib/python3.5/dist-packages/absl/app.py”,第300行,运行中
_运行_main(main,args)
文件“/usr/local/lib/python3.5/dist-packages/absl/app.py”,第251行,在主
系统出口(主(argv))
文件“freezekeras.py”,第127行,在main中
model=load\u model(FLAGS.input\u model、FLAGS.input\u model\u json、FLAGS.input\u model\u yaml)
文件“freezekeras.py”,第105行,在load_模型中
提出错误的\u文件\u错误
文件“freezekeras.py”,第62行,在load_模型中
模型=keras.models.load\u模型(输入模型路径)
文件“/usr/local/lib/python3.5/dist-packages/keras/engine/saving.py”,第419行,在load_模型中
model=\反序列化\模型(f,自定义\对象,编译)
文件“/usr/local/lib/python3.5/dist-packages/keras/engine/saving.py”,第225行,在反序列化模型中
模型=来自配置的模型(模型配置,自定义对象=自定义对象)
文件“/usr/local/lib/python3.5/dist-packages/keras/engine/saving.py”,第458行,型号为
返回反序列化(配置,自定义对象=自定义对象)
文件“/usr/local/lib/python3.5/dist-packages/keras/layers/_-init__.py”,第55行,反序列化
可打印\u模块\u name='layer')
文件“/usr/local/lib/python3.5/dist packages/keras/utils/generic_utils.py”,第145行,反序列化_keras_对象
列表(自定义对象.项())
文件“/usr/local/lib/python3.5/dist packages/keras/engine/network.py”,第1022行,from_config
处理层(层数据)
文件“/usr/local/lib/python3.5/dist-packages/keras/engine/network.py”,第1008行,进程层中
自定义对象=自定义对象)
文件“/usr/local/lib/python3.5/dist-packages/keras/layers/_-init__.py”,第55行,反序列化
可打印\u模块\u name='layer')
文件“/usr/local/lib/python3.5/dist packages/keras/utils/generic_utils.py”,第138行,反序列化_keras_对象
“:”+类名)
ValueError:未知层:ROIPoolGCONV

尝试明确指定自定义图层:

model = load_model('my_model.h5', custom_objects={'RoiPoolingConv': RoiPoolingConv})
显然,您必须将
keras\u重新编写为\u tensorflow.py
脚本。请参见解决方案下的“保存的模型”部分中的“处理自定义图层(或其他自定义对象)”
  • keras\u to\u tensorflow.py中加载模型时指定自定义层
  • 将RoipoolConv.py导入keras\u to\u tensorflow项目
  • 为ROIPOOLGCONV指定默认池大小、ROI数量

  • 请提供错误的完整跟踪堆栈。确定!我加了,谢谢!我没有在正确的位置进行搜索,我修改了代码,它工作正常。
    model = load_model('my_model.h5', custom_objects={'RoiPoolingConv': RoiPoolingConv})
    
        model = keras.models.load_model(input_model_path, custom_objects={'RoiPoolingConv':RoiPoolingConv})
    
        def __init__(self, pool_size = 7, num_rois = 32, **kwargs):