Tensorflow: Wie speichere / stelle ich ein Modell wieder her?


552

Nachdem Sie ein Modell in Tensorflow trainiert haben:

  1. Wie speichern Sie das trainierte Modell?
  2. Wie können Sie dieses gespeicherte Modell später wiederherstellen?

Konnten Sie die im Inception-Modell verwendeten Variablen wiederherstellen? Ich versuche auch genau das gleiche Problem, aber ich kann keine Variablen schreiben, die beim Training des Inception-Modells (von dem ich eine ckpt-Datei habe) verwendet wurden
exAres

Ich habe es mit dem Inception-Modell nicht versucht. Haben Sie die Netzwerkstruktur des Modells mit seinen Namen? Sie müssen das Netzwerk replizieren und dann die Gewichte und Verzerrungen (die ckpt-Datei) laden, wie Ryan erklärt. Vielleicht hat sich seit dem 15. November etwas geändert und es gibt jetzt einen einfacheren Ansatz, ich bin mir nicht sicher
Mathetes

Ohh ok. Ich habe bereits andere vorab trainierte Tensorflow-Modelle geladen, suchte jedoch nach variablen Spezifikationen des Inception-Modells. Vielen Dank.
ExAres

1
Wenn Sie wiederherstellen, um mit dem Training fortzufahren, verwenden Sie einfach die Saver-Checkpoints. Wenn Sie das Modell als Referenz speichern, nur die Tensorflow-SavedModel-APIs.
HY G

Auch wenn Sie LSTM verwenden, haben Sie eine Zuordnung von einer Zeichenfolge zu einer Liste von Zeichen. Speichern und laden Sie diese Liste in derselben Reihenfolge! Dies wird nicht durch das Speichern der Modellgewichte und des Modelldiagrammnetzwerks abgedeckt und lässt den Eindruck entstehen, dass Ihr Modell nicht geladen wurde, wenn Sie Sitzungen ändern oder sich die Daten ändern.
Devssh

Antworten:


119

Docs

Aus den Dokumenten:

speichern

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

Wiederherstellen

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

Dies ist noch Beta, daher würde ich vorerst davon abraten. Wenn Sie diesen Weg noch gehen möchten, finden Sie hier die tf.saved_modelGebrauchsanweisung

Tensorflow <2

simple_save

Viele gute Antworten, der Vollständigkeit halber füge ich meine 2 Cent hinzu: simple_save . Auch ein eigenständiges Codebeispiel mit der 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
        )

Wiederherstellen:

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

Eigenständiges Beispiel

Ursprünglicher Blog-Beitrag

Der folgende Code generiert zur Demonstration zufällige Daten.

  1. Wir beginnen mit der Erstellung der Platzhalter. Sie speichern die Daten zur Laufzeit. Aus ihnen erschaffen wir das Datasetund dann sein Iterator. Wir erhalten den vom Iterator erzeugten Tensor, genanntinput_tensor der als Eingabe für unser Modell dient.
  2. Das Modell selbst besteht aus input_tensor: einem GRU-basierten bidirektionalen RNN, gefolgt von einem dichten Klassifikator. Weil warum nicht.
  3. Der Verlust ist ein softmax_cross_entropy_with_logits, optimiert mit Adam. Nach 2 Epochen (mit jeweils 2 Chargen) speichern wir das "trainierte" Modell mit tf.saved_model.simple_save. Wenn Sie den Code unverändert ausführen, wird das Modell in einem Ordner gespeichert, der simple/in Ihrem aktuellen Arbeitsverzeichnis aufgerufen wird .
  4. In einem neuen Diagramm stellen wir dann das gespeicherte Modell mit wieder her tf.saved_model.loader.load. Wir greifen die Platzhalter und Logs mit graph.get_tensor_by_nameund den IteratorInitialisierungsvorgang mit graph.get_operation_by_name.
  5. Zuletzt führen wir eine Inferenz für beide Stapel im Dataset durch und überprüfen, ob das gespeicherte und das wiederhergestellte Modell beide dieselben Werte ergeben. Tun sie!

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)

Dies wird gedruckt:

$ 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

