【问题标题】:How to save/restore a model after training?训练后如何保存/恢复模型?
【发布时间】:2016-02-18 23:34:45
【问题描述】:

在 Tensorflow 中训练模型后:

  1. 如何保存训练好的模型?
  2. 以后如何恢复这个保存的模型?

【问题讨论】:

  • 你能恢复初始模型中使用的变量吗?我也在尝试完全相同的问题,但我无法编写训练初始模型时使用的一组变量(我有 ckpt 文件)
  • 我没有尝试过初始模型。你有模型的网络结构和它的名字吗?正如 Ryan 解释的那样,您必须复制网络,然后加载权重和偏差(ckpt 文件)。也许自 15 年 11 月以来发生了一些变化,现在有一种更直接的方法,我不确定
  • 哦,好吧。我之前已经加载了其他预训练的张量流模型,但正在寻找初始模型的可变规格。谢谢。
  • 如果您恢复继续训练,只需使用 Saver 检查点。如果您保存模型以进行引用,则只需使用 tensorflow SavedModel API。
  • 另外,如果您使用 LSTM,您将拥有从字符串到字符列表的映射,请务必以相同的顺序保存和加载该列表!保存模型权重和模型图网络不涵盖这一点,并且会在您更改会话或数据更改时看起来好像您的模型没有加载。

标签: python tensorflow


【解决方案1】:

对于 TensorFlow 版本

保存的检查点包含模型中Variables 的值,而不是模型/图形本身,这意味着恢复检查点时图形应该相同。

这是一个线性回归示例,其中有一个保存变量检查点的训练循环和一个用于恢复先前运行中保存的变量并计算预测的评估部分。当然,如果您愿意,您也可以恢复变量并继续训练。

x = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)

w = tf.Variable(tf.zeros([1, 1], dtype=tf.float32))
b = tf.Variable(tf.ones([1, 1], dtype=tf.float32))
y_hat = tf.add(b, tf.matmul(x, w))

...more setup for optimization and what not...

saver = tf.train.Saver()  # defaults to saving all variables - in this case w and b

with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    if FLAGS.train:
        for i in xrange(FLAGS.training_steps):
            ...training loop...
            if (i + 1) % FLAGS.checkpoint_steps == 0:
                saver.save(sess, FLAGS.checkpoint_dir + 'model.ckpt',
                           global_step=i+1)
    else:
        # Here's where you're restoring the variables w and b.
        # Note that the graph is exactly as it was when the variables were
        # saved in a prior training run.
        ckpt = tf.train.get_checkpoint_state(FLAGS.checkpoint_dir)
        if ckpt and ckpt.model_checkpoint_path:
            saver.restore(sess, ckpt.model_checkpoint_path)
        else:
            ...no checkpoint found...

        # Now you can run the model to get predictions
        batch_x = ...load some data...
        predictions = sess.run(y_hat, feed_dict={x: batch_x})

这里是Variables 的docs,包括保存和恢复。这里是docsSaver

