Tensorflow: comment enregistrer / restaurer un modèle?

553

Après avoir formé un modèle dans Tensorflow:

  1. Comment enregistrez-vous le modèle formé?
  2. Comment restaurer ultérieurement ce modèle enregistré?
mathetes
la source
Avez-vous pu restaurer les variables utilisées dans le modèle de démarrage? J'essaie également exactement le même problème, mais je ne suis pas en mesure d'écrire un ensemble de variables qui ont été utilisées lors de la formation du modèle de démarrage (dont j'ai le fichier ckpt)
exAres
Je n'ai pas essayé avec le modèle de création. Avez-vous la structure réseau du modèle avec ses noms? Vous devez répliquer le réseau, puis charger les poids et les biais (le fichier ckpt) comme l'explique Ryan. Peut-être que quelque chose a changé depuis le 15 novembre et qu'il y a maintenant une approche plus simple, je ne suis pas sûr
mathetes
Ohh d'accord. J'ai déjà chargé d'autres modèles de tensorflow pré-formés, mais je cherchais des spécifications variables pour le modèle de démarrage. Merci.
départ
1
Si vous restaurez pour continuer à vous entraîner, utilisez simplement les points de contrôle Saver. Si vous enregistrez le modèle pour faire référence, uniquement les API tensorflow SavedModel.
HY G
De plus, si vous utilisez LSTM, vous aurez une carte de chaîne à une liste de caractères, assurez-vous de sauvegarder et de charger cette liste dans le même ordre! Cela n'est pas couvert par l'enregistrement des pondérations du modèle et du réseau de graphes de modèle et il semblera que votre modèle n'a pas été chargé lorsque vous modifiez des sessions ou les modifications de données.
devssh

Réponses:

119

Documents

De la documentation:

sauver

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

Restaurer

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 2

Ceci est encore en version bêta, donc je déconseille pour l'instant. Si vous voulez toujours emprunter cette voie, voici le tf.saved_modelguide d'utilisation

Tensorflow <2

simple_save

Beaucoup de bonne réponse, pour être complet j'ajouterai mes 2 cents: simple_save . Également un exemple de code autonome utilisant l' tf.data.DatasetAPI.

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
        )

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 pour la démonstration.

  1. Nous commençons par créer les espaces réservés. Ils conserveront les données lors de l'exécution. À partir d'eux, nous créons le Datasetpuis son Iterator. Nous obtenons le tenseur généré par l'itérateur, appelé input_tensorqui servira d'entrée à notre modèle.
  2. Le modèle lui-même est construit à partir input_tensor: d'un RNN bidirectionnel basé sur GRU suivi d'un classificateur dense. Parce que pourquoi pas.
  3. La perte est a softmax_cross_entropy_with_logits, optimisée avec Adam. Après 2 époques (de 2 lots chacune), nous sauvegardons le modèle "entraîné" avec tf.saved_model.simple_save. Si vous exécutez le code tel quel, le modèle sera 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 récupérons les espaces réservés et les logits avec graph.get_tensor_by_nameet l' Iteratoropération d'initialisation avec graph.get_operation_by_name.
  5. Enfin, nous effectuons une inférence pour les deux lots dans l'ensemble de données et vérifions que les modèles enregistré et restauré produisent tous les deux 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 __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)

Cela imprimera:

$ 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
ted
la source
1
Je suis débutant et j'ai besoin de plus d'explications ...: Si j'ai un modèle CNN, dois-je stocker juste 1. inputs_placeholder 2. labels_placeholder, et 3. output_of_cnn? Ou tous les intermédiaires tf.contrib.layers?
pleut le
2
Le graphique est entièrement restauré. Vous pouvez le vérifier en cours d'exécution [n.name for n in graph2.as_graph_def().node]. Comme le dit la documentation, la sauvegarde simple vise à simplifier l'interaction avec le service tensorflow, c'est le point des arguments; d'autres variables sont cependant toujours restaurées, sinon l'inférence ne se produirait pas. Saisissez simplement vos variables d'intérêt comme je l'ai fait dans l'exemple. Consultez la documentation
ted
@ted quand utiliserais-je tf.saved_model.simple_save vs tf.train.Saver ()? D'après mon intuition, j'utiliserais tf.train.Saver () pendant l'entraînement et pour stocker différents moments dans le temps. J'utiliserais tf.saved_model.simple_save lorsque la formation est effectuée pour une utilisation en production. (J'ai demandé la même chose aussi dans un commentaire ici )
loco.loop
1
Bien je suppose, mais cela fonctionne-t-il également avec les modèles en mode Désireux et tfe.Saver?
Geoffrey Anderson
1
sans global_stepargument, si vous vous arrêtez puis essayez de reprendre la formation, il pensera que vous êtes une étape. Cela gâchera au moins vos visualisations de tensorboard
Monica Heddneck
252

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) la version 0.11 de Tensorflow :

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

