3

J'ai un petit problème en utilisant la norme batch lors de la restauration du modèle en tensorflow.Utilisation de la norme de traitement par lots lors de la restauration du modèle?

Ci-dessous est ma norme de traitement par lots qui de here:

def _batch_normalization(self, input_tensor, is_training, batch_norm_epsilon, decay=0.999): 
    """batch normalization for dense nets. 

    Args: 
     input_tensor: `tensor`, the input tensor which needed normalized. 
     is_training: `bool`, if true than update the mean/variance using moving average, 
          else using the store mean/variance. 
     batch_norm_epsilon: `float`, param for batch normalization. 
     decay: `float`, param for update move average, default is 0.999. 

    Returns: 
     normalized params. 
    """ 
    # actually batch normalization is according to the channels dimension. 
    input_shape_channels = int(input_tensor.get_shape()[-1]) 

    # scala and beta using in the the formula like that: scala * (x - E(x))/sqrt(var(x)) + beta 
    scale = tf.Variable(tf.ones([input_shape_channels])) 
    beta = tf.Variable(tf.zeros([input_shape_channels])) 

    # global mean and var are the mean and var that after moving averaged. 
    global_mean = tf.Variable(tf.zeros([input_shape_channels]), trainable=False) 
    global_var = tf.Variable(tf.ones([input_shape_channels]), trainable=False) 

    # if training, then update the mean and var, else using the trained mean/var directly. 
    if is_training: 
     # batch norm in the channel axis. 
     axis = list(range(len(input_tensor.get_shape()) - 1)) 
     batch_mean, batch_var = tf.nn.moments(input_tensor, axes=axis) 

     # update the mean and var. 
     train_mean = tf.assign(global_mean, global_mean * decay + batch_mean * (1 - decay)) 
     train_var = tf.assign(global_var, global_var * decay + batch_var * (1 - decay)) 
     with tf.control_dependencies([train_mean, train_var]): 
      return tf.nn.batch_normalization(input_tensor, 
              batch_mean, batch_var, beta, scale, batch_norm_epsilon) 
    else: 
     return tf.nn.batch_normalization(input_tensor, 
             global_mean, global_var, beta, scale, batch_norm_epsilon) 

Je forme le modèle et l'enregistrer en utilisant tf.train.Saver(). Ci-dessous le code de test:

def inference(self, images_for_predict): 
    """load the pre-trained model and do the inference. 

    Args: 
     images_for_predict: `tensor`, images for predict using the pre-trained model. 

    Returns: 
     the predict labels. 
    """ 

    tf.reset_default_graph() 
    images, labels, _, _, prediction, accuracy, saver = self._build_graph(1, False) 

    predictions = [] 
    correct = 0 
    with tf.Session() as sess: 
     sess.run(tf.global_variables_initializer()) 
     # saver = tf.train.import_meta_graph('./models/dense_nets_model/dense_nets.ckpt.meta') 
     # saver.restore(sess, tf.train.latest_checkpoint('./models/dense_nets_model/')) 
     saver.restore(sess, './models/dense_nets_model/dense_nets.ckpt') 
     for i in range(100): 
      pred, corr = sess.run([tf.argmax(prediction, 1), accuracy], 
            feed_dict={ 
             images: [images_for_predict.images[i]], 
             labels: [images_for_predict.labels[i]]}) 
      correct += corr 
      predictions.append(pred[0]) 
    print("PREDICTIONS:", predictions) 
    print("ACCURACY:", correct/100) 

Mais le résultat de prédire toujours très mal, comme ça:

('PREDICTIONS:', [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]) 

('ACCURACY:', 0.080000000000000002) 

Quelques conseils: images_for_predict = mnist.test et la méthode self._build_graph a deux params: batch_size et is_training.

Tout le monde peut me aider?

Répondre

2

En voyant votre mise en œuvre de la norme de traitement par lots, lorsque vous chargez votre modèle, vous devez garder le graphique construit avec images, labels, _, _, prediction, accuracy, saver = self._build_graph(1, False) et charger le poids valeurs pour le chekpoint, mais pas le méta graphique. Je pense que saver.restore(sess, './models/dense_nets_model/dense_nets.ckpt') restaure également le méta graphique maintenant (désolé si je me trompe), ainsi vous devez reconstituer seulement la partie de «données» de lui. Dans le cas contraire, vous utilisez simplement le graphique pour l'entraînement, dans lequel la moyenne et la variance utilisées dans la norme de lot sont celles obtenues à partir du lot. Mais lorsque vous testez le lot a la taille 1, donc la normalisation par la moyenne et la variance du lot amène toujours vos données à 0, d'où la sortie constante.

Dans tous les cas, je suggère d'utiliser tf.layers.batch_normalization à la place, avec un espace réservé is_training que vous aurez besoin pour nourrir votre réseau ...

+0

Merci! Mais si ma taille de lot de test est 1, comment puis-je le mettre dans le modèle formé dont la taille de lot est supérieure à 1? – Yang

+0

Salut, gdelab, je change mon 'batch_norm' en' tf.layers.batch_normalization (input_tensor, training = is_training) 'mais ça ne marche pas, je mets à jour le post github, peux-tu m'aider? – Yang

2

Après avoir essayé beaucoup de méthodes, je résoudre ce problème , ci-dessous sont ce que j'ai fait.

Première grâce à @gdelab, j'utilisé à la place tf.layers.batch_normalization, donc mon lot fonction de norme comme:

def _batch_normalization(self, input_tensor, is_training): 
    return tf.layers.batch_normalization(input_tensor, training=is_training) 

PARAM is_training est un espace réservé comme ça: is_training = tf.placeholder(tf.bool)

lors de la construction de votre graphique, rappelez-vous ajouter ce code dans votre optimize:

extra_update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) 
with tf.control_dependencies(extra_update_ops): 
    train_step = tf.train.AdamOptimizer(self.learning_rate).minimize(cross_entropy) 

parce que le tf.layers.batch_normalization ajoute jusqu'à La date et la variance ne sont pas automatiquement ajoutées en tant que dépendances de l'opération du train - donc si vous ne faites rien de plus, elles ne sont jamais exécutées.

Alors Begain pour former le filet, terminer après la formation, enregistrez le modèle en utilisant le code comme ça:

saver = tf.train.Saver(var_list=tf.global_variables()) 
savepath = saver.save(sess, 'here_is_your_personal_model_path') 

Notez que var_list=tf.global_variables() param assurez-vous tensorflow enregistrer tous les params comprennent la moyenne mondiale/var qui ne sont pas entraînables.

lors de la restauration et de tester le modèle, faire comme ça:

# build the graph like training: 
images, labels, _, _, prediction, accuracy, saver = self._build_graph(1, False) 
saver = tf.train.Saver() 
saver.restore(sess, 'here_is_your_personal_model_path') 

Et maintenant, on peut tester sa/son modèle, espérons que cela peut aider u, merci!