Tensorflow: วิธีการบันทึก / กู้คืนรูปแบบ?


552

หลังจากคุณฝึกโมเดลใน Tensorflow:

  1. คุณจะบันทึกโมเดลที่ได้รับการฝึกฝนอย่างไร
  2. คุณจะคืนค่าโมเดลที่บันทึกไว้ในภายหลังได้อย่างไร

คุณสามารถกู้คืนตัวแปรที่ใช้ในแบบจำลองการลงทะเบียนได้หรือไม่? ฉันกำลังพยายามแก้ไขปัญหาเดียวกัน แต่ฉันไม่สามารถเขียนชุดตัวแปรที่ใช้ขณะฝึกอบรมแบบจำลองการลงทะเบียน (ซึ่งฉันมีไฟล์ ckpt)
exAres

ฉันไม่ได้ลองกับแบบจำลองการลงทะเบียน คุณมีโครงสร้างเครือข่ายของชื่อรุ่นหรือไม่? คุณต้องทำซ้ำเครือข่ายแล้วโหลดน้ำหนักและอคติ (ไฟล์ ckpt) ตามที่ Ryan อธิบาย อาจมีบางอย่างเปลี่ยนไปตั้งแต่ พ.ย. 15 และมีวิธีที่ตรงไปตรงมามากกว่าตอนนี้ฉันไม่แน่ใจ
mathetes

โอเคไม่เป็นไร ฉันได้โหลดโมเดลเทนเซอร์โฟลว์ที่ผ่านการฝึกอบรมมาก่อนหน้านี้แล้ว แต่กำลังมองหาข้อมูลจำเพาะเกี่ยวกับตัวแปรของแบบจำลองการลงทะเบียน ขอบคุณ
exAres

1
หากคุณกู้คืนเพื่อฝึกอบรมต่อให้ใช้จุดตรวจสอบ Saver หากคุณบันทึกโมเดลเพื่อทำการอ้างอิงเพียงแค่ tensorflow SavedModel APIs
HY G

นอกจากนี้หากคุณกำลังใช้ LSTM คุณจะมีแผนที่จากสตริงไปยังรายชื่อตัวละครอย่าลืมบันทึกและโหลดรายการนั้นในลำดับเดียวกัน! สิ่งนี้ไม่ได้รวมอยู่ในการบันทึกน้ำหนักแบบจำลองและเครือข่ายกราฟแบบจำลองและจะทำให้ดูเหมือนว่าแบบจำลองของคุณไม่ได้ถูกโหลดเมื่อคุณเปลี่ยนเซสชันหรือการเปลี่ยนแปลงข้อมูล
devssh

คำตอบ:


119

เอกสาร

จากเอกสาร:

บันทึก

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

Tensorflow 2

ยังคงเป็นรุ่นเบต้าดังนั้นฉันจะแนะนำในตอนนี้ หากคุณยังต้องการลงไปที่ถนนนี่คือtf.saved_modelคู่มือการใช้งาน

Tensorflow <2

simple_save

คำตอบที่ดีมากเพื่อความสมบูรณ์ฉันจะเพิ่ม 2 เซ็นต์ของฉัน: simple_save นอกจากนี้ยังมีตัวอย่างรหัสแบบสแตนด์อโลนโดยใช้tf.data.DatasetAPI

Python 3; Tensorflow 1.14

import tensorflow as tf
from tensorflow.saved_model import tag_constants

with tf.Graph().as_default():
    with tf.Session() as sess:
        ...

        # Saving
        inputs = {
            "batch_size_placeholder": batch_size_placeholder,
            "features_placeholder": features_placeholder,
            "labels_placeholder": labels_placeholder,
        }
        outputs = {"prediction": model_output}
        tf.saved_model.simple_save(
            sess, 'path/to/your/location/', inputs, outputs
        )

การกู้คืน:

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

ตัวอย่างแบบสแตนด์อโลน

โพสต์บล็อกเดิม

รหัสต่อไปนี้สร้างข้อมูลแบบสุ่มเพื่อการสาธิต

  1. เราเริ่มต้นด้วยการสร้างตัวแทน พวกเขาจะเก็บข้อมูลที่รันไทม์ จากพวกเราสร้างแล้วมันDataset Iteratorเราได้รับเมตริกซ์ที่สร้างขึ้นของ iterator ที่เรียกว่าinput_tensorซึ่งจะทำหน้าที่เป็นข้อมูลป้อนเข้าโมเดลของเรา
  2. ตัวแบบถูกสร้างขึ้นจากinput_tensor: RNN แบบสองทิศทางที่อิงกับ GRU ตามด้วยตัวจําแนกแบบหนาแน่น เพราะเหตุใด
  3. การสูญเสียเป็นsoftmax_cross_entropy_with_logits, Adamการเพิ่มประสิทธิภาพด้วย หลังจากนั้น 2 epochs (2 สำหรับกระบวนการแต่ละ) เราประหยัด "ได้รับการฝึกฝน" tf.saved_model.simple_saveรูปแบบด้วย หากคุณเรียกใช้รหัสตามเดิมโมเดลจะถูกบันทึกไว้ในโฟลเดอร์ที่เรียกว่าsimple/ในไดเรกทอรีการทำงานปัจจุบันของคุณ
  4. tf.saved_model.loader.loadในกราฟใหม่เราแล้วเรียกคืนรุ่นที่บันทึกไว้ด้วย เราคว้าตัวยึดและ logits กับgraph.get_tensor_by_nameและการดำเนินงานเริ่มต้นด้วยIteratorgraph.get_operation_by_name
  5. ในที่สุดเราก็ทำการอนุมานสำหรับทั้งสองชุดในชุดข้อมูลและตรวจสอบว่าทั้งสองรุ่นที่บันทึกและกู้คืนให้ค่าเดียวกัน พวกเขาทำ!

