Sau khi bạn đào tạo một mô hình trong Tensorflow:
- Làm thế nào để bạn lưu mô hình được đào tạo?
- Làm thế nào để bạn sau đó khôi phục mô hình đã lưu này?
Sau khi bạn đào tạo một mô hình trong Tensorflow:
Câu trả lời:
hướng dẫn đầy đủ và hữu ích -> https://www.tensorflow.org/guide/satted_model
Hướng dẫn chi tiết về máy ảnh để lưu mô hình -> https://www.tensorflow.org/guide/keras/save_and_serialize
Từ các tài liệu:
# 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())
Đây vẫn là bản beta nên tôi khuyên bạn nên chống lại bây giờ. Nếu bạn vẫn muốn đi xuống con đường đó thì đây là tf.saved_model
hướng dẫn sử dụng
simple_save
Nhiều câu trả lời hay, để hoàn thiện tôi sẽ thêm 2 xu của mình: Simple_save . Cũng là một ví dụ mã độc lập sử dụng tf.data.Dataset
API.
Trăn 3; Dòng chảy 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
)
Khôi phục:
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
})
Đoạn mã sau tạo dữ liệu ngẫu nhiên vì mục đích trình diễn.
Dataset
và sau đó của nó Iterator
. Chúng tôi nhận được tenxơ được tạo của iterator, được gọi input_tensor
là đầu vào cho mô hình của chúng tôi.input_tensor
: RNN hai chiều dựa trên GRU, theo sau là phân loại dày đặc. Vì tại sao không.softmax_cross_entropy_with_logits
, tối ưu hóa với Adam
. Sau 2 epoch (mỗi đợt 2 đợt), chúng tôi lưu mô hình "được đào tạo" với tf.saved_model.simple_save
. Nếu bạn chạy mã như vậy, thì mô hình sẽ được lưu trong một thư mục có tên simple/
trong thư mục làm việc hiện tại của bạn.tf.saved_model.loader.load
. Chúng tôi lấy placeholders và logits với graph.get_tensor_by_name
và Iterator
hoạt động khởi tạo với graph.get_operation_by_name
.Mã số:
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)
Điều này sẽ in:
$ 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]
. Như tài liệu nói, lưu đơn giản nhằm mục đích đơn giản hóa sự tương tác với phục vụ tenorflow, đây là điểm của các đối số; tuy nhiên các biến khác vẫn được khôi phục, nếu không thì suy luận sẽ không xảy ra. Chỉ cần lấy các biến quan tâm của bạn như tôi đã làm trong ví dụ. Kiểm tra tài liệu
global_step
có tranh luận, nếu bạn dừng lại sau đó cố gắng tập luyện trở lại, nó sẽ nghĩ bạn là một bước một. Nó sẽ làm hỏng trực quan bảng căng của bạn ít nhất
Tôi đang cải thiện câu trả lời của mình để thêm chi tiết cho việc lưu và khôi phục các mô hình.
Trong (và sau) Phiên bản kéo căng 0.11 :
Lưu mô hình:
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)
Khôi phục mô hình:
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
Điều này và một số trường hợp sử dụng nâng cao hơn đã được giải thích rất tốt ở đây.
Một hướng dẫn đầy đủ nhanh chóng để lưu và khôi phục các mô hình Tensorflow
:0
vào tên?
Trong (và sau) TensorFlow phiên bản 0.11.0RC1, bạn có thể lưu và khôi phục mô hình của mình trực tiếp bằng cách gọi tf.train.export_meta_graph
và tf.train.import_meta_graph
theo 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()
theo sau var = tf.get_variable("varname")
. Điều này mang lại cho tôi lỗi: "ValueError: Biến tên biến không tồn tại hoặc không được tạo bằng tf.get_variable ()." Tại sao? Điều này có nên không thể?
Đối với phiên bản TensorFlow <0.11.0RC1:
Các điểm kiểm tra được lưu chứa các giá trị cho Variable
s trong mô hình của bạn, chứ không phải chính mô hình / biểu đồ, điều đó có nghĩa là biểu đồ sẽ giống nhau khi bạn khôi phục điểm kiểm tra.
Đây là một ví dụ cho hồi quy tuyến tính trong đó có một vòng huấn luyện lưu các điểm kiểm tra biến và phần đánh giá sẽ khôi phục các biến được lưu trong lần chạy trước và tính toán dự đoán. Tất nhiên, bạn cũng có thể khôi phục các biến và tiếp tục đào tạo nếu bạn muốn.
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})
Dưới đây là các tài liệu cho Variable
s, bao gồm tiết kiệm và khôi phục. Và đây là các tài liệu cho Saver
.
batch_x
cần phải có? Nhị phân? Mảng Numpy?
undefined
. Bạn có thể cho tôi biết đó là def của FLAGS cho mã này không. @RyanSepassi
Môi trường của tôi: Python 3.6, Tensorflow 1.3.0
Mặc dù đã có nhiều giải pháp, hầu hết chúng đều dựa trên tf.train.Saver
. Khi chúng tôi tải một .ckpt
cứu bởi Saver
, chúng ta phải xác định lại một trong hai mạng tensorflow hoặc sử dụng một số tên kỳ lạ và khó nhớ, ví dụ như 'placehold_0:0'
, 'dense/Adam/Weight:0'
. Ở đây tôi khuyên bạn nên sử dụng tf.saved_model
, một ví dụ đơn giản nhất được đưa ra dưới đây, bạn có thể tìm hiểu thêm từ Phục vụ Mô hình TensorFlow :
Lưu mô hình:
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()
Tải mô hình:
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})
Có hai phần cho mô hình, định nghĩa mô hình, được lưu bởi Supervisor
như graph.pbtxt
trong thư mục mô hình và các giá trị số của tenxơ, được lưu vào các tệp điểm kiểm tra như thế nào model.ckpt-1003418
.
Định nghĩa mô hình có thể được khôi phục bằng cách sử dụng tf.import_graph_def
và các trọng số được khôi phục bằng cách sử dụng Saver
.
Tuy nhiên, Saver
sử dụng danh sách các bộ sưu tập đặc biệt của các biến được đính kèm với Biểu đồ mô hình và bộ sưu tập này không được khởi tạo bằng cách sử dụng import_graph_def, vì vậy bạn không thể sử dụng hai biến này cùng lúc (theo lộ trình của chúng tôi để khắc phục). Hiện tại, bạn phải sử dụng cách tiếp cận của Ryan Sepassi - xây dựng biểu đồ bằng tay với các tên nút giống hệt nhau và sử dụng Saver
để tải trọng số vào nó.
(Ngoài ra, bạn có thể hack nó bằng cách sử dụng import_graph_def
, tạo các biến thủ công và sử dụng tf.add_to_collection(tf.GraphKeys.VARIABLES, variable)
cho từng biến, sau đó sử dụng Saver
)
Bạn cũng có thể thực hiện cách này dễ dàng hơn.
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
và lưu nómodel_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)
Trong khi chạy trong trường hợp python khác nhau, sử dụng
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)
Trong hầu hết các trường hợp, lưu và khôi phục từ đĩa bằng cách sử dụng a tf.train.Saver
là tùy chọn tốt nhất của bạn:
... # 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
Bạn cũng có thể lưu / khôi phục cấu trúc biểu đồ (xem tài liệu MetaGraph để biết chi tiết). Theo mặc định, Saver
cấu trúc biểu đồ lưu vào một .meta
tệp. Bạn có thể gọi import_meta_graph()
để khôi phục nó. Nó khôi phục cấu trúc đồ thị và trả về một Saver
cái mà bạn có thể sử dụng để khôi phục trạng thái của mô hình:
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
Tuy nhiên, có những trường hợp bạn cần một cái gì đó nhanh hơn nhiều. Ví dụ: nếu bạn thực hiện dừng sớm, bạn muốn lưu điểm kiểm tra mỗi khi mô hình cải thiện trong quá trình đào tạo (như được đo trên bộ xác thực), thì nếu không có tiến triển trong một thời gian, bạn muốn quay lại mô hình tốt nhất. Nếu bạn lưu mô hình vào đĩa mỗi khi nó cải thiện, nó sẽ làm chậm quá trình đào tạo. Mẹo nhỏ là lưu các trạng thái biến vào bộ nhớ , sau đó chỉ cần khôi phục chúng sau:
... # 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)
Giải thích nhanh: khi bạn tạo một biến X
, TensorFlow sẽ tự động tạo một thao tác gán X/Assign
để đặt giá trị ban đầu của biến. Thay vì tạo các trình giữ chỗ và các op gán thêm (điều này sẽ làm cho biểu đồ trở nên lộn xộn), chúng ta chỉ sử dụng các op chuyển nhượng hiện có này. Đầu vào đầu tiên của mỗi lần gán op là một tham chiếu đến biến được cho là khởi tạo và đầu vào thứ hai ( assign_op.inputs[1]
) là giá trị ban đầu. Vì vậy, để đặt bất kỳ giá trị nào chúng ta muốn (thay vì giá trị ban đầu), chúng ta cần sử dụng a feed_dict
và thay thế giá trị ban đầu. Có, TensorFlow cho phép bạn cung cấp giá trị cho bất kỳ op nào, không chỉ cho giữ chỗ, vì vậy điều này hoạt động tốt.
Như Yaroslav đã nói, bạn có thể hack khôi phục từ graph_def và điểm kiểm tra bằng cách nhập biểu đồ, tạo thủ công các biến và sau đó sử dụng Trình tiết kiệm.
Tôi đã triển khai điều này cho mục đích sử dụng cá nhân của mình, vì vậy tôi mặc dù tôi muốn chia sẻ mã ở đây.
Liên kết: https://gist.github.com/nikitakit/6ef3b72be67b86cb7868
(Tất nhiên, đây là một vụ hack và không có gì đảm bảo rằng các mô hình được lưu theo cách này sẽ vẫn có thể đọc được trong các phiên bản tương lai của TensorFlow.)
Nếu đó là một mô hình được lưu nội bộ, bạn chỉ cần chỉ định một trình phục hồi cho tất cả các biến là
restorer = tf.train.Saver(tf.all_variables())
và sử dụng nó để khôi phục các biến trong phiên hiện tại:
restorer.restore(self._sess, model_file)
Đối với mô hình bên ngoài, bạn cần chỉ định ánh xạ từ tên biến của nó sang tên biến của bạn. Bạn có thể xem tên biến mô hình bằng lệnh
python /path/to/tensorflow/tensorflow/python/tools/inspect_checkpoint.py --file_name=/path/to/pretrained_model/model.ckpt
Tập lệnh tests_checkpoint.py có thể được tìm thấy trong thư mục './tensorflow/python/tools' của nguồn Tensorflow.
Để chỉ định ánh xạ, bạn có thể sử dụng Tensorflow-Worklab của tôi , chứa một tập hợp các lớp và tập lệnh để huấn luyện và đào tạo lại các mô hình khác nhau. Nó bao gồm một ví dụ về đào tạo lại các mô hình ResNet, được đặt ở đây
all_variables()
hiện không được chấp nhận
Đây là giải pháp đơn giản của tôi cho hai trường hợp cơ bản khác nhau về việc bạn muốn tải biểu đồ từ tệp hoặc xây dựng nó trong thời gian chạy.
Câu trả lời này đúng với Tensorflow 0.12+ (bao gồm 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
Khi sử dụng kỹ thuật này, đảm bảo tất cả các lớp / biến của bạn đã đặt rõ ràng các tên duy nhất.Mặt khác, Tensorflow sẽ làm cho các tên trở nên độc đáo và do đó chúng sẽ khác với các tên được lưu trữ trong tệp. Đây không phải là vấn đề trong kỹ thuật trước đó, bởi vì các tên được "đọc sai" theo cùng một cách trong cả tải và lưu.
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
biến và trung bình di chuyển của chuẩn hóa hàng loạt là các biến không thể huấn luyện, nhưng cả hai đều chắc chắn có giá trị tiết kiệm. Ngoài ra, bạn nên phân biệt rõ hơn việc xây dựng biểu đồ với việc chạy phiên, ví dụ Saver(...).save()
sẽ tạo các nút mới mỗi khi bạn chạy nó. Có lẽ không phải là những gì bạn muốn. Và còn nữa ...: /
Bạn cũng có thể kiểm tra các ví dụ trong TensorFlow / skflow , cung cấp save
và restore
phương pháp có thể giúp bạn dễ dàng quản lý các mô hình của mình. Nó có các tham số mà bạn cũng có thể kiểm soát tần suất bạn muốn sao lưu mô hình của mình.
Nếu bạn sử dụng tf.train.MonitoredTrainingSession làm phiên mặc định, bạn không cần thêm mã bổ sung để thực hiện lưu / khôi phục mọi thứ. Chỉ cần chuyển một tên thư mục điểm kiểm tra cho hàm tạo của MonitoredTrainingSession, nó sẽ sử dụng các hook phiên để xử lý các hàm này.
Tất cả các câu trả lời ở đây là tuyệt vời, nhưng tôi muốn thêm hai điều.
Đầu tiên, để giải thích câu trả lời của @ user7505159, "./" có thể rất quan trọng để thêm vào đầu tên tệp mà bạn đang khôi phục.
Ví dụ: bạn có thể lưu biểu đồ không có "./" trong tên tệp như vậy:
# 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)
Nhưng để khôi phục biểu đồ, bạn có thể cần phải thêm "./" vào tệp_name:
# 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)
Bạn sẽ không luôn luôn cần "./", nhưng nó có thể gây ra sự cố tùy thuộc vào môi trường và phiên bản của TensorFlow.
Nó cũng muốn đề cập rằng sess.run(tf.global_variables_initializer())
có thể quan trọng trước khi khôi phục phiên.
Nếu bạn đang nhận được một lỗi liên quan đến các biến chưa được khởi tạo khi cố gắng khôi phục phiên đã lưu, hãy đảm bảo bạn bao gồm sess.run(tf.global_variables_initializer())
trước saver.restore(sess, save_file)
dòng. Nó có thể giúp bạn đỡ đau đầu.
Theo phiên bản Tensorflow mới, tf.train.Checkpoint
là cách tốt nhất để lưu và khôi phục mô hình:
Checkpoint.save
vàCheckpoint.restore
viết và đọc các điểm kiểm tra dựa trên đối tượng, ngược lại với tf.train.Saver viết và đọc các điểm kiểm tra dựa trên biến. Điểm kiểm tra dựa trên đối tượng lưu một biểu đồ phụ thuộc giữa các đối tượng Python (Lớp, Trình tối ưu hóa, Biến, v.v.) với các cạnh được đặt tên và biểu đồ này được sử dụng để khớp các biến khi khôi phục điểm kiểm tra. Có thể mạnh mẽ hơn đối với các thay đổi trong chương trình Python và giúp hỗ trợ khôi phục khi tạo cho các biến khi thực hiện một cách háo hức. Thíchtf.train.Checkpoint
hơntf.train.Saver
cho mã mới .
Đây là một ví dụ:
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)
Đối với tenorflow 2.0 , nó đơn giản như
# Save the model model.save('path_to_my_model.h5')
Để khôi phục lại:
new_model = tensorflow.keras.models.load_model('path_to_my_model.h5')
TF2.0
Tôi thấy câu trả lời tuyệt vời cho việc lưu mô hình bằng TF1.x. Tôi muốn cung cấp một vài gợi ý hơn trong việc tiết kiệmtensorflow.keras
các mô hình hơi phức tạp vì có nhiều cách để lưu mô hình.
Ở đây tôi cung cấp một ví dụ về việc lưu một tensorflow.keras
mô hình vào model_path
thư mục trong thư mục hiện tại. Điều này hoạt động tốt với hầu hết các dòng chảy gần đây (TF2.0). Tôi sẽ cập nhật mô tả này nếu có bất kỳ thay đổi nào trong tương lai gần.
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))
Nếu bạn chỉ muốn tiết kiệm trọng lượng mô hình và sau đó tải trọng lượng để khôi phục mô hình, thì
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})
Khi chúng ta có các op tùy chỉnh như trong trường hợp sau ( tf.tile
), chúng ta cần tạo một hàm và bọc bằng một lớp Lambda. Nếu không, mô hình không thể được lưu.
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")
Tôi nghĩ rằng tôi đã đề cập đến một vài trong số nhiều cách lưu mô hình tf.keras. Tuy nhiên, có nhiều cách khác. Vui lòng bình luận bên dưới nếu bạn thấy trường hợp sử dụng của bạn không được đề cập ở trên. Cảm ơn!
Bạn có thể lưu các biến trong mạng bằng cách sử dụng
saver = tf.train.Saver()
saver.save(sess, 'path of save/fileName.ckpt')
Để khôi phục mạng để sử dụng lại sau hoặc trong tập lệnh khác, hãy sử dụng:
saver = tf.train.Saver()
saver.restore(sess, tf.train.latest_checkpoint('path of save/')
sess.run(....)
Điểm quan trọng:
sess
phải giống nhau giữa các lần chạy đầu tiên và sau đó (cấu trúc mạch lạc). saver.restore
cần đường dẫn của thư mục của các tệp đã lưu, không phải là đường dẫn tệp riêng lẻ. Bất cứ nơi nào bạn muốn lưu mô hình,
self.saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
...
self.saver.save(sess, filename)
Hãy chắc chắn rằng, tất cả các bạn tf.Variable
đều có tên, vì bạn có thể muốn khôi phục chúng sau này bằng tên của chúng. Và nơi bạn muốn dự đoán,
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
Hãy chắc chắn rằng trình tiết kiệm chạy bên trong phiên tương ứng. Hãy nhớ rằng, nếu bạn sử dụng tf.train.latest_checkpoint('./')
, thì chỉ có điểm kiểm tra mới nhất sẽ được sử dụng.
Đối với dòng chảy-2.0
nó rất đơn giản.
import tensorflow as tf
model.save("model_name")
model = tf.keras.models.load_model('model_name')
Theo câu trả lời của @Vishnuvardhan Janapati, đây là một cách khác để lưu và tải lại mô hình với lớp / số liệu / mất tùy chỉnh theo 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})
Bằng cách này, một khi bạn đã thực hiện các mã như vậy, và lưu mô hình của bạn với tf.keras.models.save_model
hoặc model.save
hoặc ModelCheckpoint
gọi lại, bạn có thể tái nạp mô hình của bạn mà không cần các đối tượng tùy chỉnh chính xác, đơn giản như
new_model = tf.keras.models.load_model("./model.h5"})
Trong phiên bản mới của tenorflow 2.0, quá trình lưu / tải mô hình dễ dàng hơn rất nhiều. Do việc triển khai API Keras, API cấp cao dành cho TensorFlow.
Để lưu mô hình: Kiểm tra tài liệu để tham khảo: 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)
Để tải một mô hình:
https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/keras/models/load_model
model = tf.keras.models.load_model(filepath)
Dưới đây là một ví dụ đơn giản sử dụng định dạng Tensorflow 2.0 SavingModel (là định dạng được đề xuất, theo các tài liệu ) cho trình phân loại dữ liệu MNIST đơn giản, sử dụng API chức năng Keras mà không cần quá nhiều sự ưa thích đang diễn ra:
# 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
Là serving_default
gì
Đó là tên của chữ ký def của thẻ bạn đã chọn (trong trường hợp này, serve
thẻ mặc định đã được chọn). Ngoài ra, ở đây giải thích cách tìm thẻ và chữ ký của một mô hình bằng cách sử dụng saved_model_cli
.
Khước từ
Đây chỉ là một ví dụ cơ bản nếu bạn chỉ muốn khởi động và chạy, nhưng không có nghĩa là một câu trả lời hoàn chỉnh - có lẽ tôi có thể cập nhật nó trong tương lai. Tôi chỉ muốn đưa ra một ví dụ đơn giản bằng cách sử dụngSavedModel
trong TF 2.0 vì tôi chưa thấy một , ngay cả ở nơi đơn giản này.
Câu trả lời của @ Tom là một ví dụ SavingModel, nhưng nó sẽ không hoạt động trên Tensorflow 2.0, vì không may có một số thay đổi vi phạm.
Câu trả lời của @ Vishnuvardhan Janapati nói TF 2.0, nhưng nó không dành cho định dạng SavingModel.