Tensorflow: як зберегти / відновити модель?


552

Після того як ви тренуєте модель в Tensorflow:

  1. Як ви зберігаєте навчену модель?
  2. Як згодом відновити цю збережену модель?

Чи вдалося відновити змінні, які використовувались у моделі створення? Я також намагаюся точно цю проблему, але я не можу написати набір змінних, які використовувались під час навчання моделі створення (з яких у мене файл ckpt)
exAres

Я не пробував з початковою моделлю. Чи є у вас мережева структура моделі з її назвами? Ви повинні копіювати мережу, а потім завантажувати ваги та ухили (файл ckpt), як пояснює Райан. Можливо, щось змінилося з 15 листопада, і зараз є більш прямолінійний підхід, я не впевнений
mathetes

Ой гаразд. Раніше я завантажував інші заздалегідь підготовлені моделі тензорфлоу, але шукав змінні технічні характеристики початкової моделі. Дякую.
exAres

1
Якщо ви відновитесь, щоб продовжувати тренуватися, просто використовуйте контрольно-пропускні пункти Saver. Якщо ви збережете модель для посилання, просто API тензорного SavedModel.
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.

Пітон 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. Ми отримуємо згенерований ітератором тензор, званийinput_tensor який входом до нашої моделі.
  2. Сама модель побудована з input_tensor: двонаправленої RNN на основі ГРУ з наступним щільним класифікатором. Бо чому б ні.
  3. Втрати softmax_cross_entropy_with_logits, оптимізовані за допомогою Adam. Після 2 епох (по 2 партії кожна) ми зберігаємо «навчену» модель за допомогою tf.saved_model.simple_save. Якщо запустити код таким, який є, модель буде збережена у папці, що називається simple/у вашій поточній робочій директорії.
  4. У новому графіку ми відновимо збережену модель за допомогою tf.saved_model.loader.load. Ми захоплюємо заповнювачі та логіти, graph.get_tensor_by_nameа також Iteratorоперацію ініціалізації graph.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]. Як зазначається в документації, просте збереження спрямоване на спрощення взаємодії з подачею тензорфлоу, це суть аргументів; інші змінні все ж таки відновлюються, інакше висновок не відбудеться. Просто захопіть ваші змінні цікавлять, як я це робив у прикладі. Ознайомтеся з документацією
тед

@ted, коли я буду використовувати tf.saved_model.simple_save vs tf.train.Saver ()? Зі своєї інтуїції я би використовував tf.train.Saver () під час тренувань і зберігати різні моменти у часі. Я б використовував tf.saved_model.simple_save, коли проводиться навчання для використання у виробництві. (Я запитав те саме і в коментарі тут )
loco.loop

1
Приємно, мабуть, але чи це також працює з моделями режиму Eager і tfe.Saver?
Джеффрі Андерсон

