如何将已训练好的Tensorflow模型转换为Keras?

28

我有一个训练好的Tensorflow模型和权重向量,已经被导出成protobuf和权重文件。

我该如何将它们转换成JSON或YAML和HDF5文件,以便Keras能够使用?

我有Tensorflow模型的代码,因此也可以将tf.Session转换为Keras模型并在代码中保存。

4个回答

12

我认为在keras中使用回调函数也是一种解决方案。

TF可以使用以下方式保存ckpt文件:

saver = tf.train.Saver()
saver.save(sess, checkpoint_name)

要在Keras中加载检查点,您需要一个回调类,如下所示:

class RestoreCkptCallback(keras.callbacks.Callback):
    def __init__(self, pretrained_file):
        self.pretrained_file = pretrained_file
        self.sess = keras.backend.get_session()
        self.saver = tf.train.Saver()
    def on_train_begin(self, logs=None):
        if self.pretrian_model_path:
            self.saver.restore(self.sess, self.pretrian_model_path)
            print('load weights: OK.')

然后在你的Keras脚本中:

 model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
 restore_ckpt_callback = RestoreCkptCallback(pretrian_model_path='./XXXX.ckpt') 
 model.fit(x_train, y_train, batch_size=128, epochs=20, callbacks=[restore_ckpt_callback])

那将很好。 我认为这很容易实现,希望能有所帮助。


你好,MyCallbacks是什么? - Austin
嗨,@Austin,MyCallbacks是RestoreCkptCallback。我已经更正了我的帖子。谢谢你的提醒! - Jiang Xiang
然而,这需要你用keras编写模型,不是吗? - Henrique Mendonça

12

keras的创始人Francois Chollet在04/2017曾说过:“您不能将任意TensorFlow检查点转换为Keras模型。但是,您可以构建一个等效的Keras模型,然后将权重加载到该Keras模型中。”,详情请见https://github.com/keras-team/keras/issues/5273。据我所知,这种情况并未改变。

一个小例子:

首先,您可以像这样提取tensorflow检查点的权重

PATH_REL_META = r'checkpoint1.meta'
    
# start tensorflow session
with tf.Session() as sess:
    
    # import graph
    saver = tf.train.import_meta_graph(PATH_REL_META)
    
    # load weights for graph
    saver.restore(sess, PATH_REL_META[:-5])
        
    # get all global variables (including model variables)
    vars_global = tf.global_variables()
    
    # get their name and value and put them into dictionary
    sess.as_default()
    model_vars = {}
    for var in vars_global:
        try:
            model_vars[var.name] = var.eval()
        except:
            print("For var={}, an exception occurred".format(var.name))

还可以将tensorflow模型导出供tensorboard使用,详情请参见https://dev59.com/2lsX5IYBdhLWcg3wHcTA#43569991

其次,您可以像往常一样构建keras模型,并通过“model.compile”完成最终编译。请注意,您需要为每个层定义名称并在此之后将其添加到模型中,例如:

layer_1 = keras.layers.Conv2D(6, (7,7), activation='relu', input_shape=(48,48,1))
net.add(layer_1)
...
net.compile(...)

第三,您可以使用tensorflow的值来设置权重,例如:

layer_1.set_weights([model_vars['conv7x7x1_1/kernel:0'], model_vars['conv7x7x1_1/bias:0']])

如何处理batch_norm层,因为它们有4个参数,似乎会引起问题... - ADA
1
@ADA:不是100%确定,但如果您发布一个包含最小代码示例的新问题,我或其他人可以看一下。 - gebbissimo
谢谢,我发了一篇帖子。我很想知道我漏掉了什么,请提供意见。 - ADA

10

目前,Tensorflow或Keras中没有直接内置支持将冻结模型或检查点文件转换为hdf5格式的方法。

但是,既然您提到了您拥有Tensorflow模型的代码,那么您将需要在Keras中重写该模型的代码。然后,您将需要使用layer.load_weights(weights)方法从检查点文件中读取变量的值,并将其分配给Keras模型。

除了这种方法之外,我建议您直接在Keras中进行训练,因为据称Keras的优化器比Tensorflow的优化器快5-10%。另一种方法是使用tf.contrib.keras模块编写您的代码,并直接将文件保存为hdf5格式。


1
不确定这是否是您要找的,但我碰巧刚刚使用了 TF 1.2 中新发布的 keras 支持。您可以在此处找到更多有关 API 的信息:https://www.tensorflow.org/api_docs/python/tf/contrib/keras 为了节省一些时间,我还发现我必须包含如下所示的 keras 模块,并将其附加到 API 文档中显示的内容中。

from tensorflow.contrib.keras.python.keras.models import Sequential

希望这能帮助您达到想要去的地方。基本上一旦集成,您就可以像往常一样处理模型/权重导出。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接