รหัส:

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)

สิ่งนี้จะพิมพ์:

$ python3 save_and_restore.py

Epoch 0, batch 0 | Sample value: [-0.13851789 -0.3087595   0.12804556  0.20013677 -0.08229901]
Epoch 0, batch 1 | Sample value: [-0.00555491 -0.04339041 -0.05111827 -0.2480045  -0.00107776]
Epoch 1, batch 0 | Sample value: [-0.19321944 -0.2104792  -0.00602257  0.07465433  0.11674127]
Epoch 1, batch 1 | Sample value: [-0.05275984  0.05981954 -0.15913513 -0.3244143   0.10673307]
Epoch 2, batch 0 | Final inference | Sample value: [-0.26331693 -0.13013336 -0.12553    -0.04276478  0.2933622 ]
Epoch 2, batch 1 | Final inference | Sample value: [-0.07730117  0.11119192 -0.20817074 -0.35660955  0.16990358]

Saving...
INFO:tensorflow:Assets added to graph.
INFO:tensorflow:No assets to write.
INFO:tensorflow:SavedModel written to: b'/some/path/simple/saved_model.pb'
Ok

Restoring...
INFO:tensorflow:Restoring parameters from b'/some/path/simple/variables/variables'
Ok
Restored values:  [-0.26331693 -0.13013336 -0.12553    -0.04276478  0.2933622 ]
Restored values:  [-0.07730117  0.11119192 -0.20817074 -0.35660955  0.16990358]

Inferences match:  True

1
ฉันเริ่มต้นและฉันต้องการคำอธิบายเพิ่มเติม ... : ถ้าฉันมีโมเดล CNN ฉันควรจัดเก็บเพียง 1 inputs_placeholder 2. labels_placeholder และ 3. output_of_cnn? หรือสื่อกลางทั้งหมดtf.contrib.layers?
ฝนตก

2
กราฟถูกเรียกคืนทั้งหมด [n.name for n in graph2.as_graph_def().node]คุณสามารถตรวจสอบการทำงาน ตามที่เอกสารระบุว่าการบันทึกอย่างง่ายมีจุดมุ่งหมายเพื่อลดความซับซ้อนของการโต้ตอบกับการแสดงผลของเทนเซอร์โฟลว์นี่คือจุดโต้แย้ง อย่างไรก็ตามตัวแปรอื่น ๆ ยังคงถูกกู้คืนมิฉะนั้นการอนุมานจะไม่เกิดขึ้น เพียงแค่หยิบตัวแปรที่คุณสนใจตามตัวอย่าง ตรวจสอบเอกสาร
เท็ด

@ เสร็จแล้วฉันจะใช้ tf.saved_model.simple_save กับ tf.train.Saver () เมื่อใด จากสัญชาตญาณของฉันฉันจะใช้ tf.train.Saver () ระหว่างการฝึกอบรมและเพื่อเก็บช่วงเวลาที่แตกต่างกันในเวลา ฉันจะใช้ tf.saved_model.simple_save เมื่อมีการฝึกอบรมเพื่อใช้ในการผลิต (ฉันถามเหมือนกันในความคิดเห็นที่นี่ )
loco.loop

1
ดีฉันเดา แต่มันยังใช้งานได้กับโหมด Eager และ tfe.Saver หรือไม่
Geoffrey Anderson

1
โดยไม่ต้องglobal_stepเป็นอาร์กิวเมนต์ถ้าคุณหยุดแล้วพยายามที่จะรับการฝึกอบรมอีกครั้งก็จะคิดว่าคุณเป็นหนึ่งในขั้นตอนเดียว มันจะทำให้การสร้างภาพบนบอร์ดเมตริกซ์ของคุณน้อยที่สุด
Monica Heddneck

252

ฉันกำลังปรับปรุงคำตอบของฉันเพื่อเพิ่มรายละเอียดเพิ่มเติมสำหรับการบันทึกและกู้คืนโมเดล

ใน (และหลัง) Tensorflow เวอร์ชั่น 0.11 :

บันทึกโมเดล:

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)

กู้คืนโมเดล:

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 

กรณีนี้และการใช้งานขั้นสูงอื่น ๆ ได้รับการอธิบายได้ดีมากที่นี่

บทแนะนำฉบับย่อที่สมบูรณ์เพื่อบันทึกและกู้คืนโมเดล Tensorflow


3
+1 สำหรับ # ตัวแปรนี้บันทึกการเข้าถึงพิมพ์โดยตรง (sess.run ('อคติ: 0')) # สิ่งนี้จะพิมพ์ 2 ซึ่งเป็นค่าของอคติที่เราบันทึกไว้ มันช่วยได้มากสำหรับการแก้ไขจุดบกพร่องเพื่อดูว่าโหลดแบบจำลองถูกต้องหรือไม่ ตัวแปรสามารถรับได้ด้วย "All_varaibles = tf.get_collection (tf.GraphKeys.GLOBAL_VARIABLES" นอกจากนี้ "sess.run (tf.global_variables_initializer ())" ก่อนที่จะกู้คืน
LGG

1
คุณแน่ใจหรือว่าเราต้องเรียกใช้ global_variables_initializer อีกครั้ง ฉันกู้คืนกราฟของฉันด้วย global_variable_initialization และมันให้ผลลัพธ์ที่แตกต่างกันทุกครั้งบนข้อมูลเดียวกัน ดังนั้นฉันจึงแสดงความคิดเห็นการเริ่มต้นและเพิ่งกู้คืนกราฟตัวแปรอินพุตและ ops และตอนนี้ก็ใช้งานได้ดี
Aditya Shinde