1
Ich bin Anfänger und brauche weitere Erklärungen ...: Wenn ich ein CNN-Modell habe, sollte ich nur 1. input_placeholder 2. labels_placeholder und 3. output_of_cnn speichern? Oder alle Zwischenprodukte tf.contrib.layers?
Regen

2
Das Diagramm wird vollständig wiederhergestellt. Sie könnten überprüfen, ob es läuft [n.name for n in graph2.as_graph_def().node]. Wie in der Dokumentation angegeben, zielt das einfache Speichern darauf ab, die Interaktion mit dem Tensorflow-Serving zu vereinfachen. Dies ist der Punkt der Argumente. andere Variablen werden jedoch noch wiederhergestellt, da sonst keine Inferenz auftreten würde. Nehmen Sie einfach Ihre interessierenden Variablen wie im Beispiel. Schauen Sie sich die Dokumentation an
am

@ted wann würde ich tf.saved_model.simple_save vs tf.train.Saver () verwenden? Aus meiner Intuition heraus würde ich tf.train.Saver () während des Trainings verwenden und verschiedene Momente in der Zeit speichern. Ich würde tf.saved_model.simple_save verwenden, wenn das Training für die Verwendung in der Produktion abgeschlossen ist. (Ich habe das auch in einem Kommentar hier gefragt )
loco.loop

1
Schön, denke ich, aber funktioniert es auch mit Eager-Modus-Modellen und tfe.Saver?
Geoffrey Anderson

1
Ohne global_stepein Argument, wenn Sie aufhören und dann versuchen, das Training wieder aufzunehmen, wird es denken, dass Sie ein Schritt eins sind. Es wird zumindest Ihre Tensorboard-Visualisierungen vermasseln
Monica Heddneck

252

Ich verbessere meine Antwort, um weitere Details zum Speichern und Wiederherstellen von Modellen hinzuzufügen.

In (und nach) Tensorflow Version 0.11 :

Speichern Sie das Modell:

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)

Stellen Sie das Modell wieder her:

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 

Dieser und einige fortgeschrittenere Anwendungsfälle wurden hier sehr gut erklärt.

Ein kurzes, vollständiges Tutorial zum Speichern und Wiederherstellen von Tensorflow-Modellen


3
+1 für diesen # Zugriff auf gespeicherte Variablen direkt drucken (sess.run ('Bias: 0')) # Dies gibt 2 aus, das ist der Wert des Bias, den wir gespeichert haben. Für Debugging-Zwecke ist es sehr hilfreich, festzustellen, ob das Modell korrekt geladen ist. Die Variablen können mit "All_varaibles = tf.get_collection (tf.GraphKeys.GLOBAL_VARIABLES" abgerufen werden. Außerdem muss "sess.run (tf.global_variables_initializer ())" vor der Wiederherstellung sein.
LGG

1
Sind Sie sicher, dass wir global_variables_initializer erneut ausführen müssen? Ich habe mein Diagramm mit global_variable_initialization wiederhergestellt und es gibt mir jedes Mal eine andere Ausgabe für dieselben Daten. Also habe ich die Initialisierung auskommentiert und nur das Diagramm, die Eingabevariable und die Operationen wiederhergestellt, und jetzt funktioniert es einwandfrei.
Aditya Shinde

@AdityaShinde Ich verstehe nicht, warum ich jedes Mal andere Werte bekomme. Und ich habe den Variableninitialisierungsschritt zum Wiederherstellen nicht eingeschlossen. Ich benutze übrigens meinen eigenen Code.
Chaine

@AdityaShinde: Sie benötigen keine Init-Operation, da die Werte bereits durch die Wiederherstellungsfunktion initialisiert wurden. Entfernen Sie sie daher. Ich bin mir jedoch nicht sicher, warum Sie mit init op eine andere Ausgabe erhalten haben.
Sankit

5
@sankit Wenn Sie die Tensoren wiederherstellen, warum fügen Sie :0sie den Namen hinzu?
Sahar Rabinoviz

177

In (und nach) TensorFlow Version 0.11.0RC1 können Sie Ihr Modell direkt durch den Aufruf speichern und wiederherzustellen tf.train.export_meta_graphund tf.train.import_meta_graphnach https://www.tensorflow.org/programmers_guide/meta_graph .