【讨论】:

  • FLAGS 是用户定义的。这是定义它们的示例:github.com/tensorflow/tensorflow/blob/master/tensorflow/…
  • batch_x 需要采用哪种格式?二进制? numpy 数组?
  • @pepe Numpy arrary 应该没问题。并且元素的类型应该与占位符的类型相对应。 [链接]tensorflow.org/versions/r0.9/api_docs/python/…
  • FLAGS 给出错误undefined。你能告诉我这段代码的 FLAGS 是哪个 def 吗? @RyanSepassi
  • 明确说明:Tensorflow 的最新版本 do 允许存储模型/图形。 [我不清楚答案的哪些方面适用于
【解决方案2】:

模型有两部分,模型定义,由Supervisor保存在模型目录中graph.pbtxt,张量的数值,保存到model.ckpt-1003418等检查点文件中。

可以使用tf.import_graph_def恢复模型定义,使用Saver恢复权重。

但是,Saver 使用特殊的集合来保存附加到模型 Graph 的变量列表,并且此集合未使用 import_graph_def 初始化,因此您目前不能将两者一起使用(它在我们的路线图上进行修复)。现在,您必须使用 Ryan Sepassi 的方法——手动构建一个具有相同节点名称的图,并使用Saver 将权重加载到其中。

(或者,您可以通过使用import_graph_def 来破解它,手动创建变量,并为每个变量使用tf.add_to_collection(tf.GraphKeys.VARIABLES, variable),然后使用Saver

【讨论】:

  • 在使用inceptionv3的classify_image.py示例中,只加载了graphdef。这是否意味着现在 GraphDef 也包含变量?
  • @jrabary 模型可能是frozen
  • 嘿,我是 tensorflow 新手,无法保存我的模型。如果您能帮助我,我将不胜感激stackoverflow.com/questions/48083474/…
【解决方案3】:

正如 Yaroslav 所说,您可以通过导入图形、手动创建变量,然后使用 Saver 来破解从 graph_def 和检查点恢复。

我实现这个是为了我个人使用,所以我想在这里分享代码。

链接:https://gist.github.com/nikitakit/6ef3b72be67b86cb7868

(当然,这是一种 hack,不能保证以这种方式保存的模型在未来的 TensorFlow 版本中仍然可读。)

【讨论】:

    【解决方案4】:

    您还可以在TensorFlow/skflow 中查看examples,它提供了saverestore 方法,可以帮助您轻松管理模型。它具有参数,您还可以控制备份模型的频率。

    【讨论】:

      【解决方案5】:

      如果是内部保存的模型,你只需为所有变量指定一个恢复器为

      restorer = tf.train.Saver(tf.all_variables())
      

      并使用它来恢复当前会话中的变量:

      restorer.restore(self._sess, model_file)
      

      对于外部模型,您需要指定从其变量名到您的变量名的映射。您可以使用命令查看模型变量名称

      python /path/to/tensorflow/tensorflow/python/tools/inspect_checkpoint.py --file_name=/path/to/pretrained_model/model.ckpt
      

      inspect_checkpoint.py 脚本可以在 Tensorflow 源码的 './tensorflow/python/tools' 文件夹中找到。

      要指定映射,可以使用我的Tensorflow-Worklab,其中包含一组类和脚本,用于训练和重新训练不同的模型。它包括一个重新训练 ResNet 模型的示例,位于 here

      【讨论】:

      【解决方案6】:

      在 TensorFlow 0.11.0RC1(及之后)版本中,您可以根据https://www.tensorflow.org/programmers_guide/meta_graph 调用tf.train.export_meta_graphtf.train.import_meta_graph 直接保存和恢复您的模型。

      保存模型

      w1 = tf.Variable(tf.truncated_normal(shape=[10]), name='w1')
      w2 = tf.Variable(tf.truncated_normal(shape=[20]), name='w2')
      tf.add_to_collection('vars', w1)
      tf.add_to_collection('vars', w2)
      saver = tf.train.Saver()
      sess = tf.Session()
      sess.run(tf.global_variables_initializer())
      saver.save(sess, 'my-model')
      # `save` method will call `export_meta_graph` implicitly.
      # you will get saved graph files:my-model.meta
      

      恢复模型

      sess = tf.Session()
      new_saver = tf.train.import_meta_graph('my-model.meta')
      new_saver.restore(sess, tf.train.latest_checkpoint('./'))
      all_vars = tf.get_collection('vars')
      for v in all_vars:
          v_ = sess.run(v)
          print(v_)
      

      【讨论】:

      • 如何从保存的模型中加载变量?如何复制其他变量中的值?
      • 我无法让这段代码工作。模型确实保存了,但我无法恢复它。它给了我这个错误。 <built-in function TF_Run> returned a result with an error set
      • 恢复后我访问变量如上所示,它可以工作。但我无法更直接地使用tf.get_variable_scope().reuse_variables() 后跟var = tf.get_variable("varname") 获取变量。这给了我错误:“ValueError:变量 varname 不存在,或者不是用 tf.get_variable() 创建的。”为什么?这不应该吗?
      • 这仅适用于变量,但如何在恢复图形后访问占位符并为其提供值?
      • 这里只显示如何恢复变量。如何在不重新定义网络的情况下恢复整个模型并在新数据上对其进行测试?
      【解决方案7】:

      如问题6255中所述:

      use '**./**model_name.ckpt'
      saver.restore(sess,'./my_model_final.ckpt')
      

      而不是

      saver.restore('my_model_final.ckpt')
      

      【讨论】:

        【解决方案8】:

        您也可以采用这种更简单的方法。

        第 1 步:初始化所有变量

        W1 = tf.Variable(tf.truncated_normal([6, 6, 1, K], stddev=0.1), name="W1")
        B1 = tf.Variable(tf.constant(0.1, tf.float32, [K]), name="B1")
        
        Similarly, W2, B2, W3, .....
        

        第2步:将会话保存在模型Saver中并保存

        model_saver = tf.train.Saver()
        
        # Train the model and save it in the end
        model_saver.save(session, "saved_models/CNN_New.ckpt")
        

        第三步:恢复模型

        with tf.Session(graph=graph_cnn) as session:
            model_saver.restore(session, "saved_models/CNN_New.ckpt")
            print("Model restored.") 
            print('Initialized')
        

        第 4 步:检查变量

        W1 = session.run(W1)
        print(W1)
        

        在不同的python实例中运行时,使用

        with tf.Session() as sess:
            # Restore latest checkpoint
            saver.restore(sess, tf.train.latest_checkpoint('saved_model/.'))
        
            # Initalize the variables
            sess.run(tf.global_variables_initializer())
        
            # Get default graph (supply your custom graph if you have one)
            graph = tf.get_default_graph()
        
            # It will give tensor object
            W1 = graph.get_tensor_by_name('W1:0')
        
            # To get the value (numpy array)
            W1_value = session.run(W1)
        

        【讨论】:

        • 嗨,假设 3000 次迭代后如何保存模型,类似于 Caffe。我发现 tensorflow 只保存最后一个模型,尽管我将迭代次数与模型连接起来以在所有迭代中区分它。我的意思是model_3000.ckpt,model_6000.ckpt,---model_100000.ckpt。您能否解释一下为什么它不保存所有内容,而只保存最后 3 次迭代。
        • 有没有办法让所有的变量/操作名称保存在图中?
        【解决方案9】:

        在大多数情况下,使用tf.train.Saver 从磁盘保存和恢复是您的最佳选择:

        ... # build your model
        saver = tf.train.Saver()
        
        with tf.Session() as sess:
            ... # train the model
            saver.save(sess, "/tmp/my_great_model")
        
        with tf.Session() as sess:
            saver.restore(sess, "/tmp/my_great_model")
            ... # use the model
        

        您还可以保存/恢复图形结构本身(有关详细信息,请参阅MetaGraph documentation)。默认情况下,Saver 将图形结构保存到 .meta 文件中。您可以致电import_meta_graph() 进行恢复。它恢复图形结构并返回一个Saver,您可以使用它来恢复模型的状态:

        saver = tf.train.import_meta_graph("/tmp/my_great_model.meta")
        
        with tf.Session() as sess:
            saver.restore(sess, "/tmp/my_great_model")
            ... # use the model
        

        但是,在某些情况下,您需要更快的速度。例如,如果您实施提前停止,您希望在每次模型在训练期间改进时保存检查点(在验证集上测量),然后如果一段时间没有进展,您希望回滚到最佳模型。如果每次改进时都将模型保存到磁盘,这将大大减慢训练速度。诀窍是将变量状态保存到内存,然后再恢复它们:

        ... # build your model
        
        # get a handle on the graph nodes we need to save/restore the model
        graph = tf.get_default_graph()
        gvars = graph.get_collection(tf.GraphKeys.GLOBAL_VARIABLES)
        assign_ops = [graph.get_operation_by_name(v.op.name + "/Assign") for v in gvars]
        init_values = [assign_op.inputs[1] for assign_op in assign_ops]
        
        with tf.Session() as sess:
            ... # train the model
        
            # when needed, save the model state to memory
            gvars_state = sess.run(gvars)
        
            # when needed, restore the model state
            feed_dict = {init_value: val
                         for init_value, val in zip(init_values, gvars_state)}
            sess.run(assign_ops, feed_dict=feed_dict)
        

        简单说明:当你创建一个变量X时,TensorFlow会自动创建一个赋值操作X/Assign来设置变量的初始值。我们没有创建占位符和额外的分配操作(这只会使图形变得混乱),而是使用这些现有的分配操作。每个赋值操作的第一个输入是对它应该初始化的变量的引用,第二个输入 (assign_op.inputs[1]) 是初始值。因此,为了设置我们想要的任何值(而不是初始值),我们需要使用feed_dict 并替换初始值。是的,TensorFlow 允许您为任何操作提供值,而不仅仅是占位符,所以这很好用。

        【讨论】:

        【解决方案10】:

        这是我针对两种基本情况的简单解决方案,即您是要从文件中加载图表还是在运行时构建图表。

        此答案适用于 Tensorflow 0.12+(包括 1.0)。

        在代码中重建图表

        保存

        graph = ... # build the graph
        saver = tf.train.Saver()  # create the saver after the graph
        with ... as sess:  # your session object
            saver.save(sess, 'my-model')
        

        加载中

        graph = ... # build the graph
        saver = tf.train.Saver()  # create the saver after the graph
        with ... as sess:  # your session object
            saver.restore(sess, tf.train.latest_checkpoint('./'))
            # now you can use the graph, continue training or whatever
        

        同时从文件中加载图表

        使用此技术时,请确保您的所有层/变量都明确设置了唯一名称。 否则,Tensorflow 将使名称本身唯一,因此它们将与文件中存储的名称不同.在以前的技术中这不是问题,因为名称在加载和保存时都以相同的方式“损坏”。

        保存

        graph = ... # build the graph
        
        for op in [ ... ]:  # operators you want to use after restoring the model
            tf.add_to_collection('ops_to_restore', op)
        
        saver = tf.train.Saver()  # create the saver after the graph
        with ... as sess:  # your session object
            saver.save(sess, 'my-model')
        

        加载中

        with ... as sess:  # your session object
            saver = tf.train.import_meta_graph('my-model.meta')
            saver.restore(sess, tf.train.latest_checkpoint('./'))
            ops = tf.get_collection('ops_to_restore')  # here are your operators in the same order in which you saved them to the collection
        

        【讨论】:

        • -1 通过忽略“此处的所有其他答案”来开始您的答案有点苛刻。也就是说,我出于其他原因投反对票:您绝对应该保存所有全局变量,而不仅仅是可训练的变量。例如,global_step 变量和批量标准化的移动平均值是不可训练的变量,但两者都绝对值得保存。此外,您应该更清楚地区分图表的构建和运行会话,例如Saver(...).save() 将在您每次运行时创建新节点。可能不是你想要的。还有更多...:/
        • @MiniQuark 好的,感谢您的反馈,我会根据您的建议编辑答案;)
        【解决方案11】:

        我正在改进我的答案,以添加更多用于保存和恢复模型的详细信息。

        在(及之后)Tensorflow 0.11 版

        保存模型:

        import tensorflow as tf
        
        #Prepare to feed input, i.e. feed_dict and placeholders
        w1 = tf.placeholder("float", name="w1")
        w2 = tf.placeholder("float", name="w2")
        b1= tf.Variable(2.0,name="bias")
        feed_dict ={w1:4,w2:8}
        
        #Define a test operation that we will restore
        w3 = tf.add(w1,w2)
        w4 = tf.multiply(w3,b1,name="op_to_restore")
        sess = tf.Session()
        sess.run(tf.global_variables_initializer())
        
        #Create a saver object which will save all the variables
        saver = tf.train.Saver()
        
        #Run the operation by feeding input
        print sess.run(w4,feed_dict)
        #Prints 24 which is sum of (w1+w2)*b1 
        
        #Now, save the graph
        saver.save(sess, 'my_test_model',global_step=1000)
        

        恢复模型:

        import tensorflow as tf
        
        sess=tf.Session()    
        #First let's load meta graph and restore weights
        saver = tf.train.import_meta_graph('my_test_model-1000.meta')
        saver.restore(sess,tf.train.latest_checkpoint('./'))
        
        
        # Access saved Variables directly
        print(sess.run('bias:0'))
        # This will print 2, which is the value of bias that we saved
        
        
        # Now, let's access and create placeholders variables and
        # create feed-dict to feed new data
        
        graph = tf.get_default_graph()
        w1 = graph.get_tensor_by_name("w1:0")
        w2 = graph.get_tensor_by_name("w2:0")
        feed_dict ={w1:13.0,w2:17.0}
        
        #Now, access the op that you want to run. 
        op_to_restore = graph.get_tensor_by_name("op_to_restore:0")
        
        print sess.run(op_to_restore,feed_dict)
        #This will print 60 which is calculated 
        

        这里已经很好地解释了这个和一些更高级的用例。

        A quick complete tutorial to save and restore Tensorflow models

        【讨论】:

        • +1 for this # Access saved Variables directly print(sess.run('bias:0')) # 这将打印 2,这是我们保存的偏差值。它对调试目的有很大帮助,以查看模型是否正确加载。变量可以通过 "All_varaibles = tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES" 获得。另外,"sess.run(tf.global_variables_initializer())" 必须在恢复之前。
        • 您确定我们必须再次运行 global_variables_initializer 吗?我用 global_variable_initialization 恢复了我的图表,每次在相同的数据上它都会给我不同的输出。所以我把初始化注释掉了,只是恢复了图形、输入变量和操作,现在可以正常工作了。
        • @AdityaShinde 我不明白为什么我每次都得到不同的值。而且我没有包括用于恢复的变量初始化步骤。顺便说一句,我正在使用我自己的代码。
        • @AdityaShinde:您不需要 init op,因为值已由 restore 函数初始化,因此将其删除。但是,我不确定您为什么使用 init op 得到不同的输出。
        • @sankit 恢复张量时,为什么要在名称中添加:0
        【解决方案12】:

        如果您使用tf.train.MonitoredTrainingSession 作为默认会话,则无需添加额外代码来执行保存/恢复操作。只需将检查点目录名称传递给 MonitoredTrainingSession 的构造函数,它将使用会话挂钩来处理这些。

        【讨论】:

        • 使用tf.train.Supervisor 将为您处理创建这样的会话,并提供更完整的解决方案。
        • @Mark tf.train.Supervisor 已弃用
        • 您是否有任何链接支持“Supervisor 已被弃用”的说法?我没有看到任何迹象表明情况如此。
        • 感谢 URL -- 我检查了信息的原始来源,并被告知它可能会在 TF 1.x 系列结束之前出现,但在那之后不能保证。
        【解决方案13】:

        这里的所有答案都很棒,但我想补充两点。

        首先,为了详细说明@user7505159 的答案,“./”对于添加到您要恢复的文件名的开头可能很重要。

        例如,您可以像这样保存文件名中没有“./”的图形:

        # Some graph defined up here with specific names
        
        saver = tf.train.Saver()
        save_file = 'model.ckpt'
        
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
            saver.save(sess, save_file)
        

        但为了恢复图形,您可能需要在文件名前添加“./”:

        # Same graph defined up here
        
        saver = tf.train.Saver()
        save_file = './' + 'model.ckpt' # String addition used for emphasis
        
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
            saver.restore(sess, save_file)
        

        您并不总是需要“./”,但根据您的环境和 TensorFlow 版本,它可能会导致问题。

        还想提一下,sess.run(tf.global_variables_initializer()) 在恢复会话之前可能很重要。

        如果您在尝试恢复已保存的会话时收到有关未初始化变量的错误,请确保在 saver.restore(sess, save_file) 行之前包含 sess.run(tf.global_variables_initializer())。它可以让您免于头疼。

        【讨论】:

          【解决方案14】:

          我的环境:Python 3.6、Tensorflow 1.3.0

          虽然有很多解决方案,但大部分都是基于tf.train.Saver。当我们加载由Saver 保存的.ckpt 时,我们必须重新定义 tensorflow 网络或使用一些奇怪且难以记住的名称,例如'placehold_0:0','dense/Adam/Weight:0'。这里我推荐使用tf.saved_model,下面给出一个最简单的例子,你可以向Serving a TensorFlow Model了解更多:

          保存模型:

          import tensorflow as tf
          
          # define the tensorflow network and do some trains
          x = tf.placeholder("float", name="x")
          w = tf.Variable(2.0, name="w")
          b = tf.Variable(0.0, name="bias")
          
          h = tf.multiply(x, w)
          y = tf.add(h, b, name="y")
          sess = tf.Session()
          sess.run(tf.global_variables_initializer())
          
          # save the model
          export_path =  './savedmodel'
          builder = tf.saved_model.builder.SavedModelBuilder(export_path)
          
          tensor_info_x = tf.saved_model.utils.build_tensor_info(x)
          tensor_info_y = tf.saved_model.utils.build_tensor_info(y)
          
          prediction_signature = (
            tf.saved_model.signature_def_utils.build_signature_def(
                inputs={'x_input': tensor_info_x},
                outputs={'y_output': tensor_info_y},
                method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME))
          
          builder.add_meta_graph_and_variables(
            sess, [tf.saved_model.tag_constants.SERVING],
            signature_def_map={
                tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
                    prediction_signature 
            },
            )
          builder.save()
          

          加载模型:

          import tensorflow as tf
          sess=tf.Session() 
          signature_key = tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY
          input_key = 'x_input'
          output_key = 'y_output'
          
          export_path =  './savedmodel'
          meta_graph_def = tf.saved_model.loader.load(
                     sess,
                    [tf.saved_model.tag_constants.SERVING],
                    export_path)
          signature = meta_graph_def.signature_def
          
          x_tensor_name = signature[signature_key].inputs[input_key].name
          y_tensor_name = signature[signature_key].outputs[output_key].name
          
          x = sess.graph.get_tensor_by_name(x_tensor_name)
          y = sess.graph.get_tensor_by_name(y_tensor_name)
          
          y_out = sess.run(y, {x: 3.0})
          

          【讨论】:

          • +1 是 SavedModel API 的一个很好的例子。但是,我希望您的 保存模型 部分显示像 Ryan Sepassi 的回答一样的训练循环!我意识到这是一个老问题,但这个回答是我在 Google 上找到的为数不多(而且很有价值)的 SavedModel 示例之一。
          • @Tom 这是一个很好的答案——只有一个针对新的 SavedModel。你能看看这个 SavedModel 问题吗? stackoverflow.com/questions/48540744/…
          • 现在让它与 TF Eager 模型一起正常工作。谷歌在 2018 年的演讲中建议大家远离 TF 图代码。
          【解决方案15】:

          Tensorflow 2 文档

          保存检查点

          改编自the docs

          # -------------------------
          # -----  Toy Context  -----
          # -------------------------
          import tensorflow as tf
          
          
          class Net(tf.keras.Model):
              """A simple linear model."""
          
              def __init__(self):
                  super(Net, self).__init__()
                  self.l1 = tf.keras.layers.Dense(5)
          
              def call(self, x):
                  return self.l1(x)
          
          
          def toy_dataset():
              inputs = tf.range(10.0)[:, None]
              labels = inputs * 5.0 + tf.range(5.0)[None, :]
              return (
                  tf.data.Dataset.from_tensor_slices(dict(x=inputs, y=labels)).repeat().batch(2)
              )
          
          
          def train_step(net, example, optimizer):
              """Trains `net` on `example` using `optimizer`."""
              with tf.GradientTape() as tape:
                  output = net(example["x"])
                  loss = tf.reduce_mean(tf.abs(output - example["y"]))
              variables = net.trainable_variables
              gradients = tape.gradient(loss, variables)
              optimizer.apply_gradients(zip(gradients, variables))
              return loss
          
          
          # ----------------------------
          # -----  Create Objects  -----
          # ----------------------------
          
          net = Net()
          opt = tf.keras.optimizers.Adam(0.1)
          dataset = toy_dataset()
          iterator = iter(dataset)
          ckpt = tf.train.Checkpoint(
              step=tf.Variable(1), optimizer=opt, net=net, iterator=iterator
          )
          manager = tf.train.CheckpointManager(ckpt, "./tf_ckpts", max_to_keep=3)
          
          # ----------------------------
          # -----  Train and Save  -----
          # ----------------------------
          
          ckpt.restore(manager.latest_checkpoint)
          if manager.latest_checkpoint:
              print("Restored from {}".format(manager.latest_checkpoint))
          else:
              print("Initializing from scratch.")
          
          for _ in range(50):
              example = next(iterator)
              loss = train_step(net, example, opt)
              ckpt.step.assign_add(1)
              if int(ckpt.step) % 10 == 0:
                  save_path = manager.save()
                  print("Saved checkpoint for step {}: {}".format(int(ckpt.step), save_path))
                  print("loss {:1.2f}".format(loss.numpy()))
          
          
          # ---------------------
          # -----  Restore  -----
          # ---------------------
          
          # In another script, re-initialize objects
          opt = tf.keras.optimizers.Adam(0.1)
          net = Net()
          dataset = toy_dataset()
          iterator = iter(dataset)
          ckpt = tf.train.Checkpoint(
              step=tf.Variable(1), optimizer=opt, net=net, iterator=iterator
          )
          manager = tf.train.CheckpointManager(ckpt, "./tf_ckpts", max_to_keep=3)
          
          # Re-use the manager code above ^
          
          ckpt.restore(manager.latest_checkpoint)
          if manager.latest_checkpoint:
              print("Restored from {}".format(manager.latest_checkpoint))
          else:
              print("Initializing from scratch.")
          
          for _ in range(50):
              example = next(iterator)
              # Continue training or evaluate etc.
          
          

          更多链接

          检查点捕获模型使用的所有参数(tf.Variable 对象)的确切值。 检查点不包含模型定义的计算的任何描述,因此通常仅在使用保存的参数值的源代码可用时才有用。

          另一方面,SavedModel 格式除了参数值(检查点)之外,还包括模型定义的计算的序列化描述。这种格式的模型与创建模型的源代码独立。因此,它们适合通过 TensorFlow Serving、TensorFlow Lite、TensorFlow.js 或其他编程语言(C、C++、Java、Go、Rust、C# 等 TensorFlow API)的程序进行部署。

          (重点是我自己的)


          张量流

          来自文档:

          保存

          # Create some variables.
          v1 = tf.get_variable("v1", shape=[3], initializer = tf.zeros_initializer)
          v2 = tf.get_variable("v2", shape=[5], initializer = tf.zeros_initializer)
          
          inc_v1 = v1.assign(v1+1)
          dec_v2 = v2.assign(v2-1)
          
          # Add an op to initialize the variables.
          init_op = tf.global_variables_initializer()
          
          # Add ops to save and restore all the variables.
          saver = tf.train.Saver()
          
          # Later, launch the model, initialize the variables, do some work, and save the
          # variables to disk.
          with tf.Session() as sess:
            sess.run(init_op)
            # Do some work with the model.
            inc_v1.op.run()
            dec_v2.op.run()
            # Save the variables to disk.
            save_path = saver.save(sess, "/tmp/model.ckpt")
            print("Model saved in path: %s" % save_path)
          

          恢复

          tf.reset_default_graph()
          
          # Create some variables.
          v1 = tf.get_variable("v1", shape=[3])
          v2 = tf.get_variable("v2", shape=[5])
          
          # Add ops to save and restore all the variables.
          saver = tf.train.Saver()
          
          # Later, launch the model, use the saver to restore variables from disk, and
          # do some work with the model.
          with tf.Session() as sess:
            # Restore variables from disk.
            saver.restore(sess, "/tmp/model.ckpt")
            print("Model restored.")
            # Check the values of the variables
            print("v1 : %s" % v1.eval())
            print("v2 : %s" % v2.eval())
          

          simple_save

          很多好的答案,为了完整起见,我会加我的 2 美分:simple_save。也是一个使用tf.data.Dataset API 的独立代码示例。

          Python 3 ; TensorFlow 1.14

          import tensorflow as tf
          from tensorflow.saved_model import tag_constants
          
          with tf.Graph().as_default():
              with tf.Session() as sess:
                  ...
          
                  # Saving
                  inputs = {
                      "batch_size_placeholder": batch_size_placeholder,
                      "features_placeholder": features_placeholder,
                      "labels_placeholder": labels_placeholder,
                  }
                  outputs = {"prediction": model_output}
                  tf.saved_model.simple_save(
                      sess, 'path/to/your/location/', inputs, outputs
                  )
          

          恢复:

          graph = tf.Graph()
          with restored_graph.as_default():
              with tf.Session() as sess:
                  tf.saved_model.loader.load(
                      sess,
                      [tag_constants.SERVING],
                      'path/to/your/location/',
                  )
                  batch_size_placeholder = graph.get_tensor_by_name('batch_size_placeholder:0')
                  features_placeholder = graph.get_tensor_by_name('features_placeholder:0')
                  labels_placeholder = graph.get_tensor_by_name('labels_placeholder:0')
                  prediction = restored_graph.get_tensor_by_name('dense/BiasAdd:0')
          
                  sess.run(prediction, feed_dict={
                      batch_size_placeholder: some_value,
                      features_placeholder: some_other_value,
                      labels_placeholder: another_value
                  })
          

          独立示例

          Original blog post

          为了演示,以下代码生成随机数据。

          1. 我们首先创建占位符。他们将在运行时保存数据。从它们中,我们创建Dataset,然后创建它的Iterator。我们得到迭代器生成的张量,称为input_tensor,它将作为我们模型的输入。
          2. 模型本身是从input_tensor 构建的:一个基于 GRU 的双向 RNN,后跟一个密集分类器。因为为什么不呢。
          3. 损失是softmax_cross_entropy_with_logits,用Adam优化。在 2 个 epoch(每个 2 个批次)之后,我们使用 tf.saved_model.simple_save 保存“训练过的”模型。如果您按原样运行代码,则模型将保存在您当前工作目录中名为 simple/ 的文件夹中。
          4. 在新图表中,我们使用tf.saved_model.loader.load 恢复保存的模型。我们使用graph.get_tensor_by_name 获取占位符和logits,使用graph.get_operation_by_name 获取Iterator 初始化操作。
          5. 最后,我们对数据集中的两个批次运行推理,并检查保存和恢复的模型是否都产生相同的值。他们会的!

          代码:

          import os
          import shutil
          import numpy as np
          import tensorflow as tf
          from tensorflow.python.saved_model import tag_constants
          
          
          def model(graph, input_tensor):
              """Create the model which consists of
              a bidirectional rnn (GRU(10)) followed by a dense classifier
          
              Args:
                  graph (tf.Graph): Tensors' graph
                  input_tensor (tf.Tensor): Tensor fed as input to the model
          
              Returns:
                  tf.Tensor: the model's output layer Tensor
              """
              cell = tf.nn.rnn_cell.GRUCell(10)
              with graph.as_default():
                  ((fw_outputs, bw_outputs), (fw_state, bw_state)) = tf.nn.bidirectional_dynamic_rnn(
                      cell_fw=cell,
                      cell_bw=cell,
                      inputs=input_tensor,
                      sequence_length=[10] * 32,
                      dtype=tf.float32,
                      swap_memory=True,
                      scope=None)
                  outputs = tf.concat((fw_outputs, bw_outputs), 2)
                  mean = tf.reduce_mean(outputs, axis=1)
                  dense = tf.layers.dense(mean, 5, activation=None)
          
                  return dense
          
          
          def get_opt_op(graph, logits, labels_tensor):
              """Create optimization operation from model's logits and labels
          
              Args:
                  graph (tf.Graph): Tensors' graph
                  logits (tf.Tensor): The model's output without activation
                  labels_tensor (tf.Tensor): Target labels
          
              Returns:
                  tf.Operation: the operation performing a stem of Adam optimizer
              """
              with graph.as_default():
                  with tf.variable_scope('loss'):
                      loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
                              logits=logits, labels=labels_tensor, name='xent'),
                              name="mean-xent"
                              )
                  with tf.variable_scope('optimizer'):
                      opt_op = tf.train.AdamOptimizer(1e-2).minimize(loss)
                  return opt_op
          
          
          if __name__ == '__main__':
              # Set random seed for reproducibility
              # and create synthetic data
              np.random.seed(0)
              features = np.random.randn(64, 10, 30)
              labels = np.eye(5)[np.random.randint(0, 5, (64,))]
          
              graph1 = tf.Graph()
              with graph1.as_default():
                  # Random seed for reproducibility
                  tf.set_random_seed(0)
                  # Placeholders
                  batch_size_ph = tf.placeholder(tf.int64, name='batch_size_ph')
                  features_data_ph = tf.placeholder(tf.float32, [None, None, 30], 'features_data_ph')
                  labels_data_ph = tf.placeholder(tf.int32, [None, 5], 'labels_data_ph')
                  # Dataset
                  dataset = tf.data.Dataset.from_tensor_slices((features_data_ph, labels_data_ph))
                  dataset = dataset.batch(batch_size_ph)
                  iterator = tf.data.Iterator.from_structure(dataset.output_types, dataset.output_shapes)
                  dataset_init_op = iterator.make_initializer(dataset, name='dataset_init')
                  input_tensor, labels_tensor = iterator.get_next()
          
                  # Model
                  logits = model(graph1, input_tensor)
                  # Optimization
                  opt_op = get_opt_op(graph1, logits, labels_tensor)
          
                  with tf.Session(graph=graph1) as sess:
                      # Initialize variables
                      tf.global_variables_initializer().run(session=sess)
                      for epoch in range(3):
                          batch = 0
                          # Initialize dataset (could feed epochs in Dataset.repeat(epochs))
                          sess.run(
                              dataset_init_op,
                              feed_dict={
                                  features_data_ph: features,
                                  labels_data_ph: labels,
                                  batch_size_ph: 32
                              })
                          values = []
                          while True:
                              try:
                                  if epoch < 2:
                                      # Training
                                      _, value = sess.run([opt_op, logits])
                                      print('Epoch {}, batch {} | Sample value: {}'.format(epoch, batch, value[0]))
                                      batch += 1
                                  else:
                                      # Final inference
                                      values.append(sess.run(logits))
                                      print('Epoch {}, batch {} | Final inference | Sample value: {}'.format(epoch, batch, values[-1][0]))
                                      batch += 1
                              except tf.errors.OutOfRangeError:
                                  break
                      # Save model state
                      print('\nSaving...')
                      cwd = os.getcwd()
                      path = os.path.join(cwd, 'simple')
                      shutil.rmtree(path, ignore_errors=True)
                      inputs_dict = {
                          "batch_size_ph": batch_size_ph,
                          "features_data_ph": features_data_ph,
                          "labels_data_ph": labels_data_ph
                      }
                      outputs_dict = {
                          "logits": logits
                      }
                      tf.saved_model.simple_save(
                          sess, path, inputs_dict, outputs_dict
                      )
                      print('Ok')
              # Restoring
              graph2 = tf.Graph()
              with graph2.as_default():
                  with tf.Session(graph=graph2) as sess:
                      # Restore saved values
                      print('\nRestoring...')
                      tf.saved_model.loader.load(
                          sess,
                          [tag_constants.SERVING],
                          path
                      )
                      print('Ok')
                      # Get restored placeholders
                      labels_data_ph = graph2.get_tensor_by_name('labels_data_ph:0')
                      features_data_ph = graph2.get_tensor_by_name('features_data_ph:0')
                      batch_size_ph = graph2.get_tensor_by_name('batch_size_ph:0')
                      # Get restored model output
                      restored_logits = graph2.get_tensor_by_name('dense/BiasAdd:0')
                      # Get dataset initializing operation
                      dataset_init_op = graph2.get_operation_by_name('dataset_init')
          
                      # Initialize restored dataset
                      sess.run(
                          dataset_init_op,
                          feed_dict={
                              features_data_ph: features,
                              labels_data_ph: labels,
                              batch_size_ph: 32
                          }
          
                      )
                      # Compute inference for both batches in dataset
                      restored_values = []
                      for i in range(2):
                          restored_values.append(sess.run(restored_logits))
                          print('Restored values: ', restored_values[i][0])
          
              # Check if original inference and restored inference are equal
              valid = all((v == rv).all() for v, rv in zip(values, restored_values))
              print('\nInferences match: ', valid)
          

          这将打印:

          $ python3 save_and_restore.py
          
          Epoch 0, batch 0 | Sample value: [-0.13851789 -0.3087595   0.12804556  0.20013677 -0.08229901]
          Epoch 0, batch 1 | Sample value: [-0.00555491 -0.04339041 -0.05111827 -0.2480045  -0.00107776]
          Epoch 1, batch 0 | Sample value: [-0.19321944 -0.2104792  -0.00602257  0.07465433  0.11674127]
          Epoch 1, batch 1 | Sample value: [-0.05275984  0.05981954 -0.15913513 -0.3244143   0.10673307]
          Epoch 2, batch 0 | Final inference | Sample value: [-0.26331693 -0.13013336 -0.12553    -0.04276478  0.2933622 ]
          Epoch 2, batch 1 | Final inference | Sample value: [-0.07730117  0.11119192 -0.20817074 -0.35660955  0.16990358]
          
          Saving...
          INFO:tensorflow:Assets added to graph.
          INFO:tensorflow:No assets to write.
          INFO:tensorflow:SavedModel written to: b'/some/path/simple/saved_model.pb'
          Ok
          
          Restoring...
          INFO:tensorflow:Restoring parameters from b'/some/path/simple/variables/variables'
          Ok
          Restored values:  [-0.26331693 -0.13013336 -0.12553    -0.04276478  0.2933622 ]
          Restored values:  [-0.07730117  0.11119192 -0.20817074 -0.35660955  0.16990358]
          
          Inferences match:  True
          

          【讨论】:

          • 我是初学者,我需要更多解释......:如果我有一个 CNN 模型,我应该只存储 1.inputs_placeholder 2.labels_placeholder 和 3.output_of_cnn 吗?还是所有中间的tf.contrib.layers
          • 图形完全恢复。你可以检查它运行[n.name for n in graph2.as_graph_def().node]。正如文档所说,简单保存旨在简化与 tensorflow 服务的交互,这就是争论的重点;然而,其他变量仍然被恢复,否则推理不会发生。就像我在示例中所做的那样,抓住你感兴趣的变量。查看documentation
          • 我猜不错,但它是否也适用于 Eager 模式模型和 tfe.Saver?
          • 没有global_step作为参数,如果你停下来再尝试重新开始训练,它会认为你是第一步。它至少会搞砸你的张量板可视化
          • 我正在尝试调用 restore 并收到此错误 ValueError: No variables to save。有人可以帮忙吗?
          【解决方案16】:

          使用tf.train.Saver 保存模型。请记住,如果要减小模型大小,则需要指定 var_listval_list 可以是:

          • tf.trainable_variables
          • tf.global_variables

          【讨论】:

            【解决方案17】:

            根据新的 Tensorflow 版本,tf.train.Checkpoint 是保存和恢复模型的首选方式:

            Checkpoint.saveCheckpoint.restore 基于对象的读写 检查点,与写入和读取的 tf.train.Saver 相比 基于变量名的检查点。基于对象的检查点节省了 Python 对象之间的依赖关系图(层、优化器、 变量等)具有命名的边,并且该图用于匹配 恢复检查点时的变量。它可以更强大 Python 程序中的更改,并有助于支持 restore-on-create 急切执行时的变量。 更喜欢tf.train.Checkpoint tf.train.Saver 获取新代码

            这是一个例子:

            import tensorflow as tf
            import os
            
            tf.enable_eager_execution()
            
            checkpoint_directory = "/tmp/training_checkpoints"
            checkpoint_prefix = os.path.join(checkpoint_directory, "ckpt")
            
            checkpoint = tf.train.Checkpoint(optimizer=optimizer, model=model)
            status = checkpoint.restore(tf.train.latest_checkpoint(checkpoint_directory))
            for _ in range(num_training_steps):
              optimizer.minimize( ... )  # Variables will be restored on creation.
            status.assert_consumed()  # Optional sanity checks.
            checkpoint.save(file_prefix=checkpoint_prefix)
            

            More information and example here.

            【讨论】:

              【解决方案18】:

              无论您想将模型保存在何处,

              self.saver = tf.train.Saver()
              with tf.Session() as sess:
                          sess.run(tf.global_variables_initializer())
                          ...
                          self.saver.save(sess, filename)
              

              确保您的所有tf.Variable 都有名称,因为您可能希望稍后使用它们的名称来恢复它们。 以及您想要预测的位置,

              saver = tf.train.import_meta_graph(filename)
              name = 'name given when you saved the file' 
              with tf.Session() as sess:
                    saver.restore(sess, name)
                    print(sess.run('W1:0')) #example to retrieve by variable name
              

              确保保护程序在相应的会话中运行。 请记住,如果您使用tf.train.latest_checkpoint('./'),则只会使用最新的检查点。

              【讨论】:

                【解决方案19】:

                您可以将变量保存在网络中使用

                saver = tf.train.Saver() 
                saver.save(sess, 'path of save/fileName.ckpt')
                

                恢复网络以供以后或在其他脚本中重复使用,请使用:

                saver = tf.train.Saver()
                saver.restore(sess, tf.train.latest_checkpoint('path of save/')
                sess.run(....) 
                

                要点:

                1. sess 在第一次和以后的运行之间必须相同(连贯结构)。
                2. saver.restore 需要保存文件的文件夹路径,而不是单个文件路径。

                【讨论】:

                  【解决方案20】:

                  对于tensorflow 2.0,为as simple as

                  # Save the model
                  model.save('path_to_my_model.h5')
                  

                  恢复:

                  new_model = tensorflow.keras.models.load_model('path_to_my_model.h5')
                  

                  【讨论】:

                  【解决方案21】:

                  我正在使用版本:

                  tensorflow (1.13.1)
                  tensorflow-gpu (1.13.1)
                  

                  简单的方法是

                  保存:

                  model.save("model.h5")
                  

                  恢复:

                  model = tf.keras.models.load_model("model.h5")
                  

                  【讨论】:

                    【解决方案22】:

                    在新版本的 tensorflow 2.0 中,保存/加载模型的过程要容易得多。因为 Keras API 的实现,TensorFlow 的高级 API。

                    要保存模型: 检查文档以供参考: https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/keras/models/save_model

                    tf.keras.models.save_model(model_name, filepath, save_format)
                    

                    加载模型:

                    https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/keras/models/load_model

                    model = tf.keras.models.load_model(filepath)
                    

                    【讨论】:

                      【解决方案23】:

                      tf.keras 使用TF2.0 保存模型

                      我看到了使用 TF1.x 保存模型的绝佳答案。我想提供更多关于保存tensorflow.keras 模型的提示,这有点复杂,因为有很多方法可以保存模型。

                      这里我提供了一个将tensorflow.keras 模型保存到当前目录下的model_path 文件夹的示例。这适用于最新的 tensorflow (TF2.0)。如果近期有任何变化,我会更新此描述。

                      保存和加载整个模型

                      import tensorflow as tf
                      from tensorflow import keras
                      mnist = tf.keras.datasets.mnist
                      
                      #import data
                      (x_train, y_train),(x_test, y_test) = mnist.load_data()
                      x_train, x_test = x_train / 255.0, x_test / 255.0
                      
                      # create a model
                      def create_model():
                        model = tf.keras.models.Sequential([
                          tf.keras.layers.Flatten(input_shape=(28, 28)),
                          tf.keras.layers.Dense(512, activation=tf.nn.relu),
                          tf.keras.layers.Dropout(0.2),
                          tf.keras.layers.Dense(10, activation=tf.nn.softmax)
                          ])
                      # compile the model
                        model.compile(optimizer='adam',
                                    loss='sparse_categorical_crossentropy',
                                    metrics=['accuracy'])
                        return model
                      
                      # Create a basic model instance
                      model=create_model()
                      
                      model.fit(x_train, y_train, epochs=1)
                      loss, acc = model.evaluate(x_test, y_test,verbose=1)
                      print("Original model, accuracy: {:5.2f}%".format(100*acc))
                      
                      # Save entire model to a HDF5 file
                      model.save('./model_path/my_model.h5')
                      
                      # Recreate the exact same model, including weights and optimizer.
                      new_model = keras.models.load_model('./model_path/my_model.h5')
                      loss, acc = new_model.evaluate(x_test, y_test)
                      print("Restored model, accuracy: {:5.2f}%".format(100*acc))
                      

                      仅保存和加载模型权重

                      如果您只想保存模型权重然后加载权重以恢复模型,那么

                      model.fit(x_train, y_train, epochs=5)
                      loss, acc = model.evaluate(x_test, y_test,verbose=1)
                      print("Original model, accuracy: {:5.2f}%".format(100*acc))
                      
                      # Save the weights
                      model.save_weights('./checkpoints/my_checkpoint')
                      
                      # Restore the weights
                      model = create_model()
                      model.load_weights('./checkpoints/my_checkpoint')
                      
                      loss,acc = model.evaluate(x_test, y_test)
                      print("Restored model, accuracy: {:5.2f}%".format(100*acc))
                      

                      使用 keras 检查点回调保存和恢复

                      # include the epoch in the file name. (uses `str.format`)
                      checkpoint_path = "training_2/cp-{epoch:04d}.ckpt"
                      checkpoint_dir = os.path.dirname(checkpoint_path)
                      
                      cp_callback = tf.keras.callbacks.ModelCheckpoint(
                          checkpoint_path, verbose=1, save_weights_only=True,
                          # Save weights, every 5-epochs.
                          period=5)
                      
                      model = create_model()
                      model.save_weights(checkpoint_path.format(epoch=0))
                      model.fit(train_images, train_labels,
                                epochs = 50, callbacks = [cp_callback],
                                validation_data = (test_images,test_labels),
                                verbose=0)
                      
                      latest = tf.train.latest_checkpoint(checkpoint_dir)
                      
                      new_model = create_model()
                      new_model.load_weights(latest)
                      loss, acc = new_model.evaluate(test_images, test_labels)
                      print("Restored model, accuracy: {:5.2f}%".format(100*acc))
                      

                      使用自定义指标保存模型

                      import tensorflow as tf
                      from tensorflow import keras
                      mnist = tf.keras.datasets.mnist
                      
                      (x_train, y_train),(x_test, y_test) = mnist.load_data()
                      x_train, x_test = x_train / 255.0, x_test / 255.0
                      
                      # Custom Loss1 (for example) 
                      @tf.function() 
                      def customLoss1(yTrue,yPred):
                        return tf.reduce_mean(yTrue-yPred) 
                      
                      # Custom Loss2 (for example) 
                      @tf.function() 
                      def customLoss2(yTrue, yPred):
                        return tf.reduce_mean(tf.square(tf.subtract(yTrue,yPred))) 
                      
                      def create_model():
                        model = tf.keras.models.Sequential([
                          tf.keras.layers.Flatten(input_shape=(28, 28)),
                          tf.keras.layers.Dense(512, activation=tf.nn.relu),  
                          tf.keras.layers.Dropout(0.2),
                          tf.keras.layers.Dense(10, activation=tf.nn.softmax)
                          ])
                        model.compile(optimizer='adam',
                                    loss='sparse_categorical_crossentropy',
                                    metrics=['accuracy', customLoss1, customLoss2])
                        return model
                      
                      # Create a basic model instance
                      model=create_model()
                      
                      # Fit and evaluate model 
                      model.fit(x_train, y_train, epochs=1)
                      loss, acc,loss1, loss2 = model.evaluate(x_test, y_test,verbose=1)
                      print("Original model, accuracy: {:5.2f}%".format(100*acc))
                      
                      model.save("./model.h5")
                      
                      new_model=tf.keras.models.load_model("./model.h5",custom_objects={'customLoss1':customLoss1,'customLoss2':customLoss2})
                      

                      使用自定义操作保存 keras 模型

                      当我们在以下情况下(tf.tile)有自定义操作时,我们需要创建一个函数并使用 Lambda 层进行包装。否则无法保存模型。

                      import numpy as np
                      import tensorflow as tf
                      from tensorflow.keras.layers import Input, Lambda
                      from tensorflow.keras import Model
                      
                      def my_fun(a):
                        out = tf.tile(a, (1, tf.shape(a)[0]))
                        return out
                      
                      a = Input(shape=(10,))
                      #out = tf.tile(a, (1, tf.shape(a)[0]))
                      out = Lambda(lambda x : my_fun(x))(a)
                      model = Model(a, out)
                      
                      x = np.zeros((50,10), dtype=np.float32)
                      print(model(x).numpy())
                      
                      model.save('my_model.h5')
                      
                      #load the model
                      new_model=tf.keras.models.load_model("my_model.h5")
                      

                      我想我已经介绍了许多保存 tf.keras 模型的方法中的一些。但是,还有许多其他方法。如果您发现上面没有涵盖您的用例,请在下面发表评论。谢谢!

                      【讨论】:

                        【解决方案24】:

                        根据@Vishnuvardhan Janapati 的回答,这是另一种在 TensorFlow 2.0.0

                        下使用 custom layer/metric/loss 保存和重新加载模型的方法
                        import tensorflow as tf
                        from tensorflow.keras.layers import Layer
                        from tensorflow.keras.utils.generic_utils import get_custom_objects
                        
                        # custom loss (for example)  
                        def custom_loss(y_true,y_pred):
                          return tf.reduce_mean(y_true - y_pred)
                        get_custom_objects().update({'custom_loss': custom_loss}) 
                        
                        # custom loss (for example) 
                        class CustomLayer(Layer):
                          def __init__(self, ...):
                              ...
                          # define custom layer and all necessary custom operations inside custom layer
                        
                        get_custom_objects().update({'CustomLayer': CustomLayer})  
                        

                        这样,一旦你执行了这样的代码,并用tf.keras.models.save_modelmodel.saveModelCheckpoint回调保存了你的模型,你就可以重新加载你的模型而无需精确的自定义对象,就像

                        new_model = tf.keras.models.load_model("./model.h5"})
                        

                        【讨论】:

                          【解决方案25】:

                          对于 tensorflow-2.0

                          这很简单。

                          import tensorflow as tf
                          

                          保存

                          model.save("model_name")
                          

                          恢复

                          model = tf.keras.models.load_model('model_name')
                          

                          【讨论】:

                          • 谢谢!这是对我有用的答案。
                          【解决方案26】:

                          这是一个使用 Tensorflow 2.0 SavedModel 格式的简单示例(这是推荐的格式,according to the docs 用于简单的 MNIST 数据集分类器,使用 Keras 函数式 API,无需太花哨了:

                          # Imports
                          import tensorflow as tf
                          from tensorflow.keras.layers import Input, Dense, Flatten
                          from tensorflow.keras.models import Model
                          import matplotlib.pyplot as plt
                          
                          # Load data
                          mnist = tf.keras.datasets.mnist # 28 x 28
                          (x_train,y_train), (x_test, y_test) = mnist.load_data()
                          
                          # Normalize pixels [0,255] -> [0,1]
                          x_train = tf.keras.utils.normalize(x_train,axis=1)
                          x_test = tf.keras.utils.normalize(x_test,axis=1)
                          
                          # Create model
                          input = Input(shape=(28,28), dtype='float64', name='graph_input')
                          x = Flatten()(input)
                          x = Dense(128, activation='relu')(x)
                          x = Dense(128, activation='relu')(x)
                          output = Dense(10, activation='softmax', name='graph_output', dtype='float64')(x)
                          model = Model(inputs=input, outputs=output)
                          
                          model.compile(optimizer='adam',
                                       loss='sparse_categorical_crossentropy',
                                       metrics=['accuracy'])
                          
                          # Train
                          model.fit(x_train, y_train, epochs=3)
                          
                          # Save model in SavedModel format (Tensorflow 2.0)
                          export_path = 'model'
                          tf.saved_model.save(model, export_path)
                          
                          # ... possibly another python program 
                          
                          # Reload model
                          loaded_model = tf.keras.models.load_model(export_path) 
                          
                          # Get image sample for testing
                          index = 0
                          img = x_test[index] # I normalized the image on a previous step
                          
                          # Predict using the signature definition (Tensorflow 2.0)
                          predict = loaded_model.signatures["serving_default"]
                          prediction = predict(tf.constant(img))
                          
                          # Show results
                          print(np.argmax(prediction['graph_output']))  # prints the class number
                          plt.imshow(x_test[index], cmap=plt.cm.binary)  # prints the image
                          
                          

                          什么是serving_default

                          这是您选择的signature def of the tag 的名称(在本例中,选择了默认的serve 标记)。此外,here 解释了如何使用saved_model_cli 查找模型的标签和签名。

                          免责声明

                          如果您只是想启动并运行它,这只是一个基本示例,但绝不是一个完整的答案 - 也许我将来可以更新它。我只是想举一个在 TF 2.0 中使用 SavedModel 的简单示例,因为我在任何地方都没有见过,即使如此简单。

                          @Tom 的答案是 SavedModel 示例,但它不适用于 Tensorflow 2.0,因为不幸的是有一些重大更改。

                          @Vishnuvardhan Janapati 的回答是 TF 2.0,但它不适用于 SavedModel 格式。

                          【讨论】:

                            【解决方案27】:

                            Tensorflow 2.6:现在变得更简单了,您可以将模型保存为 2 种格式

                            1. Saved_model(与 tf-serving 兼容)
                            2. H5 或 HDF5

                            两种格式的保存模型:

                             from tensorflow.keras import Model
                             inputs = tf.keras.Input(shape=(224,224,3))
                             y = tf.keras.layers.Conv2D(24, 3, activation='relu', input_shape=input_shape[1:])(inputs)
                             outputs = tf.keras.layers.Dense(5, activation=tf.nn.softmax)(y)
                             model = tf.keras.Model(inputs=inputs, outputs=outputs)
                             model.save("saved_model/my_model") #To Save in Saved_model format
                             model.save("my_model.h5") #To save model in H5 or HDF5 format
                            

                            以两种格式加载模型

                            import tensorflow as tf
                            h5_model = tf.keras.models.load_model("my_model.h5") # loading model in h5 format
                            h5_model.summary()
                            saved_m = tf.keras.models.load_model("saved_model/my_model") #loading model in saved_model format
                            saved_m.summary()
                            

                            【讨论】:

                              【解决方案28】:

                              最简单的方法是使用keras api,在线保存模型,一行加载模型

                              from keras.models import load_model
                              
                              my_model.save('my_model.h5')  # creates a HDF5 file 'my_model.h5'
                              
                              del my_model  # deletes the existing model
                              
                              
                              my_model = load_model('my_model.h5') # returns a compiled model identical to the previous one
                              

                              【讨论】:

                                猜你喜欢
                                • 2018-02-08
                                • 1970-01-01
                                • 2019-11-17
                                • 1970-01-01
                                • 2018-04-25
                                • 2019-08-27
                                • 1970-01-01
                                • 1970-01-01
                                相关资源
                                最近更新 更多