5 votes

Sauvegarde et chargement de modèle Tensorflow

Comment sauvegarder un modèle tensorflow avec un graphique de modèle comme nous le faisons dans keras. Au lieu de redéfinir tout le graphique à nouveau dans le fichier de prédiction, pouvons-nous sauvegarder le modèle entier (poids et graphe) et l'importer ultérieurement

Dans Keras:

checkpoint = ModelCheckpoint('RightLane-{epoch:03d}.h5',monitor='val_loss', verbose=0,  save_best_only=False, mode='auto')

donnera un fichier h5 que nous pouvons utiliser pour la prédiction

model = load_model("RightLane-030.h5")

comment faire la même chose en tensorflow natif

4voto

BiBi Points 1193

Méthode 1: Geler le graphe et les poids dans un seul fichier (la reformation pourrait ne pas être possible)

Cette option montre comment enregistrer le graphe et les poids dans un seul fichier. Son cas d'utilisation prévu est le déploiement/partage d'un modèle après son entraînement. À cette fin, nous utiliserons le format protobuf (pb).

Étant donné une session tensorflow (et un graphe), vous pouvez générer un protobuf avec

# geler les variables
output_graph_def = tf.graph_util.convert_variables_to_constants(
                               sess=sess,
                               input_graph_def=sess.graph.as_graph_def(),
                               output_node_names=['myMode/conv/output'])

# écrire le protobuf sur le disque
with tf.gfile.GFile('graph.pb', "wb") as f:
    f.write(output_graph_def.SerializeToString())

output_node_names attend une liste de chaînes de noms pour les nœuds de résultat du graphe (cf. documentation de tensorflow).

Ensuite, vous pouvez charger le protobuf et obtenir le graphe avec ses poids pour effectuer facilement des passes en avant.

with tf.gfile.GFile(chemin_vers_pb, "rb") as f:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())
with tf.Graph().as_default() as graph:
    tf.import_graph_def(graph_def, name='')
    return graphe

Méthode 2: Restaurer le metagraph et le checkpoint (reformation facile)

Si vous souhaitez pouvoir continuer à entraîner le modèle, vous devrez peut-être restaurer le graphe complet, c'est-à-dire les poids mais aussi la fonction de perte, certaines informations de gradient (par exemple pour l'optimiseur Adam), etc.

Vous avez besoin des fichiers meta et checkpoint générés par tensorflow lorsque vous utilisez

saver = tf.train.Saver(...variables...)
saver.save(sess, 'mon-modele')

Cela générera deux fichiers, mon-modele et mon-modele.meta.

À partir de ces deux fichiers, vous pouvez charger le graphe avec:

  new_saver = tf.train.import_meta_graph('mon-modele.meta')
  new_saver.restore(sess, 'mon-modele')

Pour plus de détails, vous pouvez consulter la documentation officielle.

0voto

swiftg Points 306

Ceci est un exemple complet basé sur tensorflow github. Je l'ai copié d'une autre réponse que j'ai faite ailleurs sur SO. Il y a probablement d'autres/meilleures façons de le faire quelque part.

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import numpy as np
import pandas as pd
import argparse
import sys
import tempfile
​
from tensorflow.examples.tutorials.mnist import input_data
​
import tensorflow as tf
​
FLAGS = None
​
​
def deepnn(x):
  """deepnn construit le graphique pour un réseau neuronal profond pour classifier les chiffres.
​
  Args:
    x: un tenseur d'entrée avec des dimensions (N_exemples, 784), où 784 est le
    nombre de pixels dans une image MNIST standard.
​
  Returns:
    Un tuple (y, keep_prob). y est un tenseur de forme (N_exemples, 10), avec des valeurs
    égales aux logits de classification du chiffre dans l'une des 10 classes (les
    chiffres 0-9). keep_prob est un paramètre scalaire pour la probabilité de
    dropout.
  """
  # Reshape pour une utilisation dans un réseau neuronal convolutif.
  # La dernière dimension est pour "features" - il y en a une seule ici, puisque les images sont
  # en niveaux de gris - ce serait 3 pour une image RGB, 4 pour une image RGBA, etc.
  with tf.name_scope('reshape'):
    x_image = tf.reshape(x, [-1, 28, 28, 1])
​
  # Première couche convolutive - mappe une image en niveaux de gris vers 32 cartes de caractéristiques.
  with tf.name_scope('conv1'):
    W_conv1 = weight_variable([5, 5, 1, 32])
    b_conv1 = bias_variable([32])
    h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
​
  # Couche de pooling - diminue par 2X.
  with tf.name_scope('pool1'):
    h_pool1 = max_pool_2x2(h_conv1)