Speichern Sie das Modell

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

Stellen Sie das Modell wieder her

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

4
Wie lade ich Variablen aus dem gespeicherten Modell? Wie kopiere ich Werte in eine andere Variable?
Neel

9
Ich kann diesen Code nicht zum Laufen bringen. Das Modell wird zwar gespeichert, kann aber nicht wiederhergestellt werden. Es gibt mir diesen Fehler. <built-in function TF_Run> returned a result with an error set
Saad Qureshi

2
Wenn ich nach dem Wiederherstellen wie oben gezeigt auf die Variablen zugreife, funktioniert es. Aber ich kann die Variablen nicht direkter mit tf.get_variable_scope().reuse_variables()gefolgt von erhalten var = tf.get_variable("varname"). Dies gibt mir den Fehler: "ValueError: Variable varname existiert nicht oder wurde nicht mit tf.get_variable () erstellt." Warum? Sollte das nicht möglich sein?
Johann Petrak

4
Dies funktioniert nur für Variablen. Wie können Sie jedoch nach dem Wiederherstellen des Diagramms auf einen Platzhalter zugreifen und ihm Werte zuführen?
Kbrose

11
Dies zeigt nur, wie die Variablen wiederhergestellt werden. Wie können Sie das gesamte Modell wiederherstellen und auf neuen Daten testen, ohne das Netzwerk neu zu definieren?
Chaine

127

Für TensorFlow-Version <0.11.0RC1:

Die gespeicherten Prüfpunkte enthalten Werte für die Variables in Ihrem Modell, nicht für das Modell / Diagramm selbst. Dies bedeutet, dass das Diagramm beim Wiederherstellen des Prüfpunkts identisch sein sollte.

Hier ist ein Beispiel für eine lineare Regression, bei der es eine Trainingsschleife gibt, in der Variablenprüfpunkte gespeichert werden, und einen Bewertungsabschnitt, in dem in einem vorherigen Lauf gespeicherte Variablen wiederhergestellt und Vorhersagen berechnet werden. Natürlich können Sie auch Variablen wiederherstellen und das Training fortsetzen, wenn Sie möchten.

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

Hier sind die Dokumente für Variables, die das Speichern und Wiederherstellen abdecken. Und hier sind die Dokumente für die Saver.


1
FLAGGEN sind benutzerdefiniert. Hier ist ein Beispiel für ihre Definition: github.com/tensorflow/tensorflow/blob/master/tensorflow/…
Ryan Sepassi

in welchem ​​Format muss batch_xsein? Binär? Numpy Array?
Pepe

@pepe Numpy Arrary sollte in Ordnung sein. Der Typ des Elements sollte dem Typ des Platzhalters entsprechen. [Link] tensorflow.org/versions/r0.9/api_docs/python/…
Donny

FLAGS gibt Fehler undefined. Können Sie mir sagen, welche FLAGS für diesen Code def ist? @ RyanSepassi
Muhammad Hannan

Um es deutlich: Neuere Versionen von Tensorflow Sie erlauben das Modell / Grafik zu speichern. [Mir war unklar, welche Aspekte der Antwort für die Einschränkung <0,11 gelten. Angesichts der großen Anzahl von Upvotes war ich versucht zu glauben, dass diese allgemeine Aussage für neuere Versionen immer noch gilt.]
bluenote10

78

Meine Umgebung: Python 3.6, Tensorflow 1.3.0

Obwohl es viele Lösungen gab, basieren die meisten auf diesen tf.train.Saver. Wenn wir eine Last .ckptvon gespeichert Saver, haben wir das tensorflow Netzwerk entweder neu oder einige seltsame und schwer erinnerten Namen verwenden, zB 'placehold_0:0', 'dense/Adam/Weight:0'. Hier empfehle ich die Verwendung tf.saved_modeleines einfachen Beispiels, mit dem Sie mehr über das Servieren eines TensorFlow-Modells lernen können :

Speichern Sie das Modell:

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

Laden Sie das Modell:

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

