web-dev-qa-db-fra.com

Tensorflow: comment sauvegarder/restaurer un modèle?

Après avoir entraîné un modèle dans Tensorflow: 

  1. Comment sauvez-vous le modèle formé?
  2. Comment restaurer plus tard ce modèle enregistré?
432
mathetes

Nouveau et plus court chemin: simple_save

Beaucoup de bonne réponse, pour être complet, je vais ajouter mes 2 centimes: simple_save. Également un exemple de code autonome utilisant l'API tf.data.Dataset.

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
        )

Restauration:

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

Exemple autonome

Article de blog original

Le code suivant génère des données aléatoires à des fins de démonstration.

  1. Nous commençons par créer les espaces réservés. Ils détiendront les données au moment de l'exécution. À partir d’eux, nous créons la Dataset puis sa Iterator. Nous obtenons le tenseur généré par l'itérateur, appelé input_tensor, qui servira d'input à notre modèle.
  2. Le modèle lui-même est construit à partir de input_tensor: un RNN bidirectionnel basé sur GRU suivi d'un classificateur dense. Parce que pourquoi pas.
  3. La perte est un softmax_cross_entropy_with_logits, optimisé avec Adam. Après 2 époques (de 2 lots chacune), nous sauvegardons le modèle "formé" avec tf.saved_model.simple_save. Si vous exécutez le code tel quel, le modèle sera alors enregistré dans un dossier appelé simple/ dans votre répertoire de travail actuel.
  4. Dans un nouveau graphique, nous restaurons ensuite le modèle enregistré avec tf.saved_model.loader.load. Nous saisissons les espaces réservés et les logits avec graph.get_tensor_by_name et l'opération d'initialisation Iterator avec graph.get_operation_by_name.
  5. Enfin, nous effectuons une inférence pour les deux lots du jeu de données et vérifions que le modèle enregistré et le modèle restauré donnent les mêmes valeurs. Ils font!

Code:

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 __== '__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)

Cela va imprimer:

$ 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
52
ted

J'améliore ma réponse pour ajouter plus de détails sur la sauvegarde et la restauration des modèles. 

Dans (et après) Tensorflow version 0.11

Sauvegarder le modèle:

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)

Restaurez le modèle: 

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 

Ceci et quelques cas d'utilisation plus avancés ont été très bien expliqués ici.

Un tutoriel complet rapide pour enregistrer et restaurer les modèles Tensorflow

233
sankit

Dans (et après) TensorFlow version 0.11.0RC1, vous pouvez enregistrer et restaurer votre modèle directement en appelant tf.train.export_meta_graph et tf.train.import_meta_graph conformément à https://www.tensorflow.org/programmers_guide/meta_graph .

Sauvegarder le modèle

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

Restaurer le modèle

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_)
174
lei du

Pour la version de TensorFlow <0.11.0RC1:

Les points de contrôle enregistrés contiennent des valeurs pour les Variables de votre modèle, pas le modèle/graphique lui-même, ce qui signifie que le graphique doit être identique lorsque vous restaurez le point de contrôle.

Voici un exemple de régression linéaire dans laquelle une boucle d'apprentissage enregistre les points de contrôle des variables et une section d'évaluation permettant de restaurer les variables enregistrées lors d'une exécution antérieure et de calculer les prédictions. Bien sûr, vous pouvez également restaurer des variables et poursuivre la formation si vous le souhaitez.

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

Voici les docs for Variables, qui couvrent la sauvegarde et la restauration. Et voici les docs pour le Saver.

124
Ryan Sepassi

Mon environnement: Python 3.6, Tensorflow 1.3.0

Bien qu'il y ait eu beaucoup de solutions, la plupart d'entre elles sont basées sur tf.train.Saver. Lorsque nous chargeons un .ckpt enregistré par Saver, nous devons soit redéfinir le réseau tensorflow, soit utiliser un nom étrange et durement mémorisé, par exemple. 'placehold_0:0', 'dense/Adam/Weight:0'. Ici, je recommande d’utiliser tf.saved_model, un exemple le plus simple donné ci-dessous. Vous pouvez en apprendre davantage à partir de Servir un modèle TensorFlow :

