Setelah Anda melatih model di Tensorflow:
- Bagaimana Anda menyimpan model yang terlatih?
- Bagaimana nanti Anda mengembalikan model yang disimpan ini?
Setelah Anda melatih model di Tensorflow:
Jawaban:
tutorial lengkap dan bermanfaat -> https://www.tensorflow.org/guide/saved_model
Panduan terperinci yang keras untuk menyimpan model -> https://www.tensorflow.org/guide/keras/save_and_serialize
Dari dokumen:
# 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())
Ini masih beta jadi saya sarankan untuk saat ini. Jika Anda masih ingin menyusuri jalan itu di sini adalah tf.saved_model
panduan penggunaan
simple_save
Banyak jawaban bagus, untuk kelengkapan saya akan menambahkan 2 sen: simple_save . Juga contoh kode mandiri menggunakan 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
)
Memulihkan:
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
})
Kode berikut menghasilkan data acak untuk kepentingan demonstrasi.
Dataset
dan kemudian nya Iterator
. Kami mendapatkan tensor yang dihasilkan iterator, yang disebut input_tensor
yang akan berfungsi sebagai input untuk model kami.input_tensor
: RNN dua arah berbasis GRU diikuti oleh classifier padat. Karena mengapa tidak.softmax_cross_entropy_with_logits
, dioptimalkan dengan Adam
. Setelah 2 zaman (masing-masing 2 batch), kami menyimpan model "terlatih" dengan tf.saved_model.simple_save
. Jika Anda menjalankan kode apa adanya, maka model akan disimpan dalam folder yang disebut simple/
di direktori kerja Anda saat ini.tf.saved_model.loader.load
. Kami mengambil tempat penampung dan log dengan graph.get_tensor_by_name
dan Iterator
operasi inisialisasi dengan graph.get_operation_by_name
.Kode:
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)
Ini akan mencetak:
$ 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]
. Seperti yang dikatakan dalam dokumentasi, simpanan sederhana bertujuan menyederhanakan interaksi dengan tensorflow serve, inilah poin dari argumen; Namun variabel lain masih dipulihkan, jika tidak kesimpulan tidak akan terjadi. Ambil saja variabel minat Anda seperti yang saya lakukan dalam contoh. Lihatlah dokumentasi
global_step
sebagai argumen, jika Anda berhenti kemudian mencoba mengambil pelatihan lagi, itu akan berpikir Anda satu langkah satu. Paling tidak itu akan mengacaukan visualisasi papan tensor Anda
Saya meningkatkan jawaban saya untuk menambahkan lebih banyak detail untuk menyimpan dan memulihkan model.
Dalam (dan setelah) Tensorflow versi 0.11 :
Simpan model:
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)
Pulihkan model:
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
Ini dan beberapa use case yang lebih maju telah dijelaskan dengan sangat baik di sini.
Tutorial lengkap cepat untuk menyimpan dan mengembalikan model Tensorflow
:0
nama?
Di (dan setelah) TensorFlow versi 0.11.0RC1, Anda dapat menyimpan dan memulihkan model Anda secara langsung dengan menelepon tf.train.export_meta_graph
dan tf.train.import_meta_graph
sesuai dengan 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()
diikuti oleh var = tf.get_variable("varname")
. Ini memberi saya kesalahan: "ValueError: Variabel varname tidak ada, atau tidak dibuat dengan tf.get_variable ()." Mengapa? Haruskah ini tidak mungkin?
Untuk versi TensorFlow <0.11.0RC1:
Pos pemeriksaan yang disimpan berisi nilai untuk Variable
s dalam model Anda, bukan model / grafik itu sendiri, yang berarti bahwa grafik harus sama ketika Anda mengembalikan pos pemeriksaan.
Berikut adalah contoh untuk regresi linier di mana ada loop pelatihan yang menyimpan pos pemeriksaan variabel dan bagian evaluasi yang akan mengembalikan variabel yang disimpan dalam jangka sebelumnya dan menghitung prediksi. Tentu saja, Anda juga dapat memulihkan variabel dan melanjutkan pelatihan jika Anda mau.
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})
Berikut adalah dokumen untuk Variable
s, yang mencakup penyimpanan dan pemulihan. Dan di sini adalah dokumen untuk Saver
.
batch_x
perlu? Biner? Array numpy?
undefined
. Bisakah Anda memberi tahu saya yang merupakan kekurangan BENDERA untuk kode ini. @RyanSepassi
Lingkungan saya: Python 3.6, Tensorflow 1.3.0
Meskipun ada banyak solusi, sebagian besar didasarkan pada tf.train.Saver
. Ketika kami memuat .ckpt
diselamatkan oleh Saver
, kita harus baik mendefinisikan jaringan tensorflow atau menggunakan beberapa nama yang aneh dan sulit diingat, misalnya 'placehold_0:0'
, 'dense/Adam/Weight:0'
. Di sini saya sarankan untuk menggunakan tf.saved_model
, salah satu contoh paling sederhana yang diberikan di bawah ini, Anda dapat belajar lebih banyak dari Melayani Model TensorFlow :
Simpan model:
import tensorflow as tf
# define the tensorflow network and do some trains
x = tf.placeholder("float", name="x")
w = tf.Variable(2.0, name="w")
b = tf.Variable(0.0, name="bias")
h = tf.multiply(x, w)
y = tf.add(h, b, name="y")
sess = tf.Session()
sess.run(tf.global_variables_initializer())
# save the model
export_path = './savedmodel'
builder = tf.saved_model.builder.SavedModelBuilder(export_path)
tensor_info_x = tf.saved_model.utils.build_tensor_info(x)
tensor_info_y = tf.saved_model.utils.build_tensor_info(y)
prediction_signature = (
tf.saved_model.signature_def_utils.build_signature_def(
inputs={'x_input': tensor_info_x},
outputs={'y_output': tensor_info_y},
method_name=tf.saved_model.signature_constants.PREDICT_METHOD_NAME))
builder.add_meta_graph_and_variables(
sess, [tf.saved_model.tag_constants.SERVING],
signature_def_map={
tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY:
prediction_signature
},
)
builder.save()
Muat model:
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})
Ada dua bagian dari model, definisi model, disimpan oleh Supervisor
seperti graph.pbtxt
dalam direktori model dan nilai numerik dari tensor, disimpan ke dalam file pos pemeriksaan sepertimodel.ckpt-1003418
.
Definisi model dapat dipulihkan dengan menggunakan tf.import_graph_def
, dan bobot dipulihkan dengan menggunakanSaver
.
Namun, Saver
gunakan daftar koleksi khusus variabel yang terlampir pada model Graph, dan koleksi ini tidak diinisialisasi menggunakan import_graph_def, jadi Anda tidak dapat menggunakan keduanya bersamaan saat ini (ada di peta jalan kami untuk memperbaikinya). Untuk saat ini, Anda harus menggunakan pendekatan Ryan Sepassi - secara manual membuat grafik dengan nama simpul yang identik, dan gunakan Saver
untuk memuat bobot ke dalamnya.
(Atau Anda dapat meretasnya dengan menggunakan import_graph_def
, menggunakan , membuat variabel secara manual, dan menggunakan tf.add_to_collection(tf.GraphKeys.VARIABLES, variable)
untuk setiap variabel, lalu menggunakan Saver
)
Anda juga dapat mengambil cara yang lebih mudah ini.
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
dan simpanmodel_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)
Saat berjalan dalam instance python yang berbeda, gunakan
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)
Dalam kebanyakan kasus, menyimpan dan memulihkan dari disk menggunakan tf.train.Saver
opsi terbaik Anda:
... # 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
Anda juga dapat menyimpan / mengembalikan struktur grafik itu sendiri (lihat dokumentasi MetaGraph untuk detailnya). Secara default, Saver
menyimpan struktur grafik ke dalam .meta
file. Anda dapat menelepon import_meta_graph()
untuk mengembalikannya. Ini mengembalikan struktur grafik dan mengembalikan Saver
yang dapat Anda gunakan untuk mengembalikan keadaan model:
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
Namun, ada beberapa kasus di mana Anda membutuhkan sesuatu yang lebih cepat. Misalnya, jika Anda menerapkan penghentian awal, Anda ingin menyimpan pos-pos pemeriksaan setiap kali model meningkat selama pelatihan (sebagaimana diukur pada set validasi), maka jika tidak ada kemajuan untuk beberapa waktu, Anda ingin kembali ke model terbaik. Jika Anda menyimpan model ke disk setiap kali itu membaik, itu akan sangat memperlambat pelatihan. Caranya adalah dengan menyimpan status variabel memori , lalu kembalikan saja nanti:
... # 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)
Penjelasan cepat: ketika Anda membuat variabel X
, TensorFlow secara otomatis membuat operasi penugasan X/Assign
untuk mengatur nilai awal variabel. Alih-alih membuat placeholder dan op penugasan tambahan (yang hanya akan membuat grafik berantakan), kami hanya menggunakan op penugasan yang ada ini. Input pertama dari setiap op penugasan adalah referensi ke variabel yang seharusnya diinisialisasi, dan input kedua ( assign_op.inputs[1]
) adalah nilai awal. Jadi untuk menetapkan nilai apa pun yang kita inginkan (alih-alih nilai awal), kita perlu menggunakan feed_dict
dan mengganti nilai awal. Ya, TensorFlow memungkinkan Anda memberi nilai untuk op apa pun, tidak hanya untuk placeholder, jadi ini berfungsi dengan baik.
Seperti yang dikatakan Yaroslav, Anda dapat meretas pemulihan dari graph_def dan pos pemeriksaan dengan mengimpor grafik, secara manual membuat variabel, dan kemudian menggunakan Saver.
Saya menerapkan ini untuk penggunaan pribadi saya, jadi saya pikir saya akan membagikan kode di sini.
Tautan: https://gist.github.com/nikitakit/6ef3b72be67b86cb7868
(Ini, tentu saja, peretasan, dan tidak ada jaminan bahwa model yang disimpan dengan cara ini akan tetap dapat dibaca di versi TensorFlow yang akan datang.)
Jika ini adalah model yang disimpan secara internal, Anda cukup menentukan pemulih semua variabel sebagai
restorer = tf.train.Saver(tf.all_variables())
dan menggunakannya untuk mengembalikan variabel dalam sesi saat ini:
restorer.restore(self._sess, model_file)
Untuk model eksternal, Anda perlu menentukan pemetaan dari nama variabelnya ke nama variabel Anda. Anda dapat melihat nama variabel model menggunakan perintah
python /path/to/tensorflow/tensorflow/python/tools/inspect_checkpoint.py --file_name=/path/to/pretrained_model/model.ckpt
Skrip inspect_checkpoint.py dapat ditemukan di folder './tensorflow/python/tools' dari sumber Tensorflow.
Untuk menentukan pemetaan, Anda dapat menggunakan Tensorflow-Worklab saya , yang berisi sekumpulan kelas dan skrip untuk melatih dan melatih kembali berbagai model. Ini termasuk contoh pelatihan ulang model ResNet, yang terletak di sini
all_variables()
sekarang tidak digunakan lagi
Inilah solusi sederhana saya untuk dua kasus dasar berbeda pada apakah Anda ingin memuat grafik dari file atau membangunnya selama runtime.
Jawaban ini berlaku untuk Tensorflow 0.12+ (termasuk 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
Saat menggunakan teknik ini, pastikan semua layer / variabel Anda secara eksplisit menetapkan nama unik.Kalau tidak, Tensorflow akan membuat nama-nama itu sendiri unik dan dengan demikian mereka akan berbeda dari nama-nama yang tersimpan dalam file. Ini bukan masalah dalam teknik sebelumnya, karena nama-nama "hancur" dengan cara yang sama dalam memuat dan menyimpan.
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
variabel dan rata-rata bergerak normalisasi batch adalah variabel yang tidak dapat dilatihkan, tetapi keduanya jelas layak untuk dihemat. Selain itu, Anda harus lebih jelas membedakan konstruksi grafik dari menjalankan sesi, misalnya Saver(...).save()
akan membuat node baru setiap kali Anda menjalankannya. Mungkin bukan yang Anda inginkan. Dan masih ada lagi ...: /
Anda juga dapat melihat contoh di TensorFlow / skflow , yang menawarkan save
dan restore
metode yang dapat membantu Anda mengelola model dengan mudah. Ini memiliki parameter yang Anda juga dapat mengontrol seberapa sering Anda ingin membuat cadangan model Anda.
Jika Anda menggunakan tf.train.MonitoredTrainingSession sebagai sesi default, Anda tidak perlu menambahkan kode tambahan untuk melakukan save / restore. Cukup berikan nama dir pos pemeriksaan ke konstruktor MonitoredTrainingSession, itu akan menggunakan kait sesi untuk menangani ini.
Semua jawaban di sini luar biasa, tetapi saya ingin menambahkan dua hal.
Pertama, untuk menguraikan jawaban @ user7505159, "./" bisa penting untuk ditambahkan ke awal nama file yang Anda pulihkan.
Misalnya, Anda dapat menyimpan grafik tanpa "./" di nama file seperti:
# 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)
Tetapi untuk mengembalikan grafik, Anda mungkin perlu menambahkan "./" ke nama file:
# 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)
Anda tidak akan selalu membutuhkan "./", tetapi dapat menyebabkan masalah tergantung pada lingkungan dan versi TensorFlow Anda.
Juga ingin menyebutkan bahwa ini sess.run(tf.global_variables_initializer())
bisa menjadi penting sebelum mengembalikan sesi.
Jika Anda menerima kesalahan terkait variabel yang tidak diinisialisasi saat mencoba memulihkan sesi yang disimpan, pastikan Anda memasukkan sess.run(tf.global_variables_initializer())
sebelum saver.restore(sess, save_file)
baris. Ini bisa menyelamatkan Anda dari sakit kepala.
Menurut versi Tensorflow baru, tf.train.Checkpoint
adalah cara yang lebih disukai untuk menyimpan dan memulihkan model:
Checkpoint.save
danCheckpoint.restore
menulis dan membaca pos pemeriksaan berbasis objek, berbeda dengan tf.train.Saver yang menulis dan membaca pos pemeriksaan berdasarkan variabel.name. Checkpointing berbasis objek menyimpan grafik dependensi antara objek Python (Layers, Optimizer, Variables, dll.) Dengan tepi bernama, dan grafik ini digunakan untuk mencocokkan variabel ketika mengembalikan pos pemeriksaan. Itu bisa lebih kuat untuk perubahan dalam program Python, dan membantu untuk mendukung restore-on-create untuk variabel ketika mengeksekusi dengan penuh semangat. Lebih memilihtf.train.Checkpoint
lebihtf.train.Saver
untuk kode baru .
Berikut ini sebuah contoh:
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)
Untuk tensorflow 2.0 , sesederhana
# Save the model model.save('path_to_my_model.h5')
Untuk memulihkan:
new_model = tensorflow.keras.models.load_model('path_to_my_model.h5')
TF2.0
Saya melihat jawaban yang bagus untuk menyimpan model menggunakan TF1.x. Saya ingin memberikan beberapa petunjuk lebih banyak dalam menyimpan tensorflow.keras
model yang sedikit rumit karena ada banyak cara untuk menyimpan model.
Di sini saya memberikan contoh menyimpan tensorflow.keras
model ke model_path
folder di bawah direktori saat ini. Ini bekerja dengan baik dengan tensorflow terbaru (TF2.0). Saya akan memperbarui deskripsi ini jika ada perubahan dalam waktu dekat.
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))
Jika Anda tertarik untuk menyimpan hanya bobot model dan kemudian memuat bobot untuk memulihkan model, maka
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})
Ketika kita memiliki ops kustom seperti dalam case berikut ( tf.tile
), kita perlu membuat fungsi dan membungkus dengan layer Lambda. Jika tidak, model tidak dapat disimpan.
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")
Saya pikir saya telah membahas beberapa cara menghemat model tf.keras. Namun, ada banyak cara lain. Berikan komentar di bawah ini jika Anda melihat kasus penggunaan Anda tidak tercakup di atas. Terima kasih!
Anda dapat menyimpan variabel dalam jaringan menggunakan
saver = tf.train.Saver()
saver.save(sess, 'path of save/fileName.ckpt')
Untuk memulihkan jaringan untuk digunakan kembali nanti atau dalam skrip lain, gunakan:
saver = tf.train.Saver()
saver.restore(sess, tf.train.latest_checkpoint('path of save/')
sess.run(....)
Poin-poin penting:
sess
harus sama antara pertama dan kemudian dijalankan (struktur yang koheren). saver.restore
membutuhkan jalur folder dari file yang disimpan, bukan jalur file individual. Di mana pun Anda ingin menyimpan model,
self.saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
...
self.saver.save(sess, filename)
Pastikan, semua Anda tf.Variable
memiliki nama, karena Anda mungkin ingin mengembalikannya nanti menggunakan nama mereka. Dan di mana Anda ingin memprediksi,
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
Pastikan saver berjalan di dalam sesi yang sesuai. Ingat bahwa, jika Anda menggunakan tf.train.latest_checkpoint('./')
, maka hanya titik pemeriksaan terbaru yang akan digunakan.
Saya di Versi:
tensorflow (1.13.1)
tensorflow-gpu (1.13.1)
Cara sederhana adalah
Menyimpan:
model.save("model.h5")
Mengembalikan:
model = tf.keras.models.load_model("model.h5")
Untuk tensorflow-2.0
ini sangat sederhana.
import tensorflow as tf
model.save("model_name")
model = tf.keras.models.load_model('model_name')
Mengikuti jawaban @Vishnuvardhan Janapati, berikut adalah cara lain untuk menyimpan dan memuat kembali model dengan lapisan kustom / metrik / kerugian di bawah TensorFlow 2.0.0
import tensorflow as tf
from tensorflow.keras.layers import Layer
from tensorflow.keras.utils.generic_utils import get_custom_objects
# custom loss (for example)
def custom_loss(y_true,y_pred):
return tf.reduce_mean(y_true - y_pred)
get_custom_objects().update({'custom_loss': custom_loss})
# custom loss (for example)
class CustomLayer(Layer):
def __init__(self, ...):
...
# define custom layer and all necessary custom operations inside custom layer
get_custom_objects().update({'CustomLayer': CustomLayer})
Dengan cara ini, setelah Anda mengeksekusi kode tersebut, dan menyimpan model Anda dengan tf.keras.models.save_model
atau model.save
atau ModelCheckpoint
callback, Anda dapat memuat ulang model Anda tanpa perlu objek khusus yang tepat, sesederhana
new_model = tf.keras.models.load_model("./model.h5"})
Dalam versi baru tensorflow 2.0, proses menyimpan / memuat model jauh lebih mudah. Karena Implementasi Keras API, API tingkat tinggi untuk TensorFlow.
Untuk menyimpan model: Periksa dokumentasi untuk referensi: 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)
Untuk memuat model:
https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/keras/models/load_model
model = tf.keras.models.load_model(filepath)
Berikut ini adalah contoh sederhana menggunakan format Tensorflow 2.0 SavedModel (yang merupakan format yang disarankan, menurut dokumen ) untuk pengklasifikasi dataset MNIST sederhana, menggunakan API fungsional Keras tanpa terlalu banyak suka terjadi:
# 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
Apa serving_default
?
Ini nama def tanda tangan dari tag yang Anda pilih (dalam hal ini, serve
tag default dipilih) Juga, di sini dijelaskan cara menemukan tag dan tanda tangan model yang digunakan saved_model_cli
.
Penafian
Ini hanya contoh dasar jika Anda hanya ingin menjalankannya, tetapi tidak berarti jawaban yang lengkap - mungkin saya dapat memperbaruinya di masa mendatang. Saya hanya ingin memberikan contoh sederhana menggunakanSavedModel
di TF 2.0 karena saya belum melihat satu, bahkan ini sederhana, di mana saja.
@ Tom menjawab adalah contoh SavedModel, tetapi itu tidak akan berfungsi pada Tensorflow 2.0, karena sayangnya ada beberapa perubahan yang melanggar.
@ Vishnuvardhan Janapati menjawab mengatakan TF 2.0, tetapi itu bukan untuk format SavedModel.