4
+1 für ein großartiges Beispiel für die SavedModel-API. Ich wünschte jedoch, Ihr Abschnitt " Modell speichern" hätte eine Trainingsschleife wie die Antwort von Ryan Sepassi gezeigt! Mir ist klar, dass dies eine alte Frage ist, aber diese Antwort ist eines der wenigen (und wertvollen) Beispiele für SavedModel, die ich bei Google gefunden habe.
Dylan F

@ Tom Dies ist eine großartige Antwort - nur eine, die auf das neue SavedModel abzielt. Könnten Sie sich diese SavedModel-Frage ansehen? stackoverflow.com/questions/48540744/…
Bluesummers

Jetzt funktioniert alles korrekt mit TF Eager-Modellen. Google riet in seiner Präsentation für 2018 allen, sich vom TF-Grafikcode zu entfernen.
Geoffrey Anderson

55

Das Modell besteht aus zwei Teilen: der Modelldefinition, die Supervisorwie graph.pbtxtim Modellverzeichnis gespeichert ist, und den numerischen Werten der Tensoren, die in Prüfpunktdateien wie gespeichert werden model.ckpt-1003418.

Die Modelldefinition kann mithilfe von wiederhergestellt werden tf.import_graph_def, und die Gewichte werden mithilfe von wiederhergestellt Saver.

Verwendet jedoch Savereine spezielle Sammlungsliste mit Variablen, die an das Modelldiagramm angehängt sind, und diese Sammlung wird nicht mit import_graph_def initialisiert, sodass Sie die beiden derzeit nicht zusammen verwenden können (dies ist in unserer Roadmap zu beheben). Im Moment müssen Sie den Ansatz von Ryan Sepassi verwenden - manuell ein Diagramm mit identischen Knotennamen erstellen und Saverdie Gewichte darin laden.

(Alternativ können Sie es hacken, indem Sie verwenden import_graph_def, Variablen manuell erstellen und tf.add_to_collection(tf.GraphKeys.VARIABLES, variable)für jede Variable verwenden und dann verwenden. Saver)


Im Beispiel classify_image.py, das inceptionv3 verwendet, wird nur das graphdef geladen. Bedeutet das, dass das GraphDef jetzt auch die Variable enthält?
2.

1
@jrabary Das Modell wurde wahrscheinlich eingefroren .
Eric Platon

1
Hey, ich bin neu im Tensorflow und habe Probleme beim Speichern meines Modells. Ich würde es wirklich schätzen, wenn Sie mir helfen könnten stackoverflow.com/questions/48083474/…
Ruchir Baronia

39

Sie können diesen Weg auch einfacher nehmen.

Schritt 1: Initialisieren Sie alle Ihre Variablen

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

Schritt 2: Speichern Sie die Sitzung im Modell Saverund speichern Sie sie

model_saver = tf.train.Saver()

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

Schritt 3: Stellen Sie das Modell wieder her

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

Schritt 4: Überprüfen Sie Ihre Variable

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

Verwenden Sie, während Sie in einer anderen Python-Instanz ausgeführt werden

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)

Hallo, wie kann ich das Modell nach 3000 Iterationen speichern, ähnlich wie bei Caffe? Ich fand heraus, dass Tensorflow nur die letzten Modelle speichert, obwohl ich die Iterationsnummer mit dem Modell verkette, um sie zwischen allen Iterationen zu unterscheiden. Ich meine model_3000.ckpt, model_6000.ckpt, --- model_100000.ckpt. Können Sie uns bitte erklären, warum nicht alle gespeichert werden, sondern nur die letzten 3 Iterationen gespeichert werden?
Khan


3
Gibt es eine Methode, um alle Variablen / Operationsnamen im Diagramm zu speichern?
Moondra

21

In den meisten Fällen ist das Speichern und Wiederherstellen von der Festplatte mit a tf.train.Saverdie beste 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

Sie können auch die Diagrammstruktur selbst speichern / wiederherstellen ( Einzelheiten finden Sie in der MetaGraph-Dokumentation ). Standardmäßig Saverspeichert das die Diagrammstruktur in einer .metaDatei. Sie können anrufen import_meta_graph(), um es wiederherzustellen. Es stellt die Diagrammstruktur wieder her und gibt eine zurück Saver, mit der Sie den Status des Modells wiederherstellen können:

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

