Nachdem Sie ein Modell in Tensorflow trainiert haben:
- Wie speichern Sie das trainierte Modell?
- Wie können Sie dieses gespeicherte Modell später wiederherstellen?
Nachdem Sie ein Modell in Tensorflow trainiert haben:
Antworten:
ausführliches und nützliches Tutorial -> https://www.tensorflow.org/guide/saved_model
Keras ausführliche Anleitung zum Speichern von Modellen -> https://www.tensorflow.org/guide/keras/save_and_serialize
Aus den Dokumenten:
# Create some variables.
v1 = tf.get_variable("v1", shape=[3], initializer = tf.zeros_initializer)
v2 = tf.get_variable("v2", shape=[5], initializer = tf.zeros_initializer)
inc_v1 = v1.assign(v1+1)
dec_v2 = v2.assign(v2-1)
# Add an op to initialize the variables.
init_op = tf.global_variables_initializer()
# Add ops to save and restore all the variables.
saver = tf.train.Saver()
# Later, launch the model, initialize the variables, do some work, and save the
# variables to disk.
with tf.Session() as sess:
sess.run(init_op)
# Do some work with the model.
inc_v1.op.run()
dec_v2.op.run()
# Save the variables to disk.
save_path = saver.save(sess, "/tmp/model.ckpt")
print("Model saved in path: %s" % save_path)
tf.reset_default_graph()
# Create some variables.
v1 = tf.get_variable("v1", shape=[3])
v2 = tf.get_variable("v2", shape=[5])
# Add ops to save and restore all the variables.
saver = tf.train.Saver()
# Later, launch the model, use the saver to restore variables from disk, and
# do some work with the model.
with tf.Session() as sess:
# Restore variables from disk.
saver.restore(sess, "/tmp/model.ckpt")
print("Model restored.")
# Check the values of the variables
print("v1 : %s" % v1.eval())
print("v2 : %s" % v2.eval())
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_model
Gebrauchsanweisung
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.Dataset
API.
Python 3; Tensorflow 1.14
import tensorflow as tf
from tensorflow.saved_model import tag_constants
with tf.Graph().as_default():
with tf.Session() as sess:
...
# Saving
inputs = {
"batch_size_placeholder": batch_size_placeholder,
"features_placeholder": features_placeholder,
"labels_placeholder": labels_placeholder,
}
outputs = {"prediction": model_output}
tf.saved_model.simple_save(
sess, 'path/to/your/location/', inputs, outputs
)
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
})
Der folgende Code generiert zur Demonstration zufällige Daten.
Dataset
und dann sein Iterator
. Wir erhalten den vom Iterator erzeugten Tensor, genanntinput_tensor
der als Eingabe für unser Modell dient.input_tensor
: einem GRU-basierten bidirektionalen RNN, gefolgt von einem dichten Klassifikator. Weil warum nicht.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 .tf.saved_model.loader.load
. Wir greifen die Platzhalter und Logs mit graph.get_tensor_by_name
und den Iterator
Initialisierungsvorgang mit graph.get_operation_by_name
.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
tf.contrib.layers
?
[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
global_step
ein 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
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
:0
sie den Namen hinzu?
In (und nach) TensorFlow Version 0.11.0RC1 können Sie Ihr Modell direkt durch den Aufruf speichern und wiederherzustellen tf.train.export_meta_graph
und tf.train.import_meta_graph
nach https://www.tensorflow.org/programmers_guide/meta_graph .
w1 = tf.Variable(tf.truncated_normal(shape=[10]), name='w1')
w2 = tf.Variable(tf.truncated_normal(shape=[20]), name='w2')
tf.add_to_collection('vars', w1)
tf.add_to_collection('vars', w2)
saver = tf.train.Saver()
sess = tf.Session()
sess.run(tf.global_variables_initializer())
saver.save(sess, 'my-model')
# `save` method will call `export_meta_graph` implicitly.
# you will get saved graph files:my-model.meta
sess = tf.Session()
new_saver = tf.train.import_meta_graph('my-model.meta')
new_saver.restore(sess, tf.train.latest_checkpoint('./'))
all_vars = tf.get_collection('vars')
for v in all_vars:
v_ = sess.run(v)
print(v_)
<built-in function TF_Run> returned a result with an error set
tf.get_variable_scope().reuse_variables()
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?
Für TensorFlow-Version <0.11.0RC1:
Die gespeicherten Prüfpunkte enthalten Werte für die Variable
s 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 Variable
s, die das Speichern und Wiederherstellen abdecken. Und hier sind die Dokumente für die Saver
.
batch_x
sein? Binär? Numpy Array?
undefined
. Können Sie mir sagen, welche FLAGS für diesen Code def ist? @ RyanSepassi
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 .ckpt
von 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_model
eines 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})
Das Modell besteht aus zwei Teilen: der Modelldefinition, die Supervisor
wie graph.pbtxt
im 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 Saver
eine 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 Saver
die 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
)
Sie können diesen Weg auch einfacher nehmen.
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, .....
Saver
und speichern Sie siemodel_saver = tf.train.Saver()
# Train the model and save it in the end
model_saver.save(session, "saved_models/CNN_New.ckpt")
with tf.Session(graph=graph_cnn) as session:
model_saver.restore(session, "saved_models/CNN_New.ckpt")
print("Model restored.")
print('Initialized')
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)
In den meisten Fällen ist das Speichern und Wiederherstellen von der Festplatte mit a tf.train.Saver
die 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 Saver
speichert das die Diagrammstruktur in einer .meta
Datei. 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_dict
und 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.
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.)
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
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).
graph = ... # build the graph
saver = tf.train.Saver() # create the saver after the graph
with ... as sess: # your session object
saver.save(sess, 'my-model')
graph = ... # build the graph
saver = tf.train.Saver() # create the saver after the graph
with ... as sess: # your session object
saver.restore(sess, tf.train.latest_checkpoint('./'))
# now you can use the graph, continue training or whatever
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.
graph = ... # build the graph
for op in [ ... ]: # operators you want to use after restoring the model
tf.add_to_collection('ops_to_restore', op)
saver = tf.train.Saver() # create the saver after the graph
with ... as sess: # your session object
saver.save(sess, 'my-model')
with ... as sess: # your session object
saver = tf.train.import_meta_graph('my-model.meta')
saver.restore(sess, tf.train.latest_checkpoint('./'))
ops = tf.get_collection('ops_to_restore') # here are your operators in the same order in which you saved them to the collection
global_step
Variablen 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 ...: /
Sie können sich auch Beispiele in TensorFlow / skflow ansehen , das Angebote save
und restore
Methoden 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.
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.
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.
Wie in Ausgabe 6255 beschrieben :
use '**./**model_name.ckpt'
saver.restore(sess,'./my_model_final.ckpt')
anstatt
saver.restore('my_model_final.ckpt')
Laut der neuen Tensorflow-Version tf.train.Checkpoint
ist dies die bevorzugte Methode zum Speichern und Wiederherstellen eines Modells:
Checkpoint.save
undCheckpoint.restore
objektbasierte 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. Bevorzugentf.train.Checkpoint
Sietf.train.Saver
neuen 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)
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')
TF2.0
Ich sehe gute Antworten zum Speichern von Modellen mit TF1.x. Ich möchte ein paar weitere Hinweise zum Speichern von tensorflow.keras
Modellen 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.keras
Modells in einem model_path
Ordner im aktuellen Verzeichnis. Dies funktioniert gut mit dem neuesten Tensorflow (TF2.0). Ich werde diese Beschreibung aktualisieren, wenn sich in naher Zukunft etwas ändert.
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))
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))
# include the epoch in the file name. (uses `str.format`)
checkpoint_path = "training_2/cp-{epoch:04d}.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)
cp_callback = tf.keras.callbacks.ModelCheckpoint(
checkpoint_path, verbose=1, save_weights_only=True,
# Save weights, every 5-epochs.
period=5)
model = create_model()
model.save_weights(checkpoint_path.format(epoch=0))
model.fit(train_images, train_labels,
epochs = 50, callbacks = [cp_callback],
validation_data = (test_images,test_labels),
verbose=0)
latest = tf.train.latest_checkpoint(checkpoint_dir)
new_model = create_model()
new_model.load_weights(latest)
loss, acc = new_model.evaluate(test_images, test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))
import tensorflow as tf
from tensorflow import keras
mnist = tf.keras.datasets.mnist
(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
# Custom Loss1 (for example)
@tf.function()
def customLoss1(yTrue,yPred):
return tf.reduce_mean(yTrue-yPred)
# Custom Loss2 (for example)
@tf.function()
def customLoss2(yTrue, yPred):
return tf.reduce_mean(tf.square(tf.subtract(yTrue,yPred)))
def create_model():
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(512, activation=tf.nn.relu),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy', customLoss1, customLoss2])
return model
# Create a basic model instance
model=create_model()
# Fit and evaluate model
model.fit(x_train, y_train, epochs=1)
loss, acc,loss1, loss2 = model.evaluate(x_test, y_test,verbose=1)
print("Original model, accuracy: {:5.2f}%".format(100*acc))
model.save("./model.h5")
new_model=tf.keras.models.load_model("./model.h5",custom_objects={'customLoss1':customLoss1,'customLoss2':customLoss2})
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!
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:
sess
muss zwischen erstem und späterem Lauf gleich sein (kohärente Struktur). saver.restore
benötigt den Pfad des Ordners der gespeicherten Dateien, keinen einzelnen Dateipfad. 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.Variable
Namen 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.
Für Tensorflow-2.0
es ist sehr einfach.
import tensorflow as tf
model.save("model_name")
model = tf.keras.models.load_model('model_name')
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_model
oder model.save
oder ModelCheckpoint
Rückruf gespeichert haben, Ihr Modell erneut laden, ohne präzise benutzerdefinierte Objekte zu benötigen
new_model = tf.keras.models.load_model("./model.h5"})
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)
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- serve
Tag 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.