2017-02-14 1 views
3

Je fais un exemple de boosting (4 couches DNN à 5 couches DNN) via Tensorflow. Je le fais avec save session et restaure dans TF car il y a un court paragraphe dans TF tute: 'Par exemple, vous avez peut-être entraîné un réseau de neurones avec 4 couches, et vous voulez maintenant former un nouveau modèle avec 5 couches, restaurer les paramètres des 4 couches du modèle précédemment formé dans les 4 premières couches du nouveau modèle. », où tute tensorflow inspire https://www.tensorflow.org/how_tos/variables/.Restaurer les variables qui sont un sous-ensemble du nouveau modèle dans Tensorflow?

Cependant, j'ai trouvé que personne n'a demandé comment utiliser 'restore' quand le point de contrôle enregistre les paramètres de 4 couches mais nous devons mettre cela en 5 couches, en levant un drapeau rouge.

Faire dans votre code, j'ai fait

with tf.name_scope('fcl1'): 
    hidden_1 = fully_connected_layer(inputs, train_data.inputs.shape[1], num_hidden)    
with tf.name_scope('fcl2'): 
    hidden_2 = fully_connected_layer(hidden_1, num_hidden, num_hidden)     
with tf.name_scope('fclf'): 
    hidden_final = fully_connected_layer(hidden_2, num_hidden, num_hidden)  
with tf.name_scope('outputl'): 
    outputs = fully_connected_layer(hidden_final, num_hidden, train_data.num_classes, tf.identity) 
    outputs = tf.nn.softmax(outputs) 
with tf.name_scope('boosting'): 
    boosts = fully_connected_layer(outputs, train_data.num_classes, train_data.num_classes, tf.identity) 

où les variables à l'intérieur (ou appelé de) 'FCL1' - pour que j'ai 'FCL1/variable' et 'FCL1/Variable_1' pour le poids et les préjugés - 'fcl2', 'fclf' et 'outputl' sont stockés par saver.save() dans le script sans couche 'boosting'. Cependant, comme nous l'avons maintenant la couche « stimuler », saver.restore (sess, « saved_models/model_list.ckpt ») ne fonctionne pas comme

NotFoundError: Key boosting/Variable_1 not found in checkpoint 

J'espère vraiment entendre parler de ce problème. Je vous remercie. Ci-dessous le code est la partie principale du code que je suis en difficulté.

def fully_connected_layer(inputs, input_dim, output_dim, nonlinearity=tf.nn.relu): 
    weights = tf.Variable(
     tf.truncated_normal(
      [input_dim, output_dim], stddev=2./(input_dim + output_dim)**0.5), 
     'weights') 
    biases = tf.Variable(tf.zeros([output_dim]), 'biases') 
    outputs = nonlinearity(tf.matmul(inputs, weights) + biases)  

    return outputs 

inputs = tf.placeholder(tf.float32, [None, train_data.inputs.shape[1]], 'inputs') 
targets = tf.placeholder(tf.float32, [None, train_data.num_classes], 'targets') 

with tf.name_scope('fcl1'): 
    hidden_1 = fully_connected_layer(inputs, train_data.inputs.shape[1], num_hidden)    
with tf.name_scope('fcl2'): 
    hidden_2 = fully_connected_layer(hidden_1, num_hidden, num_hidden)     
with tf.name_scope('fclf'): 
    hidden_final = fully_connected_layer(hidden_2, num_hidden, num_hidden)  
with tf.name_scope('outputl'): 
    outputs = fully_connected_layer(hidden_final, num_hidden, train_data.num_classes, tf.identity) 

with tf.name_scope('error'):  
    error = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(outputs, targets)) 
with tf.name_scope('accuracy'): 
    accuracy = tf.reduce_mean(tf.cast(
     tf.equal(tf.argmax(outputs, 1), tf.argmax(targets, 1)), 
     tf.float32)) 