Es gibt jedoch Fälle, in denen Sie etwas viel schneller benötigen. Wenn Sie beispielsweise ein vorzeitiges Anhalten implementieren, möchten Sie jedes Mal, wenn sich das Modell während des Trainings verbessert (gemessen am Validierungssatz), Prüfpunkte speichern. Wenn für einige Zeit keine Fortschritte erzielt werden, möchten Sie zum besten Modell zurückkehren. Wenn Sie das Modell bei jeder Verbesserung auf der Festplatte speichern, wird das Training erheblich verlangsamt. Der Trick besteht darin, die variablen Zustände im Speicher zu speichern und sie später wiederherzustellen:

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

Eine kurze Erklärung: Wenn Sie eine Variable erstellen X, erstellt TensorFlow automatisch eine Zuweisungsoperation X/Assign, um den Anfangswert der Variablen festzulegen. Anstatt Platzhalter und zusätzliche Zuweisungsoperationen zu erstellen (was das Diagramm nur unübersichtlich machen würde), verwenden wir nur diese vorhandenen Zuweisungsoperationen. Die erste Eingabe jeder Zuweisung op ist eine Referenz auf die Variable, die initialisiert werden soll, und die zweite Eingabe (assign_op.inputs[1] ) ist der Anfangswert. Um also einen beliebigen Wert festzulegen (anstelle des Anfangswertes), müssen wir a verwenden feed_dictund den Anfangswert ersetzen. Ja, mit TensorFlow können Sie einen Wert für jede Operation eingeben, nicht nur für Platzhalter. Dies funktioniert also einwandfrei.


Danke für die Antwort. Ich habe eine ähnliche Frage zum Konvertieren einer einzelnen .ckpt-Datei in zwei .index- und .data-Dateien (z. B. für vorab trainierte Inception-Modelle, die auf tf.slim verfügbar sind). Meine Frage ist hier: stackoverflow.com/questions/47762114/…
Amir

Hey, ich bin neu im Tensorflow und habe Probleme beim Speichern meines Modells. Ich würde es wirklich schätzen, wenn Sie mir helfen könnten stackoverflow.com/questions/48083474/…
Ruchir Baronia

17

Wie Jaroslaw sagte, können Sie die Wiederherstellung von einem graph_def und einem Checkpoint hacken, indem Sie das Diagramm importieren, manuell Variablen erstellen und dann einen Sparer verwenden.

Ich habe dies für meinen persönlichen Gebrauch implementiert, daher würde ich den Code hier teilen.

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

(Dies ist natürlich ein Hack, und es gibt keine Garantie dafür, dass auf diese Weise gespeicherte Modelle in zukünftigen Versionen von TensorFlow lesbar bleiben.)


14

Wenn es sich um ein intern gespeichertes Modell handelt, geben Sie einfach einen Wiederhersteller für alle Variablen als an

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

und verwenden Sie es, um Variablen in einer aktuellen Sitzung wiederherzustellen:

restorer.restore(self._sess, model_file)

Für das externe Modell müssen Sie die Zuordnung von den Variablennamen zu Ihren Variablennamen angeben. Sie können die Namen der Modellvariablen mit dem Befehl anzeigen

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

Das Skript inspect_checkpoint.py befindet sich im Ordner './tensorflow/python/tools' der Tensorflow-Quelle.

Um die Zuordnung festzulegen, können Sie mein Tensorflow-Worklab verwenden , das eine Reihe von Klassen und Skripten enthält, um verschiedene Modelle zu trainieren und neu zu trainieren. Es enthält ein Beispiel für die Umschulung von ResNet-Modellen, das sich hier befindet


all_variables()ist jetzt veraltet
MiniQuark

Hey, ich bin neu im Tensorflow und habe Probleme beim Speichern meines Modells. Ich würde es wirklich schätzen, wenn Sie mir helfen könnten stackoverflow.com/questions/48083474/…
Ruchir Baronia

12