Restaurer 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

sankit
la source
3
+1 pour ce # Accéder aux variables enregistrées directement imprimer (sess.run ('biais: 0')) # Cela affichera 2, qui est la valeur du biais que nous avons enregistré. Cela aide beaucoup à des fins de débogage pour voir si le modèle est correctement chargé. les variables peuvent être obtenues avec "All_varaibles = tf.get_collection (tf.GraphKeys.GLOBAL_VARIABLES". De plus, "sess.run (tf.global_variables_initializer ())" doit être avant la restauration.
LGG
1
Voulez-vous vraiment réexécuter global_variables_initializer? J'ai restauré mon graphique avec global_variable_initialization, et cela me donne une sortie différente à chaque fois sur les mêmes données. J'ai donc commenté l'initialisation et juste restauré le graphique, la variable d'entrée et les opérations, et maintenant cela fonctionne bien.
Aditya Shinde
@AdityaShinde Je ne comprends pas pourquoi j'ai toujours des valeurs différentes à chaque fois. Et je n'ai pas inclus l'étape d'initialisation variable pour la restauration. J'utilise mon propre code btw.
Chaine
@AdityaShinde: vous n'avez pas besoin d'init op car les valeurs sont déjà initialisées par la fonction de restauration, alors supprimez-la. Cependant, je ne sais pas pourquoi vous avez obtenu une sortie différente en utilisant init op.
sankit
5
@sankit Lorsque vous restaurez les tenseurs, pourquoi ajoutez-vous :0aux noms?
Sahar Rabinoviz
177

Dans (et après) la version 0.11.0RC1 de TensorFlow, vous pouvez enregistrer et restaurer votre modèle directement en appelant tf.train.export_meta_graphet tf.train.import_meta_graphselon https://www.tensorflow.org/programmers_guide/meta_graph .

Enregistrez 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_)
lei du
la source
4
comment charger des variables à partir du modèle enregistré? Comment copier des valeurs dans une autre variable?
neel
9
Je n'arrive pas à faire fonctionner ce code. Le modèle est enregistré mais je ne peux pas le restaurer. Cela me donne cette erreur. <built-in function TF_Run> returned a result with an error set
Saad Qureshi
2
Lorsque, après la restauration, j'accède aux variables comme indiqué ci-dessus, cela fonctionne. Mais je ne peux pas obtenir les variables plus directement en utilisant tf.get_variable_scope().reuse_variables()suivi de var = tf.get_variable("varname"). Cela me donne l'erreur: "ValueError: la variable varname n'existe pas ou n'a pas été créée avec tf.get_variable ()." Pourquoi? Cela ne devrait-il pas être possible?
Johann Petrak
4
Cela fonctionne bien pour les variables uniquement, mais comment pouvez-vous accéder à un espace réservé et lui donner des valeurs après avoir restauré le graphique?
kbrose
11
Cela montre uniquement comment restaurer les variables. Comment pouvez-vous restaurer l'intégralité du modèle et le tester sur de nouvelles données sans redéfinir le réseau?
Chaine
127

Pour la version TensorFlow <0.11.0RC1:

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

Voici un exemple de régression linéaire où il y a une boucle d'apprentissage qui enregistre les points de contrôle des variables et une section d'évaluation qui restaurera les variables enregistrées lors d'une exécution précédente et calculera les prédictions. Bien sûr, vous pouvez également restaurer des variables et continuer 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 documents pour Variables, qui couvrent la sauvegarde et la restauration. Et voici les documents pour le Saver.

