2016-09-06 2 views
1

Je voudrais exécuter un modèle donné à la fois sur l'ensemble de train (is_training=True) et sur l'ensemble de validation (is_training=False), en particulier sur la façon dont dropout est appliqué. En ce moment, le prebuilt models expose un paramètre is_training qui lui est passé la couche dropout lors de la construction du réseau. Le problème est que si j'appelle la méthode deux fois avec des valeurs différentes de is_training, j'obtiendrai deux réseaux différents qui ne partagent pas de poids (je pense?). Comment puis-je obtenir que les deux réseaux partagent les mêmes poids de sorte que je puisse exécuter le réseau que j'ai formé sur le jeu de validation?Tensorflow (tf-slim) Modèle avec is_training Vrai et Faux

+0

Je pense que le comportement par défaut est de partager des poids entre les deux cas, de sorte que vous n'avez rien à faire. 'tf-slim' utilise' tf.get_variable() 'qui réutilise les variables entre les appels. –

+0

D'accord, je pense que cela fonctionne principalement. Vous devez vous assurer que 'scope' est défini et que, par sécurité, il est préférable de définir' reuse = True'. –

Répondre

1

J'ai écrit une solution avec votre commentaire pour utiliser Overfeat en mode train et test. (Je ne pouvais pas le tester afin que vous puissiez vérifier si cela fonctionne?)

premier des importations et des paramètres:

import tensorflow as tf 
slim = tf.contrib.slim 
overfeat = tf.contrib.slim.nets.overfeat 

batch_size = 32 
inputs = tf.placeholder(tf.float32, [batch_size, 231, 231, 3]) 
dropout_keep_prob = 0.5 
num_classes = 1000 

En mode train, on passe une portée normale à la fonction overfeat:

scope = 'overfeat' 
is_training = True 

output = overfeat.overfeat(inputs, num_classes, is_training,   
          dropout_keep_prob, scope=scope) 

Ensuite, en mode test, nous créons la même portée mais avec reuse=True.

scope = tf.VariableScope(reuse=True, name='overfeat') 
is_training = False 

output = overfeat.overfeat(inputs, num_classes, is_training,   
          dropout_keep_prob, scope=scope) 
0

vous pouvez simplement utiliser un espace réservé pour is_training:

isTraining = tf.placeholder(tf.bool) 

# create nn 
net = ... 
net = slim.dropout(net, 
        keep_prob=0.5, 
        is_training=isTraining) 
net = ... 

# training 
sess.run([net], feed_dict={isTraining: True}) 

# testing 
sess.run([net], feed_dict={isTraining: False}) 
+1

J'ai essayé ceci et ai rencontré des problèmes parce que les variables n'étaient pas réutilisées. J'ai également rencontré des restrictions de mémoire que je ne pouvais pas expliquer. –

0

Cela dépend du cas, les solutions sont différentes.

Ma première option serait d'utiliser un processus différent pour faire l'évaluation. Il vous suffit de vérifier qu'il ya un nouveau point de contrôle et de la charge qui pèse dans le réseau d'évaluation (avec is_training=False):

checkpoint = tf.train.latest_checkpoint(self.checkpoints_path) 
# wait until a new check point is available 
while self.lastest_checkpoint == checkpoint: 
    time.sleep(30) # sleep 30 seconds waiting for a new checkpoint 
    checkpoint = tf.train.latest_checkpoint(self.checkpoints_path) 
logging.info('Restoring model from {}'.format(checkpoint)) 
self.saver.restore(session, checkpoint) 
self.lastest_checkpoint = checkpoint 

La deuxième option est après chaque époque vous déchargez le graphique et créer un nouveau graphique d'évaluation . Cette solution perd beaucoup de temps à charger et décharger des graphiques.

La troisième option consiste à partager les poids. Mais l'alimentation de ces réseaux avec des files d'attente ou des ensembles de données peut entraîner des problèmes, vous devez donc être très prudent. Je l'utilise uniquement pour les réseaux siamois.

with tf.variable_scope('the_scope') as scope: 
    your_model(is_training=True) 
    scope.reuse_variables() 
    your_model(is_training=False)