Hier ist meine einfache Lösung für die beiden grundlegenden Fälle, die sich darin unterscheiden, ob Sie das Diagramm aus einer Datei laden oder zur Laufzeit erstellen möchten.

Diese Antwort gilt für Tensorflow 0.12+ (einschließlich 1.0).

Neuaufbau des Diagramms im Code

Sparen

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

Wird geladen

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

Laden Sie auch das Diagramm aus einer Datei

Stellen Sie bei Verwendung dieser Technik sicher, dass alle Ihre Ebenen / Variablen explizit eindeutige Namen festgelegt haben.Andernfalls macht Tensorflow die Namen selbst eindeutig und unterscheidet sich somit von den in der Datei gespeicherten Namen. Bei der vorherigen Technik ist dies kein Problem, da die Namen beim Laden und Speichern auf die gleiche Weise "entstellt" werden.

Sparen

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

Wird geladen

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

-1 Das Starten Ihrer Antwort durch Verwerfen von "Alle anderen Antworten hier" ist etwas hart. Trotzdem habe ich aus anderen Gründen abgestimmt: Sie sollten auf jeden Fall alle globalen Variablen speichern, nicht nur die trainierbaren Variablen. Zum Beispiel sind die global_stepVariablen und die gleitenden Durchschnitte der Chargennormalisierung nicht trainierbare Variablen, aber beide sind definitiv eine Speicherung wert. Außerdem sollten Sie die Konstruktion des Diagramms klarer von der Ausführung der Sitzung unterscheiden. Beispielsweise Saver(...).save()werden bei jeder Ausführung neue Knoten erstellt. Wahrscheinlich nicht das, was du willst. Und es gibt noch mehr ...: /
MiniQuark

@MiniQuark ok, danke für dein Feedback, ich werde die Antwort nach deinen Vorschlägen bearbeiten;)
Martin Pecka

10

Sie können sich auch Beispiele in TensorFlow / skflow ansehen , das Angebote saveund restoreMethoden bietet, mit denen Sie Ihre Modelle einfach verwalten können. Es verfügt über Parameter, mit denen Sie auch steuern können, wie oft Sie Ihr Modell sichern möchten.


9

Wenn Sie tf.train.MonitoredTrainingSession als Standardsitzung verwenden, müssen Sie keinen zusätzlichen Code hinzufügen, um Dinge zu speichern / wiederherzustellen. Übergeben Sie einfach einen Checkpoint-Verzeichnisnamen an den Konstruktor von MonitoredTrainingSession. Er verwendet Sitzungs-Hooks, um diese zu verarbeiten.


Die Verwendung von tf.train.Supervisor übernimmt die Erstellung einer solchen Sitzung für Sie und bietet eine umfassendere Lösung.
Mark

1
@ Mark tf.train.Supervisor ist veraltet
Changming Sun

Haben Sie einen Link, der die Behauptung unterstützt, dass Supervisor veraltet ist? Ich habe nichts gesehen, was darauf hindeutet, dass dies der Fall ist.
Mark


Vielen Dank für die URL. Ich habe die ursprüngliche Informationsquelle überprüft und erfahren, dass sie wahrscheinlich bis zum Ende der TF 1.x-Serie verfügbar sein wird, aber danach keine Garantie mehr.
Mark

8

Alle Antworten hier sind großartig, aber ich möchte zwei Dinge hinzufügen.

Um die Antwort von @ user7505159 näher zu erläutern, kann es wichtig sein, das "./" am Anfang des Dateinamens hinzuzufügen, den Sie wiederherstellen.

Sie können beispielsweise ein Diagramm ohne "./" im Dateinamen wie folgt speichern:

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

Um das Diagramm wiederherzustellen, müssen Sie dem Dateinamen möglicherweise ein "./" voranstellen:

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

Sie benötigen nicht immer das "./", es kann jedoch je nach Umgebung und Version von TensorFlow Probleme verursachen.

Es möchte auch erwähnt werden, dass sess.run(tf.global_variables_initializer())dies wichtig sein kann, bevor die Sitzung wiederhergestellt wird.