@AdityaShinde ฉันไม่เข้าใจว่าทำไมฉันถึงได้รับคุณค่าที่แตกต่างกันทุกครั้ง และฉันไม่ได้รวมขั้นตอนการเริ่มต้นตัวแปรสำหรับการกู้คืน ฉันใช้รหัสของตัวเอง btw
Chaine

@AdityaShinde: คุณไม่จำเป็นต้องมี init op เนื่องจากค่านั้นได้รับการเริ่มต้นโดยฟังก์ชั่นการกู้คืนดังนั้นให้ลบออก อย่างไรก็ตามฉันไม่แน่ใจว่าทำไมคุณถึงได้ผลลัพธ์ที่แตกต่างโดยใช้ init op
sankit

5
@sankit เมื่อคุณกู้คืนเทนเซอร์ทำไมคุณเพิ่ม:0ชื่อ?
Sahar Rabinoviz

177

ใน (และหลัง) TensorFlow รุ่น 0.11.0RC1 คุณสามารถบันทึกและเรียกคืนรูปแบบของคุณได้โดยตรงโดยการโทรtf.train.export_meta_graphและtf.train.import_meta_graphตาม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_)

4
วิธีโหลดตัวแปรจากโมเดลที่บันทึกไว้ทำอย่างไร? วิธีการคัดลอกค่าในตัวแปรอื่น ๆ ?
พฤศจิกายน

9
ฉันไม่สามารถรับรหัสนี้ได้ โมเดลได้รับการบันทึก แต่ฉันไม่สามารถกู้คืนได้ มันทำให้ฉันมีข้อผิดพลาดนี้ <built-in function TF_Run> returned a result with an error set
Saad Qureshi

2
เมื่อกู้คืนฉันเข้าถึงตัวแปรตามที่แสดงด้านบนแล้วมันก็ใช้งานได้ แต่ฉันไม่สามารถรับตัวแปรอื่น ๆ ได้โดยตรงโดยใช้ ตามด้วยtf.get_variable_scope().reuse_variables() var = tf.get_variable("varname")สิ่งนี้ทำให้ฉันเกิดข้อผิดพลาด: "ValueError: ตัวแปร varname ไม่มีอยู่หรือไม่ได้ถูกสร้างขึ้นด้วย tf.get_variable ()" ทำไม? สิ่งนี้เป็นไปไม่ได้หรือไม่?
โยฮันน์เพทรักร์

4
สิ่งนี้ใช้ได้ดีกับตัวแปรเท่านั้น แต่คุณจะเข้าถึงตัวยึดและค่าฟีดได้อย่างไรหลังจากกู้คืนกราฟ
kbrose

11
แสดงเฉพาะวิธีการกู้คืนตัวแปร คุณจะคืนค่าโมเดลทั้งหมดและทดสอบกับข้อมูลใหม่โดยไม่ต้องกำหนดเครือข่ายใหม่ได้อย่างไร
Chaine

127

สำหรับ TensorFlow เวอร์ชั่น <0.11.0RC1:

จุดตรวจที่ถูกบันทึกมีค่าสำหรับ Variable s ในแบบจำลองของคุณไม่ใช่แบบ / กราฟเองซึ่งหมายความว่ากราฟควรเหมือนกันเมื่อคุณคืนค่าจุดตรวจสอบ

นี่คือตัวอย่างสำหรับการถดถอยเชิงเส้นที่มีลูปการฝึกอบรมที่บันทึกจุดตรวจตัวแปรและส่วนการประเมินผลที่จะคืนค่าตัวแปรที่บันทึกไว้ในการเรียกใช้ก่อนหน้าและคำนวณการคาดการณ์ แน่นอนคุณสามารถกู้คืนตัวแปรและดำเนินการฝึกอบรมได้หากต้องการ

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

นี่คือ เอกสารสำหรับVariables ซึ่งครอบคลุมการบันทึกและการกู้คืน และนี่เป็นเอกสารSaverสำหรับ


1
FLAGS ถูกกำหนดโดยผู้ใช้ นี่คือตัวอย่างของการกำหนด: github.com/tensorflow/tensorflow/blob/master/tensorflow/ …
Ryan Sepassi

ในรูปแบบที่ไม่batch_xจำเป็นต้องเป็นอย่างไร ไบนารี่? อาร์เรย์จำนวนมาก?
pepe

@pepe Numpy arrary ควรใช้ได้ และประเภทขององค์ประกอบควรสอดคล้องกับประเภทของตัวยึดตำแหน่ง [ลิงค์] tensorflow.org/versions/r0.9/api_docs/python/…
Donny

undefinedธงให้ข้อผิดพลาด คุณช่วยบอกฉันได้ไหมว่า def ใดของธงนี้ @RyanSepassi
Muhammad Hannan

ที่จะทำให้มันชัดเจน: รุ่นล่าสุดของ Tensorflow ไม่อนุญาตให้มีการจัดเก็บรูปแบบ / กราฟ [มันไม่ชัดเจนสำหรับฉันคำตอบด้านใดที่ใช้กับข้อ จำกัด <0.11 ด้วยจำนวน upvotes ฉันถูกล่อลวงให้เชื่อว่าคำสั่งทั่วไปนี้ยังคงเป็นจริงสำหรับรุ่นล่าสุด]
bluenote10 10

78

สภาพแวดล้อมของฉัน: Python 3.6, Tensorflow 1.3.0

tf.train.Saverแม้ว่าจะมีการแก้ไขปัญหามากที่สุดของพวกเขาจะขึ้นอยู่กับ เมื่อเราโหลด.ckptบันทึกไว้โดยSaverเรามีทั้ง redefine เครือข่าย tensorflow หรือใช้ชื่อแปลกและยากจำบางอย่างเช่น,'placehold_0:0' 'dense/Adam/Weight:0'ที่นี่ฉันแนะนำให้ใช้tf.saved_modelหนึ่งตัวอย่างที่ง่ายที่สุดที่ระบุด้านล่างคุณสามารถเรียนรู้เพิ่มเติมจากการใช้แบบจำลอง TensorFlow :