Sauvegarder le modèle:

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

Charger le modèle:

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

Le modèle comprend deux parties: la définition du modèle, enregistrée par Supervisor en tant que graph.pbtxt dans le répertoire du modèle, et les valeurs numériques des tenseurs, enregistrées dans des fichiers de point de contrôle tels que model.ckpt-1003418.

La définition de modèle peut être restaurée à l'aide de tf.import_graph_def et les poids sont restaurés à l'aide de Saver.

Cependant, Saver utilise une liste spéciale contenant des variables attachées au modèle Graph, et cette collection n'est pas initialisée à l'aide de import_graph_def. Vous ne pouvez donc pas utiliser les deux ensemble pour le moment (nous devons le réparer pour le moment). Pour l'instant, vous devez utiliser l'approche de Ryan Sepassi - construire manuellement un graphique avec des noms de nœud identiques et utiliser Saver pour y charger les poids.

(Vous pouvez également le pirater en utilisant import_graph_def, en créant des variables manuellement et en utilisant tf.add_to_collection(tf.GraphKeys.VARIABLES, variable) pour chaque variable, puis en utilisant Saver.)

53
Yaroslav Bulatov

Vous pouvez également prendre ce moyen plus facile.

Étape 1: initialisez toutes vos variables

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, .....

Étape 2: enregistrez la session dans le modèle Saver et enregistrez-la.

model_saver = tf.train.Saver()

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

Étape 3: restaurer le modèle

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

Étape 4: vérifiez votre variable

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

Lors de l'exécution dans une instance python différente, utilisez

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)
38
Himanshu Babal

Dans la plupart des cas, la meilleure solution consiste à enregistrer et à restaurer à partir d'un disque à l'aide d'un 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

Vous pouvez également enregistrer/restaurer la structure même du graphe (voir la documentation MetaGraph pour plus de détails). Par défaut, la variable Saver enregistre la structure du graphique dans un fichier .meta. Vous pouvez appeler import_meta_graph() pour le restaurer. Il restaure la structure du graphique et renvoie une Saver que vous pouvez utiliser pour restaurer l'état du modèle:

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

Cependant, il existe des cas où vous avez besoin de quelque chose de beaucoup plus rapide. Par exemple, si vous implémentez un arrêt précoce, vous souhaitez enregistrer les points de contrôle chaque fois que le modèle s'améliore au cours de la formation (tel que mesuré sur le jeu de validation). S'il n'y a pas de progrès pendant un certain temps, vous souhaitez restaurer le meilleur modèle. Si vous enregistrez le modèle sur le disque à chaque fois qu'il s'améliore, la formation sera considérablement ralentie. L'astuce consiste à enregistrer les états de variable dans memory, puis à les restaurer ultérieurement:

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

Une explication rapide: lorsque vous créez une variable X, TensorFlow crée automatiquement une opération d’affectation X/Assign afin de définir la valeur initiale de la variable. Au lieu de créer des espaces réservés et des opérations d’affectation supplémentaires (ce qui rendrait le graphique confus), nous utilisons simplement ces opérations d’affectation existantes. La première entrée de chaque opération d'affectation est une référence à la variable qu'elle est supposée initialiser, et la deuxième entrée (assign_op.inputs[1]) est la valeur initiale. Ainsi, afin de définir la valeur souhaitée (au lieu de la valeur initiale), nous devons utiliser un feed_dict et remplacer la valeur initiale. Oui, TensorFlow vous permet d’envoyer une valeur pour n’importe quelle opération, pas seulement pour les espaces réservés, donc cela fonctionne bien.

20
MiniQuark