Wenn beim Versuch, eine gespeicherte Sitzung wiederherzustellen, eine Fehlermeldung bezüglich nicht initialisierter Variablen angezeigt wird, stellen Sie sicher, dass Sie diese sess.run(tf.global_variables_initializer())vor der saver.restore(sess, save_file)Zeile einfügen. Es kann Ihnen Kopfschmerzen ersparen.


7

Wie in Ausgabe 6255 beschrieben :

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

anstatt

saver.restore('my_model_final.ckpt')

7

Laut der neuen Tensorflow-Version tf.train.Checkpointist dies die bevorzugte Methode zum Speichern und Wiederherstellen eines Modells:

Checkpoint.saveund Checkpoint.restoreobjektbasierte Prüfpunkte schreiben und lesen, im Gegensatz zu tf.train.Saver, der auf variablen Namen basierende Prüfpunkte schreibt und liest. Objektbasiertes Checkpointing speichert ein Diagramm der Abhängigkeiten zwischen Python-Objekten (Ebenen, Optimierer, Variablen usw.) mit benannten Kanten. Dieses Diagramm wird verwendet, um Variablen beim Wiederherstellen eines Checkpoints abzugleichen. Es kann robuster gegenüber Änderungen im Python-Programm sein und unterstützt die Wiederherstellung beim Erstellen von Variablen, wenn diese eifrig ausgeführt werden. Bevorzugen tf.train.CheckpointSie tf.train.Saverneuen Code .

Hier ist ein Beispiel:

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)

Weitere Informationen und Beispiele hier.


7

Für Tensorflow 2.0 ist es so einfach wie

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

Etwas wiederherstellen:

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

Was ist mit all den benutzerdefinierten tf-Operationen und -Variablen, die nicht Teil des Modellobjekts sind? Werden sie irgendwie gespeichert, wenn Sie save () für das Modell aufrufen? Ich habe verschiedene benutzerdefinierte Verlust- und Tensorflow-Wahrscheinlichkeitsausdrücke, die im Inferenz- und Generierungsnetzwerk verwendet werden, aber sie sind nicht Teil meines Modells. Mein Keras-Modellobjekt enthält nur die dichten und konv-Schichten. In TF 1 habe ich gerade die Speichermethode aufgerufen und konnte sicher sein, dass alle in meinem Diagramm verwendeten Operationen und Tensoren gespeichert werden. In TF2 sehe ich nicht, wie die Operationen, die nicht irgendwie zum Keras-Modell hinzugefügt wurden, gespeichert werden.
Kristof

Gibt es weitere Informationen zum Wiederherstellen von Modellen in TF 2.0? Ich kann keine Gewichte aus Prüfpunktdateien wiederherstellen, die über die API generiert wurden, siehe: stackoverflow.com/questions/57944786/…
jregalad


5

tf.keras Modell speichern mit TF2.0

Ich sehe gute Antworten zum Speichern von Modellen mit TF1.x. Ich möchte ein paar weitere Hinweise zum Speichern von tensorflow.kerasModellen geben, was etwas kompliziert ist, da es viele Möglichkeiten gibt, ein Modell zu speichern.

Hier gebe ich ein Beispiel für das Speichern eines tensorflow.kerasModells in einem model_pathOrdner im aktuellen Verzeichnis. Dies funktioniert gut mit dem neuesten Tensorflow (TF2.0). Ich werde diese Beschreibung aktualisieren, wenn sich in naher Zukunft etwas ändert.

Speichern und Laden des gesamten Modells

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

Modell speichern und laden Nur Gewichte

Wenn Sie nur Modellgewichte speichern und dann Gewichte laden möchten, um das Modell wiederherzustellen, dann

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

Speichern und Wiederherstellen mit Keras Checkpoint Callback

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

Modell mit benutzerdefinierten Metriken speichern

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

Speichern des Keras-Modells mit benutzerdefinierten Operationen

Wenn wir benutzerdefinierte Operationen wie im folgenden Fall ( tf.tile) haben, müssen wir eine Funktion erstellen und mit einer Lambda-Ebene umbrechen. Andernfalls kann das Modell nicht gespeichert werden.

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