บันทึกโมเดล:

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

โหลดแบบจำลอง:

import tensorflow as tf
sess=tf.Session() 
signature_key = tf.saved_model.signature_constants.DEFAULT_SERVING_SIGNATURE_DEF_KEY
input_key = 'x_input'
output_key = 'y_output'

export_path =  './savedmodel'
meta_graph_def = tf.saved_model.loader.load(
           sess,
          [tf.saved_model.tag_constants.SERVING],
          export_path)
signature = meta_graph_def.signature_def

x_tensor_name = signature[signature_key].inputs[input_key].name
y_tensor_name = signature[signature_key].outputs[output_key].name

x = sess.graph.get_tensor_by_name(x_tensor_name)
y = sess.graph.get_tensor_by_name(y_tensor_name)

y_out = sess.run(y, {x: 3.0})

4
+1 สำหรับตัวอย่างที่ดีของ SavedModel API อย่างไรก็ตามฉันหวังว่าส่วนSave the modelของคุณจะแสดงการฝึกซ้อมเหมือนคำตอบของ Ryan Sepassi! ฉันรู้ว่านี่เป็นคำถามเก่า แต่การตอบสนองนี้เป็นหนึ่งในไม่กี่ตัวอย่าง (และมีค่า) ของ SavedModel ที่ฉันพบใน Google
Dylan F

@ Tom นี่เป็นคำตอบที่ดี - มีเพียงหนึ่งเดียวที่มุ่งไปที่ SavedModel ใหม่ คุณสามารถดูคำถาม SavedModel นี้ได้ไหม stackoverflow.com/questions/48540744/…
bluesummers

ตอนนี้ทำให้มันทำงานได้อย่างถูกต้องกับรุ่น TF Eager Google ให้คำแนะนำในการนำเสนอในปี 2018 เพื่อให้ทุกคนหลีกเลี่ยงรหัสกราฟ TF
Geoffrey Anderson

55

มีสองส่วนรูปแบบความหมายรูปแบบการบันทึกไว้โดยมีความSupervisorเป็นgraph.pbtxtอยู่ในไดเรกทอรีรูปแบบและค่าตัวเลขของเทนเซอร์, บันทึกลงในไฟล์เช่นด่านmodel.ckpt-1003418บันทึกลงในไฟล์เช่นด่าน

คำจำกัดความของแบบจำลองสามารถเรียกคืนได้โดยใช้tf.import_graph_defและน้ำหนักจะถูกกู้คืนโดยใช้Saverและน้ำหนักที่มีการเรียกคืนการใช้

อย่างไรก็ตามSaverใช้รายการการเก็บพิเศษของตัวแปรที่แนบมากับกราฟของโมเดลและคอลเลกชันนี้ไม่ได้เริ่มต้นโดยใช้ import_graph_def ดังนั้นคุณจึงไม่สามารถใช้ทั้งสองร่วมกันได้ในขณะนี้ (อยู่ในแผนงานของเราในการแก้ไข) สำหรับตอนนี้คุณต้องใช้วิธีการของ Ryan Sepassi - สร้างกราฟด้วยชื่อโหนดที่เหมือนกันและใช้Saverในการโหลดน้ำหนักเข้าไป

(อีกวิธีหนึ่งคุณสามารถแฮ็คมันได้โดยใช้import_graph_defการสร้างตัวแปรด้วยตนเองและใช้tf.add_to_collection(tf.GraphKeys.VARIABLES, variable)สำหรับแต่ละตัวแปรจากนั้นใช้Saver)


ในตัวอย่าง classify_image.py ที่ใช้ inceptionv3 เฉพาะโหลด graphdef เท่านั้น หมายความว่าตอนนี้ GraphDef ยังมีตัวแปรหรือไม่
jrabary

1
@jrabary รุ่นที่ได้รับอาจจะแช่แข็ง
Eric Platon

1
เฮ้ฉันใหม่กับ tensorflow และมีปัญหาในการบันทึกโมเดลของฉัน ฉันจะซาบซึ้งจริงๆถ้าคุณสามารถช่วยฉันstackoverflow.com/questions/48083474/…
Ruchir Baronia

39

คุณสามารถใช้วิธีนี้ได้ง่ายขึ้น

ขั้นตอนที่ 1: เริ่มต้นตัวแปรทั้งหมดของคุณ

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

ขั้นตอนที่ 2: บันทึกเซสชันภายในโมเดลSaverและบันทึก

model_saver = tf.train.Saver()

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

ขั้นตอนที่ 3: กู้คืนโมเดล

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

ขั้นตอนที่ 4: ตรวจสอบตัวแปรของคุณ

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

ในขณะที่ทำงานในอินสแตนซ์ python ที่แตกต่างกันให้ใช้

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)

สวัสดีฉันจะบันทึกแบบจำลองได้อย่างไรหลังจากสมมติซ้ำ 3,000 ครั้งคล้ายกับ Caffe ฉันพบว่าเมตริกซ์บันทึกเฉพาะรุ่นสุดท้ายแม้ว่าฉันจะต่อหมายเลขซ้ำกับโมเดลเพื่อแยกความแตกต่างระหว่างการวนซ้ำทั้งหมด ฉันหมายถึง model_3000.ckpt, model_6000.ckpt, --- model_100000.ckpt คุณช่วยอธิบายได้ไหมว่าทำไมมันถึงไม่บันทึกทั้งหมดแทนที่จะบันทึกเพียง 3 ครั้งล่าสุดเท่านั้น
khan