Ryan Sepassi
la source
1
Les DRAPEAUX sont définis par l'utilisateur. Voici un exemple de leur définition: github.com/tensorflow/tensorflow/blob/master/tensorflow/…
Ryan Sepassi
dans quel format batch_xdoit être? Binaire? Tableau Numpy?
pepe
@pepe L'arrivée de Numpy devrait convenir. Et le type de l'élément doit correspondre au type de l'espace réservé. [lien] tensorflow.org/versions/r0.9/api_docs/python/…
Donny
FLAGS donne une erreur undefined. Pouvez-vous me dire quelle est la définition de FLAGS pour ce code. @RyanSepassi
Muhammad Hannan
Pour le rendre explicite: Les versions récentes de tensorflow ne permettent de stocker le modèle / graphique. [Il n'était pas clair pour moi quels aspects de la réponse s'appliquent à la contrainte <0,11. Étant donné le grand nombre de votes positifs, j'étais tenté de croire que cette déclaration générale est toujours vraie pour les versions récentes.]
bluenote10
78

Mon environnement: Python 3.6, Tensorflow 1.3.0

Bien qu'il y ait eu de nombreuses solutions, la plupart d'entre elles sont basées sur tf.train.Saver. Lorsque nous chargeons un .ckptsauvé par Saver, nous devons redéfinir soit le réseau tensorflow ou utiliser un bizarre nom et dur rappeler, 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 plus sur Serving a TensorFlow Model :

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

Chargez 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})
À M
la source
4
+1 pour un excellent exemple de l'API SavedModel. Cependant, je souhaite que votre section Enregistrer le modèle montre une boucle de formation comme la réponse de Ryan Sepassi! Je me rends compte que c'est une vieille question, mais cette réponse est l'un des rares (et précieux) exemples de SavedModel que j'ai trouvés sur Google.
Dylan F
@Tom c'est une excellente réponse - une seule destinée au nouveau SavedModel. Pourriez-vous jeter un œil à cette question SavedModel? stackoverflow.com/questions/48540744/…
bluesummers
Maintenant, faites tout fonctionner correctement avec les modèles TF Eager. Google a conseillé dans sa présentation 2018 à tout le monde de s'éloigner du code graphique TF.
Geoffrey Anderson
55

Le modèle comporte deux parties, la définition du modèle, enregistrée par Supervisorcomme graph.pbtxtdans le répertoire du modèle et les valeurs numériques des tenseurs, enregistrées dans des fichiers de point de contrôle comme model.ckpt-1003418.

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

Cependant, Saverutilise une collection spéciale contenant une liste de variables attachées au graphique du modèle, et cette collection n'est pas initialisée à l'aide d'import_graph_def, vous ne pouvez donc pas utiliser les deux ensemble pour le moment (c'est sur notre feuille de route à corriger). Pour l'instant, vous devez utiliser l'approche de Ryan Sepassi - construire manuellement un graphique avec des noms de nœuds identiques, et utiliser Saverpour y charger les poids.

(Alternativement, vous pouvez le pirater en utilisant 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)

Yaroslav Bulatov
la source
Dans l'exemple classify_image.py qui utilise inceptionv3, seul le graphdef est chargé. Est-ce à dire que maintenant le GraphDef contient également la variable?
2016 à 20h42
1
@jrabary Le modèle a probablement été gelé .
Eric Platon
1
Hey, je suis nouveau sur tensorflow et j'ai du mal à enregistrer mon modèle. J'apprécierais vraiment si vous pouviez m'aider stackoverflow.com/questions/48083474/…
Ruchir Baronia
39

Vous pouvez également utiliser cette méthode plus facilement.

É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 Saveret 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)
Himanshu Babal
la source
Salut, Comment puis-je enregistrer le modèle après supposer 3000 itérations, similaire à Caffe. J'ai découvert que tensorflow enregistre uniquement les derniers modèles malgré que je concatène le numéro d'itération avec le modèle pour le différencier entre toutes les itérations. Je veux dire model_3000.ckpt, model_6000.ckpt, --- model_100000.ckpt. Pouvez-vous bien vouloir expliquer pourquoi il ne sauvegarde pas tout, mais enregistre plutôt uniquement les 3 dernières itérations.
khan
2
@khan voir stackoverflow.com/questions/38265061/…
Himanshu Babal
3
Existe-t-il une méthode pour obtenir toutes les variables / noms d'opération enregistrés dans le graphique?
Moondra
21