Comme l'a dit Yaroslav, vous pouvez modifier la restauration à partir d'un graph_def et d'un point de contrôle en important le graphique, en créant manuellement des variables, puis en utilisant un économiseur.

J'ai implémenté cela pour mon usage personnel, alors je pensais partager le code ici.

Lien: https://Gist.github.com/nikitakit/6ef3b72be67b86cb7868

(Il s’agit bien sûr d’un hack et il n’est pas garanti que les modèles enregistrés de cette manière resteront lisibles dans les futures versions de TensorFlow.)

17
nikitakit

S'il s'agit d'un modèle enregistré en interne, vous devez simplement spécifier un restaurateur pour toutes les variables.

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

et utilisez-le pour restaurer des variables dans une session en cours:

restorer.restore(self._sess, model_file)

Pour le modèle externe, vous devez spécifier le mappage entre ses noms de variable et vos noms de variable. Vous pouvez afficher les noms de variable de modèle à l’aide de la commande 

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

Le script inspect_checkpoint.py est disponible dans le dossier './tensorflow/python/tools' de la source Tensorflow.

Pour spécifier le mappage, vous pouvez utiliser mon Tensorflow-Worklab , qui contient un ensemble de classes et de scripts pour former et recycler différents modèles. Il inclut un exemple de recyclage des modèles ResNet, situé ici

14
Sergey Demyanov

Voici ma solution simple pour les deux cas de base, selon que vous voulez charger le graphique à partir d'un fichier ou le construire pendant l'exécution.

Cette réponse est valable pour Tensorflow 0.12+ (y compris 1.0).

Reconstruire le graphique en code

Économie

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

Chargement

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

Charger aussi le graphique depuis un fichier

Lorsque vous utilisez cette technique, assurez-vous que tous vos calques/variables ont explicitement défini des noms uniques. Sinon, Tensorflow rendra les noms uniques et ils seront donc différents des noms stockés dans le fichier. Ce n'est pas un problème dans la technique précédente, parce que les noms sont "mutilés" de la même manière lors du chargement et de la sauvegarde.

Économie

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

Chargement

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
Martin Pecka

Vous pouvez également consulter examples in TensorFlow/skflow , qui propose des méthodes save et restore permettant de gérer facilement vos modèles. Il a des paramètres que vous pouvez également contrôler la fréquence à laquelle vous voulez sauvegarder votre modèle. 

10
Yuan Tang

Toutes les réponses ici sont excellentes, mais je veux ajouter deux choses.

Tout d’abord, pour préciser la réponse de @ user7505159, il peut être important d’ajouter "./" au début du nom de fichier que vous restaurez.

Par exemple, vous pouvez enregistrer un graphique sans "./" dans le nom du fichier, comme ceci:

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

Mais pour restaurer le graphique, vous devrez peut-être ajouter un "./" au nom de fichier:

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

Vous n’avez pas toujours besoin du "./", mais cela peut poser des problèmes en fonction de votre environnement et de la version de TensorFlow.

Il convient également de mentionner que le sess.run(tf.global_variables_initializer()) peut être important avant de restaurer la session.

Si vous recevez une erreur concernant les variables non initialisées lorsque vous essayez de restaurer une session enregistrée, veillez à inclure sess.run(tf.global_variables_initializer()) avant la ligne saver.restore(sess, save_file). Cela peut vous éviter un mal de tête.

8
saetch_g

Si vous utilisez tf.train.MonitoredTrainingSession comme session par défaut, vous n'avez pas besoin d'ajouter de code supplémentaire pour enregistrer/restaurer des éléments. Il suffit de passer un nom de répertoire de point de contrôle au constructeur de MonitoredTrainingSession, qui utilisera des points d'ancrage pour les gérer. 

8
Changming Sun

Comme décrit dans le numéro 6255 :

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

au lieu de 

saver.restore('my_model_final.ckpt')
7
AI4U.ai