Ich glaube, ich habe einige der vielen Möglichkeiten zum Speichern des tf.keras-Modells behandelt. Es gibt jedoch viele andere Möglichkeiten. Bitte kommentieren Sie unten, wenn Sie sehen, dass Ihr Anwendungsfall oben nicht behandelt wird. Vielen Dank!


3

Verwenden Sie tf.train.Saver, um ein Modell zu speichern. Remerber, Sie müssen die var_list angeben, wenn Sie die Modellgröße reduzieren möchten. Die val_list kann tf.trainable_variables oder tf.global_variables sein.


3

Sie können die Variablen im Netzwerk mit speichern

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

Um Wiederherstellung des Netzes für die Wiederverwendung später oder in einem anderen Skript verwenden:

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

Wichtige Punkte:

  1. sess muss zwischen erstem und späterem Lauf gleich sein (kohärente Struktur).
  2. saver.restore benötigt den Pfad des Ordners der gespeicherten Dateien, keinen einzelnen Dateipfad.

2

Wo immer Sie das Modell speichern möchten,

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

Stellen Sie sicher, dass alle Ihre tf.VariableNamen haben, da Sie sie möglicherweise später unter Verwendung ihrer Namen wiederherstellen möchten. Und wo Sie vorhersagen wollen,

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

Stellen Sie sicher, dass der Sparer in der entsprechenden Sitzung ausgeführt wird. Denken Sie daran, dass bei Verwendung von tf.train.latest_checkpoint('./')nur der neueste Kontrollpunkt verwendet wird.


2

Ich bin auf Version:

tensorflow (1.13.1)
tensorflow-gpu (1.13.1)

Einfacher Weg ist

Speichern:

model.save("model.h5")

Wiederherstellen:

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

2

Für Tensorflow-2.0

es ist sehr einfach.

import tensorflow as tf

SPEICHERN

model.save("model_name")

WIEDERHERSTELLEN

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

1

Nach der Antwort von @Vishnuvardhan Janapati gibt es eine weitere Möglichkeit, ein Modell mit benutzerdefinierten Ebenen / Metriken / Verlusten unter TensorFlow 2.0.0 zu speichern und neu zu laden

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

Auf diese Weise können Sie, sobald Sie solche Codes ausgeführt und Ihr Modell mit tf.keras.models.save_modeloder model.saveoder ModelCheckpointRückruf gespeichert haben, Ihr Modell erneut laden, ohne präzise benutzerdefinierte Objekte zu benötigen

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

0

In der neuen Version von Tensorflow 2.0 ist das Speichern / Laden eines Modells viel einfacher. Aufgrund der Implementierung der Keras-API, einer übergeordneten API für TensorFlow.

So speichern Sie ein Modell: Überprüfen Sie die Dokumentation als Referenz: 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)

So laden Sie ein Modell:

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

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

0

Hier ist ein einfaches Beispiel für die Verwendung des Tensorflow 2.0 SavedModel- Formats (das laut Dokumentation das empfohlene Format ist ) für einen einfachen MNIST-Dataset-Klassifikator, bei dem die Keras-Funktions-API verwendet wird, ohne dass zu viel Lust darauf besteht:

# 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

Was ist serving_default?

Dies ist der Name der Signatur def des von Ihnen ausgewählten Tags (in diesem Fall wurde das Standard- serveTag ausgewählt). Außerdem wird hier erläutert, wie Sie die Tags und Signaturen eines Modells mithilfe von finden saved_model_cli.

Haftungsausschluss

Dies ist nur ein einfaches Beispiel, wenn Sie es nur zum Laufen bringen möchten, aber es ist keineswegs eine vollständige Antwort - vielleicht kann ich es in Zukunft aktualisieren. Ich wollte nur ein einfaches Beispiel mit dem gebenSavedModel in TF 2.0 geben, weil ich nirgendwo eines gesehen habe, auch nicht so einfach.

@ Toms Antwort ist ein SavedModel-Beispiel, aber es funktioniert nicht mit Tensorflow 2.0, da es leider einige wichtige Änderungen gibt.

@ Vishnuvardhan Janapatis Antwort lautet TF 2.0, aber nicht für das SavedModel-Format.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.