3
มีวิธีในการรับตัวแปร / ชื่อการทำงานทั้งหมดที่บันทึกไว้ในกราฟหรือไม่?
Moondra

21

ในกรณีส่วนใหญ่การบันทึกและกู้คืนจากดิสก์โดยใช้ a tf.train.Saverเป็นตัวเลือกที่ดีที่สุดของคุณ:

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

นอกจากนี้คุณยังสามารถบันทึก / กู้คืนโครงสร้างกราฟตัวเอง (ดูเอกสาร MetaGraphสำหรับรายละเอียด) โดยค่าเริ่มต้นการSaverบันทึกโครงสร้างกราฟลงใน.metaไฟล์ คุณสามารถโทรimport_meta_graph()เพื่อคืนค่าได้ มันคืนค่าโครงสร้างกราฟและส่งกลับค่าSaverที่คุณสามารถใช้เพื่อกู้คืนสถานะของโมเดล:

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

อย่างไรก็ตามมีบางกรณีที่คุณต้องการบางสิ่งที่เร็วกว่ามาก ตัวอย่างเช่นหากคุณใช้การหยุดก่อนกำหนดคุณต้องการบันทึกจุดตรวจทุกครั้งที่แบบจำลองปรับปรุงระหว่างการฝึกอบรม (วัดจากชุดการตรวจสอบความถูกต้อง) จากนั้นหากไม่มีความคืบหน้าในบางครั้งคุณต้องการย้อนกลับไปเป็นรุ่นที่ดีที่สุด หากคุณบันทึกโมเดลลงในดิสก์ทุกครั้งที่มีการปรับปรุงมันจะช้าลงอย่างมากในการฝึกอบรม เคล็ดลับคือการบันทึกตัวแปรสถานะไว้ในหน่วยความจำจากนั้นเพียงกู้คืนพวกเขาในภายหลัง:

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

คำอธิบายอย่างรวดเร็ว: เมื่อคุณสร้างตัวแปรXTensorFlow จะสร้างการดำเนินการที่มอบหมายโดยอัตโนมัติX/Assignเพื่อตั้งค่าเริ่มต้นของตัวแปร แทนที่จะสร้างตัวยึดตำแหน่งและการมอบหมายพิเศษ (ซึ่งจะทำให้กราฟยุ่งเหยิง) เราเพียงแค่ใช้ตัวกำหนดที่มีอยู่เหล่านี้ อินพุตแรกของแต่ละการกำหนด op คือการอ้างอิงไปยังตัวแปรที่ควรเริ่มต้นและอินพุตที่สอง ( assign_op.inputs[1]) คือค่าเริ่มต้น ดังนั้นในการตั้งค่าใด ๆ ที่เราต้องการ (แทนที่จะเป็นค่าเริ่มต้น) เราจำเป็นต้องใช้feed_dictและแทนที่ค่าเริ่มต้น ใช่ TensorFlow ช่วยให้คุณป้อนค่าสำหรับตัวเลือกใด ๆ ไม่ใช่เฉพาะสำหรับตัวยึดดังนั้นจึงใช้งานได้ดี


ขอบคุณสำหรับคำตอบ. ฉันมีคำถามที่คล้ายกันเกี่ยวกับวิธีการแปลงไฟล์ .ckpt ไฟล์เดียวเป็นสองไฟล์. index และ. data (พูดสำหรับโมเดลการลงทะเบียนเรียนล่วงหน้าที่มีให้ใน tf.slim) คำถามของฉันอยู่ที่นี่: stackoverflow.com/questions/47762114/…
อาเมียร์

เฮ้ฉันใหม่กับ tensorflow และมีปัญหาในการบันทึกโมเดลของฉัน ฉันจะขอบคุณถ้าคุณสามารถช่วยฉันstackoverflow.com/questions/48083474/…
Ruchir Baronia

17

ดังที่ Yaroslav กล่าวคุณสามารถแฮ็กการกู้คืนจาก graph_def และจุดตรวจสอบโดยการนำเข้ากราฟสร้างตัวแปรด้วยตนเองแล้วใช้ Saver

ฉันใช้สิ่งนี้เพื่อการใช้งานส่วนตัวของฉันดังนั้นฉันถึงแม้ว่าฉันจะแบ่งปันรหัสที่นี่

ลิงก์: https://gist.github.com/nikitakit/6ef3b72be67b86cb7868

(แน่นอนว่าเป็นแฮ็คและไม่มีการรับประกันว่าแบบจำลองที่บันทึกด้วยวิธีนี้จะยังคงสามารถอ่านได้ใน TensorFlow เวอร์ชันในอนาคต)


14

หากเป็นรุ่นที่บันทึกไว้ภายในคุณเพียงระบุ restorer สำหรับตัวแปรทั้งหมดเป็น

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

และใช้เพื่อเรียกคืนตัวแปรในเซสชันปัจจุบัน:

restorer.restore(self._sess, model_file)

สำหรับโมเดลภายนอกคุณต้องระบุการแม็พจากชื่อตัวแปรไปยังชื่อตัวแปรของคุณ คุณสามารถดูชื่อตัวแปรโมเดลโดยใช้คำสั่ง

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

สคริปต์ inspect_checkpoint.py สามารถพบได้ในโฟลเดอร์ './tensorflow/python/tools' ของแหล่ง Tensorflow

ในการระบุการแมปคุณสามารถใช้Tensorflow-Worklabของฉันซึ่งมีชุดคลาสและสคริปต์เพื่อฝึกอบรมและฝึกสอนโมเดลที่แตกต่างกัน มันมีตัวอย่างของการฝึกอบรม ResNet รุ่นใหม่อยู่ที่นี่


all_variables()เลิกใช้แล้วตอนนี้
MiniQuark