1
без global_step аргументу, якщо ви перестанете, то спробуйте знову почати тренуватись, він подумає, що ви один крок. Це як мінімум накрутить ваші візуалізації на
тензорній дошці

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 ('bias: 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їх до імен?
Сахар Рабіновіз

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
Саад Куреші

2
Коли після відновлення я отримую доступ до змінних, як показано вище, це працює. Але я не можу отримати змінні більш безпосередньо, використовуючи tf.get_variable_scope().reuse_variables()наступні var = tf.get_variable("varname"). Це дає мені помилку: "ValueError: Ім'я змінної не існує або не було створено за допомогою tf.get_variable ()." Чому? Чи це не можливо?
Йоганн Петрак

4
Це добре працює лише для змінних, але як можна отримати доступ до заповнювача та значення подачі до нього після відновлення графіка?
кбросе

11
Це лише показує, як відновити змінні. Як можна відновити всю модель і протестувати її на нових даних, не визначаючи мережу?
Chaine

127

Для версії TensorFlow <0,11.0RC1:

Збережені контрольні точки містять значення для Variables у вашій моделі, а не модель / графік, а це означає, що графік повинен бути однаковим при відновленні контрольної точки.

Ось приклад для лінійної регресії, де є навчальний цикл, який зберігає змінні контрольні точки, і розділ оцінювання, який буде відновити змінні, збережені в попередньому запуску, та обчислити прогнози. Звичайно, ви також можете відновити змінні та продовжити навчання, якщо хочете.

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
ФЛАГИ визначені користувачем. Ось приклад їх визначення: github.com/tensorflow/tensorflow/blob/master/tensorflow/…
Ryan Sepassi

в якому форматі batch_xпотрібно бути? Бінарний? Масивний масив?
pepe

@pepe Numpy array має бути добре. І тип елемента повинен відповідати типу заповнювача. [посилання] tensorflow.org/versions/r0.9/api_docs/python/…
Донні

FLAGS видає помилку undefined. Чи можете ви сказати мені, що є FLAGS для цього коду. @RyanSepassi
Muhammad Hannan

Для того, щоб зробити його явним: Останні версії Tensorflow дійсно дозволяють зберегти модель / графік. [Мені було незрозуміло, які аспекти відповіді стосуються обмеження <0,11. Враховуючи велику кількість оновлень, я спокусився повірити, що це загальне твердження все-таки актуальне для останніх версій.]
bluenote10

78

Моє середовище: Python 3.6, Tensorflow 1.3.0

Хоча рішень було багато, більшість з них базується на tf.train.Saver. Коли ми завантажуємо .ckptврятовані Saver, ми повинні або переглянути мережу 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 - чудовий приклад API SavedModel. Однак я хочу, щоб у розділі " Зберегти модель " було показано навчальний цикл, як відповідь Райана Сепассі! Я розумію, що це давнє запитання, але ця відповідь - один з небагатьох (і цінних) прикладів SavedModel, який я знайшов у Google.
Ділан F

@Том це чудова відповідь - лише одна спрямована на новий SavedModel. Не могли б Ви ознайомитися з цим питанням SavedModel? stackoverflow.com/questions/48540744 / ...
bluesummers

Тепер змусьте це правильно працювати з моделями TF Eager. У своїй презентації 2018 рік Google порадив усім відмовитися від коду графіка TF.
Джеффрі Андерсон

55

Моделі є дві частини, визначення моделі, збережене Supervisorяк graph.pbtxtу каталозі моделі, і числові значення тензорів, збережені у файли контрольних точок model.ckpt-1003418.

Визначення моделі можна відновити за допомогою tf.import_graph_def, а ваги відновити за допомогою Saver.

Однак Saverвикористовується спеціальний перелік змінних, що містить колекцію, що додається до моделі Graph, і ця колекція не ініціалізується за допомогою import_graph_def, тому ви не можете використовувати їх разом разом (це є на нашому дорожньому карті для виправлення). Поки що ви повинні використовувати підхід Раяна Сепассі - вручну побудувати графік з однаковими назвами вузлів і використовувати Saverдля завантаження ваг у нього.

(Або ви можете зламати його, використовуючи import_graph_def, створюючи змінні вручну та використовуючи tf.add_to_collection(tf.GraphKeys.VARIABLES, variable)для кожної змінної, а потім використовуючи Saver)


У прикладі classify_image.py, який використовує inceptionv3, завантажується тільки graphdef. Чи означає це, що тепер GraphDef також містить змінну?
jrabary

1
@jrabary Модель, ймовірно, заморожена .
Ерік Платон

1
Гей, я новачок у тензорфлоу і у мене виникають проблеми зі збереженням моделі. Я був би дуже вдячний, якби ви могли б мені допомогти 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)

Привіт, як я можу зберегти модель після припущення 3000 ітерацій, схожих на Caffe. Я дізнався, що tensorflow зберігає лише останні моделі, незважаючи на те, що я пов'язую ітераційне число з моделлю, щоб диференціювати його серед усіх ітерацій. Я маю на увазі model_3000.ckpt, model_6000.ckpt, --- model_100000.ckpt. Чи можете ви люб'язно пояснити, чому це не рятує всі, а зберігає лише останні 3 ітерації.
хан


3
Чи існує метод отримання всіх змінних / імен операцій, збережених у графі?
Мондра

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)

Швидке пояснення: коли ви створюєте змінну X, TensorFlow автоматично створює операцію призначення, X/Assignщоб встановити початкове значення змінної. Замість того, щоб створювати заповнювачі та додаткові опції присвоєння (що просто зробить графік безладним), ми просто використовуємо ці наявні операційні можливості призначення. Перший вхід кожного оператора призначення - це посилання на змінну, яку слід ініціалізувати, а другий вхід ( assign_op.inputs[1]) - початкове значення. Отже, щоб встановити будь-яке значення, яке ми хочемо (замість початкового значення), нам потрібно використовувати a feed_dictі замінити початкове значення. Так, TensorFlow дозволяє подавати значення для будь-якої опції, а не лише для заповнювачів, тому це прекрасно працює.


Дякую за відповідь. У мене є подібне запитання про те, як перетворити один .ckpt файл у два .index та .data файли (скажімо, для попередньо підготовлених початкових моделей, доступних у tf.slim). Моє запитання тут: stackoverflow.com/questions/47762114/…
Амір

Гей, я новачок у тензорфлоу і у мене виникають проблеми зі збереженням моделі. Я був би дуже вдячний, якби ви могли б мені допомогти stackoverflow.com/questions/48083474 / ...
Ruchir Baronia