Selon la nouvelle version de Tensorflow, tf.train.Checkpoint est le meilleur moyen de sauvegarder et de restaurer un modèle:

Checkpoint.save et Checkpoint.restore écrivent et lisent des fichiers .__ basés sur des objets. points de contrôle, contrairement à tf.train.Saver qui écrit et lit points de contrôle basés sur variable.name. Le point de contrôle basé sur les objets enregistre un graphique des dépendances entre les objets Python (couches, optimiseurs, variables, etc.) avec des arêtes nommées, et ce graphique est utilisé pour faire correspondre. variables lors de la restauration d'un point de contrôle. Il peut être plus robuste pour modifications apportées au programme Python et aide à prendre en charge la restauration sur création pour les variables lors de l'exécution avec impatience. Préférer tf.train.Checkpoint sur tf.train.Saver pour le nouveau code.

Voici un exemple:

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)

Plus d'informations et exemple ici.

3
Amir

Vous pouvez sauvegarder les variables sur le réseau en utilisant

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

Pour restaurer le réseau pour une réutilisation ultérieure ou dans un autre script, utilisez:

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

Les points importants:

  1. sess doit être identique entre la première et la dernière exécution (structure cohérente). 
  2. saver.restore a besoin du chemin du dossier des fichiers sauvegardés, pas d’un chemin de fichier individuel. 
3
Ali Mahdavi

Utilisez tf.train.Saver pour enregistrer un modèle, que vous vous en souvenez, vous devez spécifier var_list si vous souhaitez réduire la taille du modèle. La val_list peut être tf.trainable_variables ou tf.global_variables.

2
Ariel

Où que vous vouliez sauvegarder le modèle,

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

Assurez-vous que tous vos tf.Variable ont des noms, car vous voudrez peut-être les restaurer plus tard en utilisant leurs noms .

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

Assurez-vous que l’économiseur s’exécute dans la session correspondante. Rappelez-vous que, si vous utilisez la tf.train.latest_checkpoint('./'), seul le dernier point de contrôle sera utilisé. 

1
Akshaya Natarajan

Pour tensorflow 2.0 , c'est aussi simple que

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

Restaurer:

new_model = tensorflow.keras.models.load_model('path_to_my_model.h5')
1
serv-inc

Le mode réactif est également une question non résolue de sauvegarde/restauration à laquelle personne n'a répondu, pas même la documentation, bien que la documentation soit censée y répondre. Voici le code non fonctionnel que j'ai écrit et qui tente d'utiliser la classe Saver dans tensorflow.contrib.eager en tant que tfe. Mon code définitivement enregistré sur le disque ... quelque chose a été enregistré. Le problème est la restauration. J'ai même ajouté du code explicite pour d'abord tout recréer manuellement, puis pour charger les paramètres appris:

optimizer = tf.train.AdamOptimizer() #ga
global_step = tf.train.get_or_create_global_step()  # what is a global_step?
model = tf.keras.Sequential([
  tf.keras.layers.Dense(10, activation=tf.nn.relu, input_shape=(4,)),  # input shape required
  tf.keras.layers.Dense(10, activation=tf.nn.relu, kernel_initializer='glorot_uniform'),
  tf.keras.layers.Dense(3)
])
#s = tfe.Saver([optimizer, model, global_step])
s = tfe.Saver([model])
s.restore(file_prefix="/tmp/iris-1")

Il restaure quelque chose puis jette un ValueError:

INFO:tensorflow:Restoring parameters from /tmp/iris-1

---------------------------------------------------------------------------
ValueError...
--> names, slices, dtypes = Zip(*restore_specs) 
0
Geoffrey Anderson

Je suis sur la version:

tensorflow (1.13.1)
tensorflow-gpu (1.13.1)

Moyen simple est

Sauvegarder:

model.save("model.h5")

Restaurer:

model = tf.keras.models.load_model("model.h5")
0
007fred