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
Répondre
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)
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})
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. –
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)
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. –
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'. –