เฮ้ฉันใหม่กับ tensorflow และมีปัญหาในการบันทึกโมเดลของฉัน ฉันจะขอบคุณมากถ้าคุณสามารถช่วยฉันstackoverflow.com/questions/48083474/…
Ruchir Baronia

12

ต่อไปนี้เป็นคำตอบง่ายๆของฉันสำหรับกรณีพื้นฐานสองกรณีที่แตกต่างกันไม่ว่าคุณต้องการโหลดกราฟจากไฟล์หรือสร้างในระหว่างรันไทม์

คำตอบนี้มีไว้สำหรับ Tensorflow 0.12+ (รวมถึง 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

กำลังโหลดกราฟจากไฟล์ด้วย

เมื่อใช้เทคนิคนี้ตรวจสอบให้แน่ใจว่าเลเยอร์ / ตัวแปรทั้งหมดของคุณได้ตั้งชื่อที่ไม่ซ้ำกันอย่างชัดเจนมิฉะนั้น Tensorflow จะทำให้ชื่อไม่ซ้ำกันและจะแตกต่างจากชื่อที่เก็บไว้ในไฟล์ มันไม่ได้เป็นปัญหาในเทคนิคก่อนหน้านี้เพราะชื่อ "mangled" เป็นวิธีเดียวกันในการโหลดและบันทึก

ประหยัด

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

-1 การเริ่มต้นคำตอบของคุณโดยการยกเลิก "คำตอบอื่น ๆ ทั้งหมดที่นี่" ค่อนข้างรุนแรง ที่กล่าวว่าฉันลงเพราะเหตุผลอื่น: คุณควรบันทึกตัวแปรส่วนกลางทั้งหมดอย่างแน่นอนไม่ใช่เฉพาะตัวแปรที่ฝึกได้ ตัวอย่างเช่นglobal_stepตัวแปรและค่าเฉลี่ยเคลื่อนที่ของการปรับสภาพแบทช์เป็นตัวแปรที่ไม่สามารถฝึกอบรมได้ แต่ทั้งคู่คุ้มค่าที่จะประหยัดแน่นอน นอกจากนี้คุณควรแยกความแตกต่างการสร้างกราฟให้ชัดเจนยิ่งขึ้นตัวอย่างเช่นSaver(...).save()จะสร้างโหนดใหม่ทุกครั้งที่คุณเรียกใช้ อาจไม่ใช่สิ่งที่คุณต้องการ และยังมีอีกมาก ... : /
MiniQuark

@MiniQuark ok ขอบคุณสำหรับความคิดเห็นของคุณฉันจะแก้ไขคำตอบให้เป็นไปตามคำแนะนำของคุณ;)
มาร์ติน Pecka

10

คุณยังสามารถดูตัวอย่างในTensorFlow / skflowซึ่งมีข้อเสนอsaveและrestoreวิธีการที่จะช่วยคุณจัดการโมเดลของคุณได้อย่างง่ายดาย มีพารามิเตอร์ที่คุณสามารถควบคุมความถี่ที่คุณต้องการสำรองโมเดลของคุณ


9

หากคุณใช้tf.train.MonitoredTrainingSessionเป็นเซสชั่นเริ่มต้นคุณไม่จำเป็นต้องเพิ่มรหัสพิเศษเพื่อบันทึก / เรียกคืนสิ่งต่าง ๆ เพียงส่งชื่อ dir ไปยังตัวสร้างของ MonitoredTrainingSession ก็จะใช้ session hooks เพื่อจัดการสิ่งเหล่านี้


การใช้tf.train.Supervisorจะจัดการการสร้างเซสชั่นดังกล่าวให้คุณและมอบโซลูชั่นที่สมบูรณ์ยิ่งขึ้น
Mark

1
@Mark tf.train.Supervisor เลิกใช้แล้ว
Changming Sun

คุณมีลิงค์ใด ๆ ที่สนับสนุนการอ้างสิทธิ์ว่าหัวหน้างานเลิกใช้แล้วหรือไม่? ฉันไม่เห็นสิ่งใดที่บ่งบอกว่าเป็นเช่นนี้
Mark


ขอบคุณสำหรับ URL - ฉันตรวจสอบกับแหล่งข้อมูลดั้งเดิมแล้วและได้รับการบอกว่าอาจจะมีประมาณจนกว่าจะสิ้นสุดของซีรี่ส์ TF 1.x แต่ไม่มีการรับประกันหลังจากนั้น
Mark

8

คำตอบทั้งหมดที่นี่ยอดเยี่ยม แต่ฉันต้องการเพิ่มสองสิ่ง

ก่อนอื่นให้อธิบายอย่างละเอียดกับคำตอบของ @ user7505159 "./" อาจเป็นสิ่งสำคัญที่จะเพิ่มไปยังจุดเริ่มต้นของชื่อไฟล์ที่คุณกำลังกู้คืน

ตัวอย่างเช่นคุณสามารถบันทึกกราฟโดยไม่มี "./" ในชื่อไฟล์ดังนี้:

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

แต่ในการกู้คืนกราฟคุณอาจต้องเพิ่ม "./" ลงในไฟล์ชื่อ:

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

คุณไม่จำเป็นต้องใช้ "./" เสมอไป แต่อาจทำให้เกิดปัญหาขึ้นอยู่กับสภาพแวดล้อมและรุ่นของ TensorFlow

นอกจากนี้ยังต้องการพูดถึงว่าsess.run(tf.global_variables_initializer())สามารถมีความสำคัญก่อนที่จะกู้คืนเซสชั่น

หากคุณได้รับข้อผิดพลาดเกี่ยวกับตัวแปรที่ไม่มีการกำหนดค่าเริ่มต้นเมื่อพยายามกู้คืนเซสชันที่บันทึกไว้ตรวจสอบให้แน่ใจว่าคุณได้รวมsess.run(tf.global_variables_initializer())ก่อนหน้าsaver.restore(sess, save_file)บรรทัด มันสามารถช่วยให้คุณปวดหัว