with tf.name_scope('train'): 
    train_step = tf.train.AdamOptimizer().minimize(error) 

init = tf.global_variables_initializer() 
saver = tf.train.Saver() 

with tf.Session() as sess: 
    sess.run(init) 
    saver.restore(sess, "saved_models/model.ckpt") 
    print("Model restored") 

    print("Optimization Starts!") 
    for e in range(training_epochs): 
     ... 

    #Save model - save session   
    save_path = saver.save(sess, "saved_models/model.ckpt") 
    ### I once saved the variables using var_list, but didn't work as well... 
    print("Model saved in file: %s" % save_path) 

Pour plus de clarté, le fichier point de contrôle a

fcl1/Variable:0 

fcl1/Variable_1:0 

fcl2/Variable:0 

fcl2/Variable_1:0 

fclf/Variable:0 

fclf/Variable_1:0 

outputl/Variable:0 

outputl/Variable_1:0 

Comme le modèle 4 couches d'origine n'a pas la couche 'stimuler'.

+0

Vous pouvez restaurer le modèle à l'aide du paramètre '' var_list' du tf.Saver' [constructeur] (https://www.tensorflow.org/api_docs/python/state_ops/save_and_restoring_variables). Vous serez ensuite responsable de l'initialisation de la couche 5 correctement. – drpng

Répondre

5

Il ne semble pas correct de lire les valeurs pour augmenter le point de contrôle dans ce cas et je pense que ce n'est pas ce que vous voulez faire. Évidemment, vous obtenez une erreur, car lors de la restauration des variables, vous commencez par attraper la liste de toutes les variables de votre modèle, puis vous recherchez les variables correspondantes dans votre point de contrôle, qui n'en possède pas.

Vous pouvez restaurer uniquement une partie de votre modèle en définissant un sous-ensemble de vos variables de modèle. Par exemple, vous pouvez le faire en utilisant la bibliothèque tf.slim. Obtenir la liste des variables dans vos modèles:

variables = slim.get_variables_to_restore() 

maintenant variables est une liste des tenseurs, mais pour chaque élément, vous pouvez accéder à son attribut name. En utilisant cela, vous pouvez spécifier que vous ne voulez restaurer que les couches, par exemple:

variables_to_restore = [v for v in variables if v.name.split('/')[0]!='boosting'] 
model_path = 'your/model/path' 

saver = tf.train.Saver(variables_to_restore) 

with tf.Session() as sess: 
    saver.restore(sess, model_path) 

De cette façon, vos 4 couches seront restaurées. Théoriquement, vous pourriez essayer d'attraper les valeurs d'une de vos variables à partir du point de contrôle en créant un autre serveur qui ne fera qu'accroître dans la liste des variables et renommer la variable choisie du point de contrôle, mais je ne pense pas que ce soit nécessaire.

Puisqu'il s'agit d'un calque personnalisé pour votre modèle et que vous n'avez nulle part ailleurs cette variable, il suffit de l'initialiser dans votre flux de travail au lieu d'essayer de l'importer. Vous pouvez le faire par exemple en faisant passer cet argument tout en appelant une fonction fully_connected:

weights_initializer = slim.variance_scaling_initializer() 

Vous devez vérifier vous détails bien, puisque je ne suis pas sûr de ce que vos importations et qui fonctionnent utilisez-vous ici.

Généralement je vous conseille de jeter un coup d'oeil à la bibliothèque mince, ce qui vous aidera à définir un modèle et des étendues pour les calques (au lieu de le définir avec vous pouvez passer un argument scope en appelant un fonction). Il ressemblerait à quelque chose comme ça avec mince:

boost = slim.fully_connected(input, number_of_outputs, activation_fn=None, scope='boosting', weights_initializer=slim.variance_scaling_initializer()) 
+0

Merci. Ça marche! En fait, «mince» n'était pas nécessaire dans mon cas. – sdr2002