Dans la plupart des cas, l'enregistrement et la restauration à partir du disque à l'aide de tf.train.Saverest votre meilleure option:

... # 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 graphique elle-même (voir la documentation MetaGraph pour plus de détails). Par défaut, l' Saverenregistre la structure du graphique dans un .metafichier. Vous pouvez appeler import_meta_graph()pour le restaurer. Il restaure la structure du graphique et renvoie un Saverque 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 y a des cas où vous avez besoin de quelque chose de beaucoup plus rapide. Par exemple, si vous implémentez un arrêt anticipé, vous souhaitez enregistrer les points de contrôle chaque fois que le modèle s'améliore pendant la formation (mesuré sur l'ensemble de validation), puis s'il n'y a pas de progrès pendant un certain temps, vous souhaitez revenir au meilleur modèle. Si vous enregistrez le modèle sur le disque chaque fois qu'il s'améliore, cela ralentit considérablement la formation. L'astuce consiste à enregistrer les états des variables en mémoire , puis à les restaurer plus tard:

... # 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'affectationX/Assign pour 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 désordonné), nous utilisons simplement ces opérations d'affectation existantes. La première entrée de chaque affectation op est une référence à la variable qu'elle est censée initialiser, et la deuxième entrée ( assign_op.inputs[1]) est la valeur initiale. Donc, pour définir la valeur que nous voulons (au lieu de la valeur initiale), nous devons utiliser a feed_dictet remplacer la valeur initiale. Oui, TensorFlow vous permet de fournir une valeur pour n'importe quelle opération, pas seulement pour les espaces réservés, donc cela fonctionne très bien.

MiniQuark
la source
Merci d'avoir répondu. J'ai une question similaire sur la façon de convertir un seul fichier .ckpt en deux fichiers .index et .data (disons pour les modèles de démarrage pré-formés disponibles sur tf.slim). Ma question est ici: stackoverflow.com/questions/47762114/…
Amir
Hey, je suis nouveau sur tensorflow et j'ai du mal à enregistrer mon modèle. J'apprécierais vraiment si vous pouviez m'aider stackoverflow.com/questions/48083474/…
Ruchir Baronia
17

Comme l'a dit Yaroslav, vous pouvez pirater 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, donc je pensais partager le code ici.

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

(Il s'agit bien sûr d'un hack, et rien ne garantit que les modèles enregistrés de cette manière resteront lisibles dans les futures versions de TensorFlow.)

nikitakit
la source
14

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

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

et l'utiliser 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 variables et vos noms de variables. Vous pouvez afficher les noms des variables 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 se trouve 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 comprend un exemple de recyclage des modèles ResNet, situé ici

Sergey Demyanov
la source
all_variables()est désormais obsolète
MiniQuark
Hey, je suis nouveau sur tensorflow et j'ai du mal à enregistrer mon modèle. J'apprécierais vraiment si vous pouviez m'aider stackoverflow.com/questions/48083474/…
Ruchir Baronia
12

Voici ma solution simple pour les deux cas de base différents selon que vous souhaitez charger le graphique à partir d'un fichier ou le créer 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

Chargement également du graphique à partir d'un fichier

Lorsque vous utilisez cette technique, assurez-vous que toutes vos couches / variables ont explicitement défini des noms uniques.Sinon, Tensorflow rendra les noms uniques eux-mêmes 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, car les noms sont "mutilés" de la même manière lors du chargement et de l'enregistrement.

É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
Martin Pecka
la source
-1 Commencer votre réponse en rejetant "toutes les autres réponses ici" est un peu dur. Cela dit, j'ai rétrogradé pour d'autres raisons: vous devez absolument enregistrer toutes les variables globales, pas seulement les variables entraînables. Par exemple, la global_stepvariable et les moyennes mobiles de normalisation par lots sont des variables non entraînables, mais les deux valent vraiment la peine d'être sauvegardées. En outre, vous devez distinguer plus clairement la construction du graphique de l'exécution de la session, par exemple Saver(...).save(), vous créerez de nouveaux nœuds chaque fois que vous l'exécuterez. Probablement pas ce que vous voulez. Et il y a plus ...: /
MiniQuark
@MiniQuark ok, merci pour vos commentaires, je modifierai la réponse en fonction de vos suggestions;)
Martin Pecka
10