17

Як сказав Ярослав, ви можете зламати відновлення з graph_def та контрольної точки, імпортуючи графік, створивши змінні вручну та використовуючи Saver.

Я реалізував це для особистого використання, тому хоч би поділився кодом тут.

Посилання: https://gist.github.com/nikitakit/6ef3b72be67b86cb7868

(Це, звичайно, хак, і немає гарантії, що збережені таким чином моделі залишаться читабельними у майбутніх версіях TensorFlow.)


14

Якщо це внутрішня збережена модель, ви просто вкажете реставратор для всіх змінних як

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

Гей, я новачок у тензорфлоу і у мене виникають проблеми зі збереженням моделі. Я був би дуже вдячний, якби ви могли б мені допомогти 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 зробить самі імена унікальними, і вони таким чином будуть відрізнятися від імен, що зберігаються у файлі. Це не проблема в попередній техніці, оскільки імена "керуються" однаково при завантаженні та збереженні.

Збереження

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 добре, дякую за Ваш відгук, я відредагую відповідь відповідно до ваших пропозицій;)
Мартін Печка

10

Ви також можете ознайомитись із прикладами в TensorFlow / skflow , який пропонує saveта restoreметоди, які допоможуть вам легко керувати своїми моделями. У ньому є параметри, за допомогою яких ви також можете контролювати, як часто ви хочете створювати резервну копію вашої моделі.


9

Якщо ви використовуєте tf.train.MonitoredTrainingSession як сеанс за замовчуванням, вам не потрібно додавати додатковий код для збереження / відновлення речей. Просто передайте ім'я dir контрольної точки конструктору MonitoredTrainingSession, він буде використовувати гачки сеансу для їх обробки.


за допомогою tf.train.Supervisor обробляє створення такого сеансу для вас і пропонує більш повне рішення.
Марк

1
@Mark tf.train.Supervisor застарілий
Changming Sun

Чи є у вас якесь посилання, що підтверджує твердження, що Supervisor застарів? Я не бачив нічого, що свідчить про це так.
Марк


Дякую за URL-адресу - я перевірив оригінальне джерело інформації, і мені сказали, що, ймовірно, буде до кінця серії TF 1.x, але гарантій після цього немає.
Марк

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, який записує та зчитує контрольні точки на основі varia.name. Контрольна точка на основі об'єктів зберігає графік залежностей між об'єктами 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 () на модель? У мене є різні спеціальні вирази втрат і тензорфлоун-ймовірності, які використовуються в мережі висновку та генерації, але вони не є частиною моєї моделі. Мій об'єкт моделі керас містить лише щільний та обертаний шари. У TF 1 я просто назвав метод збереження, і я міг бути впевнений, що всі операції та тензори, використані в моєму графіку, будуть збережені. У TF2 я не бачу, як операції, які якимось чином не додаються до моделі keras, будуть збережені.
Крістоф

Чи є ще інформація про відновлення моделей у TF 2.0? Я не можу відновити ваги з контрольних файлів , що генеруються з допомогою C API, см: stackoverflow.com/questions/57944786 / ...
jregalad


5

tf.keras Збереження моделі за допомогою TF2.0

Я бачу чудові відповіді щодо збереження моделей за допомогою TF1.x. Я хочу надати ще декілька покажчиків на збереження tensorflow.kerasмоделей, що трохи складніше, оскільки існує багато способів збереження моделі.

Тут я наводимо приклад збереження tensorflow.kerasмоделі в model_pathпапці під поточним каталогом. Це добре працює з останнім тензорфолом (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})

Збереження моделі керас з користувальницькими операційними можливостями

Коли у нас є власні опції, як у наступному випадку ( 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")

Відновлювати:

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 процес збереження / завантаження моделі набагато простіше. Через впровадження API Keras, 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 функціонального 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?

Це ім'я визначення підпису вибраного вами тега (у цьому випадку serveвибрано тег за замовчуванням ). Також тут пояснюється, як знайти тег та підписи моделі за допомогою saved_model_cli.

Відмова від відповідальності

Це лише основний приклад, якщо ви просто хочете його вставити та працювати, але аж ніяк не є повною відповіддю - можливо, я можу це оновити в майбутньому. Я просто хотів навести простий приклад, використовуючи SavedModelв TF 2.0, тому що я його ще ніде не бачив.

@ Відповідь Тома - приклад SavedModel, але він не працюватиме на Tensorflow 2.0, тому що, на жаль, є деякі неполадки.

@ Відповідь Вишнувардхана Джанапаті говорить TF 2.0, але це не для формату SavedModel.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.