Tensorflow:如何保存/恢复模型?

时间:2015-11-17 14:37:26

标签: python tensorflow machine-learning model

在Tensorflow中训练模型后:

  1. 如何保存经过培训的模型?
  2. 以后如何恢复此保存的模型?

26 个答案:

答案 0 :(得分:243)

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

在(及之后) Tensorflow版本0.11

保存模型:

<div class="grid-container">
  <div>
    <h1>A</h1>
  </div>
  <div>
    <h1>B</h1>
  </div>
  <div class="a">
    <h1>C</h1>
  </div>
</div>

恢复模型:

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)

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

A quick complete tutorial to save and restore Tensorflow models

答案 1 :(得分:177)

在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_)

答案 2 :(得分:125)

对于TensorFlow版本&lt; 0.11.0RC1:

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

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

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})

以下是Variable的{​​{3}},其中包括保存和恢复。以下是Saver的{​​{3}}。

答案 3 :(得分:69)

文档

他们构建了一个详尽而有用的教程 - &gt; https://www.tensorflow.org/guide/saved_model

来自文档:

保存

# 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())

Tensorflow&lt; 2

simple_save

许多好的答案,为了完整性,我将加上我的2美分: simple_save 。也是使用tf.data.Dataset API的独立代码示例。

Python 3; Tensorflow 1.7

import tensorflow as tf
from tensorflow.python.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个时期(每个2批)之后,我们使用tf.saved_model.simple_save保存“训练”模型。如果按原样运行代码,则模型将保存在当前工作目录中名为simple/的文件夹中。
  4. 在新图表中,我们会使用tf.saved_model.loader.load恢复已保存的模型。我们使用graph.get_tensor_by_name抓取占位符和logits,使用Iterator抓取graph.get_operation_by_name初始化操作。
  5. 最后,我们对数据集中的两个批次进行推断,并检查保存和恢复的模型是否产生相同的值。他们做到了!
  6. 代码:

    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
    

答案 4 :(得分:65)

我的环境:Python 3.6,Tensorflow 1.3.0

虽然有很多解决方案,但大多数都基于tf.train.Saver。当我们加载由.ckpt保存的Saver时,我们必须重新定义张量流网络或使用一些奇怪且难以记住的名称,例如'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})

答案 5 :(得分:55)

模型有两个部分,模型定义,由模型目录中的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

答案 6 :(得分:39)

您也可以采用这种方式。

第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")

第3步:恢复模型

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)

答案 7 :(得分:20)

在大多数情况下,使用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以设置变量的初始值。我们只使用这些现有的赋值操作,而不是创建占位符和额外的赋值操作(这会使图形变得混乱)。每个赋值op的第一个输入是对它应该初始化的变量的引用,第二个输入(assign_op.inputs[1])是初始值。因此,为了设置我们想要的任何值(而不是初始值),我们需要使用feed_dict并替换初始值。是的,TensorFlow允许您为任何操作提供值,而不仅仅是占位符,所以这样可以正常工作。

答案 8 :(得分:17)

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

我是为个人使用而实现的,所以我虽然在这里分享代码。

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

(当然,这是一个黑客,并且无法保证在未来的TensorFlow版本中以这种方式保存的模型仍然可读。)

答案 9 :(得分:14)

如果它是内部保存的模型,您只需将所有变量的恢复器指定为

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脚本可以在&#39; ./ tensorflow / python / tools&#39;中找到。 Tensorflow源文件夹。

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

答案 10 :(得分:11)

这是我的两个基本案例的简单解决方案,不同之处在于您是要从文件加载图形还是在运行时构建它。

这个答案适用于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

答案 11 :(得分:10)

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

答案 12 :(得分:9)

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

答案 13 :(得分:8)

这里的所有答案都很棒,但我想添加两件事。

首先,详细说明@ user7505159的答案,&#34; ./"添加到要还原的文件名的开头可能很重要。

例如,您可以保存没有&#34; ./"的图表;在文件名中如下:

# 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)

但是为了恢复图形,您可能需要预先添加&#34; ./"到file_name:

# 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)

您并不总是需要&#34; ./",但它可能会导致问题,具体取决于您的环境和TensorFlow版本。

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

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

答案 14 :(得分:7)

如问题6255中所述:

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

而不是

saver.restore('my_model_final.ckpt')

答案 15 :(得分:5)

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

  

Checkpoint.saveCheckpoint.restore写入和读取基于对象   检查点,与写入和读取的tf.train.Saver相反   基于variable.name的检查点。基于对象的检查点保存   Python对象(层,优化器,   具有命名边的变量等),此图用于匹配   恢复检查点时的变量。它可以更强大   Python程序中的更改,并有助于支持创建时还原   急于执行时的变量。 优先选择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.

答案 16 :(得分:3)

使用tf.train.Saver保存模型,重命名,如果要减小模型大小,则需要指定var_list。 val_list可以是tf.trainable_variables或tf.global_variables。

答案 17 :(得分:3)

您可以使用

将变量保存在网络中
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需要已保存文件的文件夹路径,而不是单个文件路径。

答案 18 :(得分:2)

要保存模型的任何地方,

  perl6 -e 'use Pod::Load; .perl.say for load("pod-load-clean.pod6")'

请确保您所有的self.saver = tf.train.Saver() with tf.Session() as sess: sess.run(tf.global_variables_initializer()) ... self.saver.save(sess, filename) 都有名称,因为您以后可能想使用它们的名称来还原它们。 还有您要预测的地方

tf.Variable

确保saver在相应的会话中运行。 请记住,如果您使用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 ,则将仅使用最新的检查点。

答案 19 :(得分:2)

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模型的方法。但是,还有许多其他方法。如果您发现上面没有涉及用例,请在下面发表评论。谢谢!

答案 20 :(得分:1)

对于 tensorflow 2.0 ,它是as simple as

<nav class="awemenu-nav awemenu-has-logo <?php print $is_transparent_mode ? 'awe-header--transparent' : ''; ?>" data-sticky="<?php echo esc_attr( (bool) mojado_option( 'mojado_header_nav_sticky' ) ); ?>">
            <div class="container">

                <div class="awemenu-container">
                    <div class="awemenu-language-search awe-fr">
                        <?php get_template_part( 'template-parts/header-search' ); ?>
                        <?php get_template_part( 'template-parts/header-language' ); ?>
                    </div>

                    <?php if ( $is_transparent_mode ) : ?>
                        <?php print mojado_site_logo( 'home_logo', true, '<div class="home-logo">', '</div>' ); // WPCS: XSS OK. ?>
                    <?php endif; ?>

                    <?php
                    /**
                     * Navigation Main Menu.
                     */
                    wp_nav_menu( array(
                        'container'      => '',
                        'menu_id'        => 'primary-menu',
                        'menu_class'     => 'main-navigation awemenu',
                        'theme_location' => 'primary',
                        'walker'         => new Mojado_Walker_Menu,
                        'fallback_cb'    => array( 'Mojado_Menu_Support', 'fallback' ),
                    ) );
                    ?>
                </div><!-- .awemenu-container -->

            </div><!-- .container -->
        </nav><!-- .awemenu-nav -->

要还原:

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

答案 21 :(得分:1)

这是使用 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格式的。

答案 22 :(得分:0)

我正在使用版本:

tensorflow (1.13.1)
tensorflow-gpu (1.13.1)

简单的方法是

保存:

model.save("model.h5")

还原:

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

答案 23 :(得分:0)

在新版本的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)

答案 24 :(得分:0)

按照@Vishnuvardhan Janapati的回答,这是使用 TensorFlow 2.0.0 下的自定义层/度量/损耗保存和重新加载模型的另一种方法

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 :(得分:0)

对于tensorflow-2.0

这很简单。

import tensorflow as tf

保存

model.save("model_name")

还原

model = tf.keras.models.load_model('model_name')
相关问题