​
  # Deuxième couche convolutive - mappe 32 cartes de caractéristiques vers 64.
  with tf.name_scope('conv2'):
    W_conv2 = weight_variable([5, 5, 32, 64])
    b_conv2 = bias_variable([64])
    h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
​
  # Deuxième couche de pooling.
  with tf.name_scope('pool2'):
    h_pool2 = max_pool_2x2(h_conv2)
​
  # Couche complètement connectée 1 - après 2 rounds de réduction, notre image 28x28
  # est réduite à 7x7x64 cartes de caractéristiques - mappe cela à 1024 caractéristiques.
  with tf.name_scope('fc1'):
    W_fc1 = weight_variable([7 * 7 * 64, 1024])
    b_fc1 = bias_variable([1024])
​
    h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
​
  # Dropout - contrôle la complexité du modèle, empêche la co-adaptation des
  # caractéristiques.
​
  keep_prob = tf.placeholder_with_default(1.0,())
  h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
​
  # Mappe les 1024 caractéristiques vers 10 classes, une pour chaque chiffre
  with tf.name_scope('fc2'):
    W_fc2 = weight_variable([1024, 10])
    b_fc2 = bias_variable([10])
​
    y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2
  return y_conv, keep_prob
​
​
def conv2d(x, W):
  """conv2d renvoie une couche de convolution 2d avec un pas complet."""
  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
​
​
def max_pool_2x2(x):
  """max_pool_2x2 réduit la taille d'une carte de caractéristiques de moitié."""
  return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                        strides=[1, 2, 2, 1], padding='SAME')
​
​
def weight_variable(shape):
  """weight_variable génère une variable de poids de la forme donnée."""
  initial = tf.truncated_normal(shape, stddev=0.1)
  return tf.Variable(initial)
​
​
def bias_variable(shape):
  """bias_variable génère une variable de biais de la forme donnée."""
  initial = tf.constant(0.1, shape=shape)
  return tf.Variable(initial)
​
​
# Importation des données
mnist = input_data.read_data_sets("/tmp")
# Crée le modèle
x = tf.placeholder(tf.float32, [None, 784], name="x")
# Définit la perte et l'optimiseur
y_ = tf.placeholder(tf.int64, [None])
# Construit le graphique pour le réseau profond
y_conv, keep_prob = deepnn(x)
with tf.name_scope('loss'):
    cross_entropy = tf.losses.sparse_softmax_cross_entropy(
        labels=y_, logits=y_conv)
    cross_entropy = tf.reduce_mean(cross_entropy)
​
with tf.name_scope('adam_optimizer'):
    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
​
with tf.name_scope('accuracy'):
    correct_prediction = tf.equal(tf.argmax(y_conv, 1), y_)
    correct_prediction = tf.cast(correct_prediction, tf.float32)
    accuracy = tf.reduce_mean(correct_prediction)
​
graph_location = tempfile.mkdtemp()
print('Enregistrement du graphique dans: %s' % graph_location)
train_writer = tf.summary.FileWriter(graph_location)
train_writer.add_graph(tf.get_default_graph())
​
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for i in range(1000):
      batch = mnist.train.next_batch(50)
      if i % 100 == 0:
        train_accuracy = accuracy.eval(feed_dict={
            x: batch[0], y_: batch[1], keep_prob: 1.0})
        print('étape %d, précision de l'entraînement %g' % (i, train_accuracy))
      train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})
​
    print('précision du test %g' % accuracy.eval(feed_dict={
        x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))

    simg = np.reshape(mnist.test.images[0],(-1,784))    
    output = sess.run(y_conv,feed_dict={x:simg,keep_prob:1.0})
    print(tf.argmax(output,1).eval())
    saver = tf.train.Saver()
    saver.save(sess,"/tmp/network")

Restauration à partir d'une nouvelle exécution python :

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf
import numpy as np

import argparse
import sys
import tempfile
from tensorflow.examples.tutorials.mnist import input_data

sess =  tf.Session() 
saver = tf.train.import_meta_graph('/tmp/network.meta')
saver.restore(sess,tf.train.latest_checkpoint('/tmp'))
graph = tf.get_default_graph()
mnist = input_data.read_data_sets("/tmp")
simg = np.reshape(mnist.test.images[0],(-1,784))
op_to_restore = graph.get_tensor_by_name("fc2/MatMul:0")
x = graph.get_tensor_by_name("x:0")
output = sess.run(op_to_restore,feed_dict= {x:simg})
print("Résultat = ", np.argmax(output))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X