Vous pouvez également consulter des exemples dans TensorFlow / skflow , qui propose des méthodes saveet restorequi peuvent vous aider à gérer facilement vos modèles. Il possède des paramètres que vous pouvez également contrôler à quelle fréquence vous souhaitez sauvegarder votre modèle.

Yuan Tang
la source
9

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 choses. Passez simplement un nom de répertoire de point de contrôle au constructeur de MonitoredTrainingSession, il utilisera des hooks de session pour les gérer.

Changming Sun
la source
l'utilisation de tf.train.Supervisor gérera la création d'une telle session pour vous et fournira une solution plus complète.
Mark
1
@Mark tf.train.Supervisor est déconseillé
Changming Sun
Avez-vous un lien soutenant l'affirmation selon laquelle le superviseur est déprécié? Je n'ai rien vu qui indique que ce soit le cas.
Mark
Merci pour l'URL - j'ai vérifié avec la source d'origine des informations et on m'a dit que ce serait probablement le cas jusqu'à la fin de la série TF 1.x, mais aucune garantie après cela.
Mark
8

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

Tout d'abord, pour développer la réponse de @ user7505159, le "./" peut être important à ajouter au début du nom de fichier que vous restaurez.

Par exemple, vous pouvez enregistrer un graphique sans "./" dans le nom de 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_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'aurez pas toujours besoin du "./", mais cela peut poser des problèmes en fonction de votre environnement et de la version de TensorFlow.

Il faut également 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, assurez-vous de l'inclure sess.run(tf.global_variables_initializer())avant la saver.restore(sess, save_file)ligne. Cela peut vous éviter des maux de tête.

saetch_g
la source
7

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')
AI4U.ai
la source
7

Selon la nouvelle version Tensorflow, tf.train.Checkpointest le moyen préférable d'enregistrer et de restaurer un modèle:

Checkpoint.saveet Checkpoint.restoreécrire et lire des points de contrôle basés sur des objets, contrairement à tf.train.Saver qui écrit et lit des 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 bords nommés, et ce graphique est utilisé pour faire correspondre les variables lors de la restauration d'un point de contrôle. Il peut être plus robuste aux modifications du programme Python et aide à prendre en charge la restauration lors de la création de variables lors de l'exécution avec impatience. Préférez tf.train.Checkpointle tf.train.Savernouveau 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 d'exemple ici.

Amir
la source
7

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')
serv-inc
la source
Qu'en est-il de toutes les opérations et variables tf personnalisées qui ne font pas partie de l'objet modèle? Seront-ils enregistrés d'une manière ou d'une autre lorsque vous appelez save () sur le modèle? J'ai diverses expressions personnalisées de perte et de probabilité de tensorflow qui sont utilisées dans le réseau d'inférence et de génération, mais elles ne font pas partie de mon modèle. Mon objet modèle keras ne contient que les couches denses et conv. Dans TF 1, je viens d'appeler la méthode de sauvegarde et je pouvais être sûr que toutes les opérations et tenseurs utilisés dans mon graphique seraient enregistrés. Dans TF2, je ne vois pas comment les opérations qui ne sont pas en quelque sorte ajoutées au modèle de kéros seront enregistrées.
Kristof
Y a-t-il plus d'informations sur la restauration des modèles dans TF 2.0? Je ne peux pas restaurer les poids des fichiers de points de contrôle générés via l'API C, voir: stackoverflow.com/questions/57944786/…
jregalad
5

tf.keras Enregistrement de modèle avec TF2.0

Je vois d'excellentes réponses pour enregistrer des modèles à l'aide de TF1.x. Je veux fournir quelques conseils supplémentaires pour enregistrer des tensorflow.kerasmodèles, ce qui est un peu compliqué car il existe de nombreuses façons de sauvegarder un modèle.

Ici, je fournis un exemple d'enregistrement d'un tensorflow.kerasmodèle dans un model_pathdossier sous le répertoire actuel. Cela fonctionne bien avec le tensorflow le plus récent (TF2.0). Je mettrai à jour cette description en cas de changement dans un avenir proche.

