J'entraîne un modèle où le vecteur d'entrée est la sortie d'un autre modèle. Cela implique de restaurer le premier modèle à partir d'un fichier de point de contrôle tout en initialisant le deuxième modèle à partir de zéro (en utilisant tf.initialize_variables()
) dans le même processus.
Il y a une quantité substantielle de code et d'abstraction, donc je ne fais que coller les sections pertinentes ici.
Voici le code de restauration:
self.variables = [var for var in all_vars if var.name.startswith(self.name)]
saver = tf.train.Saver(self.variables, max_to_keep=3)
self.save_path = tf.train.latest_checkpoint(os.path.dirname(self.checkpoint_path))
if should_restore:
self.saver.restore(self.sess, save_path)
else:
self.sess.run(tf.initialize_variables(self.variables))
Chaque modèle est défini dans son propre graphique et sa propre session, comme ceci:
self.graph = tf.Graph()
self.sess = tf.Session(graph=self.graph)
with self.sess.graph.as_default():
# Create variables and ops.
Toutes les variables de chaque modèle sont créées dans le gestionnaire de contexte variable_scope
.
L'alimentation fonctionne comme suit:
sess.run(inference_op)
sur input = scipy.misc.imread(X)
et place le résultat dans une file d'attente bloquante thread-safe.sess.run(train_op)
sur le deuxième modèle.PROBLÈME:
J'observe que les valeurs de perte, même dans la toute première itération de l'entraînement (deuxième modèle) continuent de changer radicalement d'une série à l'autre (et deviennent nan en quelques itérations). J'ai confirmé que la sortie du premier modèle est exactement la même à chaque fois. Commenter le sess.run
Du premier modèle et le remplacer par une entrée identique à partir d'un fichier mariné ne montre pas ce comportement.
Voici le train_op
:
loss_op = tf.nn.sparse_softmax_cross_entropy(network.feedforward())
# Apply gradients.
with tf.control_dependencies([loss_op]):
opt = tf.train.GradientDescentOptimizer(lr)
grads = opt.compute_gradients(loss_op)
apply_gradient_op = opt.apply_gradients(grads)
return apply_gradient_op
Je sais que c'est vague, mais je suis heureux de fournir plus de détails. Toute aide est appréciée!
Le problème se produit très certainement en raison de l'exécution simultanée de différents objets de session. J'ai déplacé la session du premier modèle du thread d'arrière-plan vers le thread principal, répété plusieurs fois l'expérience contrôlée (en cours d'exécution pendant plus de 24 heures et atteint la convergence) et je n'ai jamais observé NaN
. En revanche, l'exécution simultanée diverge le modèle en quelques minutes.
J'ai restructuré mon code pour utiliser un objet de session commun à tous les modèles.