7

ตามที่อธิบายในปัญหา6255 :

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

แทน

saver.restore('my_model_final.ckpt')

7

ตามรุ่น Tensorflow ใหม่tf.train.Checkpointเป็นวิธีที่ดีกว่าในการบันทึกและกู้คืนแบบจำลอง:

Checkpoint.saveและCheckpoint.restoreเขียนและอ่านจุดตรวจตามวัตถุในทางตรงกันข้ามกับ tf.train.Saver ซึ่งเขียนและอ่านจุดตรวจตามตัวแปร. ชื่อ การตรวจจับแบบอิงวัตถุจะบันทึกกราฟของการพึ่งพาระหว่างวัตถุ Python (เลเยอร์, ​​เครื่องมือปรับให้เหมาะสม, ตัวแปร, ฯลฯ ) ด้วยขอบที่มีชื่อและกราฟนี้ใช้เพื่อจับคู่ตัวแปรเมื่อเรียกคืนจุดตรวจสอบ มันจะมีความแข็งแกร่งกว่าการเปลี่ยนแปลงในโปรแกรม Python และช่วยสนับสนุนการคืนค่าเมื่อสร้างตัวแปรเมื่อเรียกใช้อย่างกระตือรือร้น ชอบtf.train.Checkpointมากกว่า tf.train.Saverรหัสใหม่

นี่คือตัวอย่าง:

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)

ข้อมูลเพิ่มเติมและตัวอย่างที่นี่


7

สำหรับtensorflow 2.0มันง่ายเหมือน

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

ในการกู้คืน:

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

สิ่งที่เกี่ยวกับการดำเนินการ TF ที่กำหนดเองและตัวแปรที่ไม่ได้เป็นส่วนหนึ่งของวัตถุรูปแบบ? พวกเขาจะได้รับการบันทึกอย่างใดเมื่อคุณเรียกใช้ save () ในโมเดลหรือไม่ ฉันมีการสูญเสียที่กำหนดเองและการแสดงออกของความน่าจะเป็นแบบเทนเซอร์กระแสที่ใช้ในการอนุมานและเครือข่ายการสร้าง แต่พวกเขาไม่ได้เป็นส่วนหนึ่งของแบบจำลองของฉัน วัตถุโมเดล keras ของฉันมีเลเยอร์หนาแน่นและ Conv เท่านั้น ใน TF 1 ฉันเพิ่งเรียกว่าวิธีการบันทึกและฉันสามารถมั่นใจได้ว่าทุกการดำเนินการและเทนเซอร์ที่ใช้ในกราฟของฉันจะได้รับการบันทึก ใน TF2 ฉันไม่เห็นว่าการดำเนินการที่ไม่ได้เพิ่มลงในโมเดล keras จะได้รับการบันทึกอย่างไร
Kristof

มีข้อมูลเพิ่มเติมเกี่ยวกับการกู้คืนโมเดลใน TF 2.0 หรือไม่ ฉันไม่สามารถเรียกคืนตุ้มน้ำหนักจากไฟล์จุดตรวจที่สร้างผ่าน C api โปรดดู: stackoverflow.com/questions/57944786/…
jregalad

@regalad: มันซับซ้อน บางทีคำถามของฉันที่stackoverflow.com/questions/56340852/... stackoverflow.com/questions/55849309/... stackoverflow.com/questions/55829593/... stackoverflow.com/questions/55829043/...และstackoverflow.com/questions/55490885/...สามารถช่วย
serv-inc

5

tf.keras รุ่นประหยัดด้วย TF2.0

ฉันเห็นคำตอบที่ยอดเยี่ยมสำหรับการบันทึกแบบจำลองโดยใช้ TF1.x ฉันต้องการให้คำแนะนำเพิ่มเติมในการบันทึกtensorflow.kerasแบบจำลองซึ่งมีความซับซ้อนเล็กน้อยเนื่องจากมีหลายวิธีในการบันทึกแบบจำลอง

ที่นี่ฉันให้ตัวอย่างของการบันทึกtensorflow.kerasแบบจำลองไปยังmodel_pathโฟลเดอร์ภายใต้ไดเรกทอรีปัจจุบัน วิธีนี้ใช้ได้ดีกับ tensorflow (TF2.0) ล่าสุด ฉันจะอัปเดตคำอธิบายนี้หากมีการเปลี่ยนแปลงในอนาคตอันใกล้

การบันทึกและการโหลดแบบจำลองทั้งหมด

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

การบันทึกและการโหลดน้ำหนักแบบจำลองเท่านั้น

หากคุณมีความสนใจในการบันทึกน้ำหนักแบบจำลองเท่านั้นจากนั้นโหลดน้ำหนักเพื่อเรียกคืนโมเดลจากนั้น

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

การบันทึกและกู้คืนโดยใช้การเรียกกลับ keras

# include the epoch in the file name. (uses `str.format`)
checkpoint_path = "training_2/cp-{epoch:04d}.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)

cp_callback = tf.keras.callbacks.ModelCheckpoint(
    checkpoint_path, verbose=1, save_weights_only=True,
    # Save weights, every 5-epochs.
    period=5)

model = create_model()
model.save_weights(checkpoint_path.format(epoch=0))
model.fit(train_images, train_labels,
          epochs = 50, callbacks = [cp_callback],
          validation_data = (test_images,test_labels),
          verbose=0)

latest = tf.train.latest_checkpoint(checkpoint_dir)

new_model = create_model()
new_model.load_weights(latest)
loss, acc = new_model.evaluate(test_images, test_labels)
print("Restored model, accuracy: {:5.2f}%".format(100*acc))