Enregistrement et chargement du modèle entier

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

Enregistrement et chargement des poids du modèle uniquement

Si vous souhaitez enregistrer uniquement les poids du modèle, puis charger des poids pour restaurer le modèle,

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

Enregistrement et restauration à l'aide du rappel de point de contrôle 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))

modèle d'enregistrement avec des mesures personnalisées

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

Enregistrement du modèle de keras avec des opérations personnalisées

Lorsque nous avons des opérations personnalisées comme dans le cas suivant ( tf.tile), nous devons créer une fonction et encapsuler avec une couche Lambda. Sinon, le modèle ne peut pas être enregistré.

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

Je pense avoir couvert quelques-unes des nombreuses façons de sauvegarder le modèle tf.keras. Cependant, il existe de nombreuses autres façons. Veuillez commenter ci-dessous si vous voyez que votre cas d'utilisation n'est pas couvert ci-dessus. Merci!

Vishnuvardhan Janapati
la source
3

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

Ariel
la source
3

Vous pouvez enregistrer les variables dans 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 le même entre la première et la dernière exécution (structure cohérente).
  2. saver.restore a besoin du chemin du dossier des fichiers enregistrés, pas d'un chemin de fichier individuel.
Ali Mahdavi
la source
2

Où que vous souhaitiez enregistrer 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 vous tf.Variableavez tous des noms, car vous souhaiterez peut-être les restaurer ultérieurement en utilisant leurs noms. Et où vous voulez prédire,

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. N'oubliez pas que si vous utilisez le tf.train.latest_checkpoint('./'), seul le dernier point de contrôle sera utilisé.

Akshaya Natarajan
la source
2

Je suis sur la version:

tensorflow (1.13.1)
tensorflow-gpu (1.13.1)

Un moyen simple est

Sauver:

model.save("model.h5")

Restaurer:

model = tf.keras.models.load_model("model.h5")
007fred
la source
2

Pour tensorflow-2.0

c'est très simple.

import tensorflow as tf

ENREGISTRER

model.save("model_name")

RESTAURER

model = tf.keras.models.load_model('model_name')
Ashiq Imran
la source
1

Suite à la réponse de @Vishnuvardhan Janapati, voici une autre façon d'enregistrer et de recharger le modèle avec une couche / métrique / perte personnalisée sous 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})  

De cette façon, une fois que vous avez exécuté de tels codes et enregistré votre modèle avec tf.keras.models.save_modelou model.saveou ModelCheckpointrappel, vous pouvez recharger votre modèle sans avoir besoin d'objets personnalisés précis, aussi simple que

new_model = tf.keras.models.load_model("./model.h5"})
yiyang
la source
0

Dans la nouvelle version de tensorflow 2.0, le processus de sauvegarde / chargement d'un modèle est beaucoup plus facile. En raison de l'implémentation de l'API Keras, une API de haut niveau pour TensorFlow.

Pour enregistrer un modèle: consultez la documentation pour référence: 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)

Pour charger un modèle:

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

model = tf.keras.models.load_model(filepath)
Vineet Suryan
la source
0

Voici un exemple simple utilisant le format Tensorflow 2.0 SavedModel (qui est le format recommandé, selon les documents ) pour un classificateur de jeu de données MNIST simple, en utilisant l'API fonctionnelle Keras sans trop de fantaisie:

# 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

Qu'est-ce que c'est serving_default?

Il s'agit du nom de la signature par défaut du tag que vous avez sélectionné (dans ce cas, le servetag par défaut a été sélectionné). Également, ici explique comment trouver les balises et les signatures d'un modèle à l'aide saved_model_cli.

Avertissements

Ce n'est qu'un exemple de base si vous voulez simplement le mettre en service, mais ce n'est en aucun cas une réponse complète - je pourrai peut-être le mettre à jour à l'avenir. Je voulais juste donner un exemple simple en utilisant leSavedModel TF 2.0 car je n'en ai vu aucun, même si simple, nulle part.

@ La réponse de Tom est un exemple de SavedModel, mais cela ne fonctionnera pas sur Tensorflow 2.0, car malheureusement il y a des changements de rupture.

@ La réponse de Vishnuvardhan Janapati dit TF 2.0, mais ce n'est pas pour le format SavedModel.

Bersan
la source