รูปแบบการบันทึกด้วยเมตริกที่กำหนดเอง

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

การบันทึกโมเดล keras ด้วย ops ที่กำหนดเอง

เมื่อเรามี ops ที่กำหนดเองดังในกรณีต่อไปนี้ ( tf.tile) เราจำเป็นต้องสร้างฟังก์ชั่นและห่อด้วยเลเยอร์แลมบ์ดา ไม่เช่นนั้นโมเดลจะไม่สามารถบันทึกได้

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

ฉันคิดว่าฉันได้ครอบคลุมหลายวิธีในการบันทึกแบบจำลอง tf.keras อย่างไรก็ตามยังมีอีกหลายวิธี โปรดแสดงความคิดเห็นด้านล่างหากคุณเห็นกรณีการใช้งานของคุณไม่ได้กล่าวถึงข้างต้น ขอบคุณ!


3

ใช้ tf.train.Saver เพื่อบันทึกโมเดล remerber คุณต้องระบุ var_list หากคุณต้องการลดขนาดของโมเดล val_list สามารถเป็น tf.trainable_variables หรือ tf.global_variables


3

คุณสามารถบันทึกตัวแปรในเครือข่ายโดยใช้

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

ในการกู้คืนเครือข่ายเพื่อนำมาใช้ใหม่ในภายหลังหรือในสคริปต์อื่นให้ใช้:

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

จุดสำคัญ:

  1. sess ต้องเหมือนกันระหว่างการรันครั้งแรกและครั้งต่อไป (โครงสร้างที่สอดคล้องกัน)
  2. saver.restore ต้องการพา ธ ของโฟลเดอร์ของไฟล์ที่บันทึกไม่ใช่พา ธ ไฟล์แต่ละไฟล์

2

ทุกที่ที่คุณต้องการบันทึกโมเดล

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

ตรวจสอบให้แน่ใจว่าทุกคนtf.Variableมีชื่อเพราะคุณอาจต้องการกู้คืนพวกเขาในภายหลังโดยใช้ชื่อ และสถานที่ที่คุณต้องการทำนาย

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

ตรวจสอบให้แน่ใจว่าโปรแกรมรักษาความปลอดภัยทำงานภายในเซสชันที่เกี่ยวข้อง โปรดจำไว้ว่าหากคุณใช้งานtf.train.latest_checkpoint('./')จะมีเฉพาะจุดตรวจสอบล่าสุดเท่านั้น


2

ฉันใช้เวอร์ชั่น:

tensorflow (1.13.1)
tensorflow-gpu (1.13.1)

วิธีง่ายๆคือ

บันทึก:

model.save("model.h5")

Restore:

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

2

สำหรับ tensorflow-2.0

มันง่ายมาก

import tensorflow as tf

ประหยัด

model.save("model_name")

เรียกคืน

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

1

ต่อไปนี้เป็นคำตอบของ @Vishnuvardhan Janapati นี่เป็นอีกวิธีหนึ่งในการบันทึกและโหลดโมเดลใหม่ด้วยเลเยอร์ / เมตริก / การสูญเสียที่กำหนดเองภายใต้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})  

ด้วยวิธีนี้เมื่อคุณเรียกใช้รหัสดังกล่าวและบันทึกโมเดลของคุณด้วยtf.keras.models.save_modelหรือmodel.saveหรือModelCheckpointโทรกลับคุณสามารถโหลดโมเดลของคุณอีกครั้งโดยไม่จำเป็นต้องใช้วัตถุที่กำหนดเองที่แม่นยำเพียงง่ายๆ

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

0

ในรุ่นใหม่ของ tensorflow 2.0 กระบวนการของการบันทึก / การโหลดแบบจำลองนั้นง่ายกว่ามาก เนื่องจากการใช้ Keras API ซึ่งเป็น API ระดับสูงสำหรับ TensorFlow

วิธีบันทึกโมเดล: ตรวจสอบเอกสารประกอบเพื่อการอ้างอิง: 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)

ในการโหลดโมเดล:

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

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

0

นี่คือตัวอย่างง่ายๆที่ใช้รูปแบบTensorflow 2.0 SavedModel (ซึ่งเป็นรูปแบบที่แนะนำตามเอกสาร )สำหรับตัวจำแนกชุดข้อมูล MNIST แบบง่ายโดยใช้ Keras functional API โดยไม่ต้องจินตนาการมากเกินไป:

# 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

คือserving_defaultอะไร

เป็นชื่อของdef ลายเซ็นต์ของแท็กที่คุณเลือก (ในกรณีนี้serveแท็กเริ่มต้นถูกเลือก) นอกจากนี้ที่นี่saved_model_cliอธิบายถึงวิธีการที่จะหาของแท็กและลายเซ็นของรูปแบบการใช้

การปฏิเสธความรับผิด

นี่เป็นเพียงตัวอย่างพื้นฐานหากคุณต้องการทำให้มันใช้งานได้ แต่ไม่ได้เป็นคำตอบที่สมบูรณ์ - บางทีฉันอาจปรับปรุงได้ในอนาคต ฉันแค่ต้องการยกตัวอย่างง่ายๆโดยใช้SavedModelใน TF 2.0 เพราะฉันไม่เคยเห็นแม้แต่สิ่งนี้เรียบง่ายทุกที่

@ Tom 's คำตอบเป็นตัวอย่าง SavedModel แต่จะไม่ทำงานกับ Tensorflow 2.0 เพราะน่าเสียดายที่มีการเปลี่ยนแปลงบางอย่าง

@ คำตอบของVishnuvardhan Janapatiพูดว่า TF 2.0 แต่ไม่ใช่สำหรับรูปแบบ SavedModel

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.