9
votes

Pourquoi Layernormbasiclstmcell est-il beaucoup plus lent et moins précis que LSTMCell?

J'ai récemment constaté que Layernormbasiclstmcell est une version de LSTM avec la normalisation et la décrochage de couche implémentées. Par conséquent, j'ai remplacé mon code d'origine à l'aide de LSTMCell avec LayernorMBASICLSTMCell. Non seulement ce changement a-t-il réduit la précision des tests de ~ 96% à 92%, il a fallu beaucoup plus de temps (environ 33 heures) pour s'entraîner (le temps d'entraînement original est de ~ 6 heures). Tous les paramètres sont les mêmes: nombre d'époques (10), nombre de couches empilées (3), nombre de taille de vecteur cachée (250), abandonnée à maintenir un problème (0,5), ... Le matériel est également identique.

Ma question est la suivante: qu'est-ce que j'ai mal fait ici? P>

Mon modèle original (Utilisation de LSTMCell): P>

...
dropcells = []
for iiLyr in range(3):
    cell_iiLyr = tf.contrib.rnn.LayerNormBasicLSTMCell(
        num_units=250,
        forget_bias=1.0,
        activation=tf.tanh,
        layer_norm=True,
        norm_gain=1.0,
        norm_shift=0.0,
        dropout_keep_prob=0.5
        )
    dropcells.append(cell_iiLyr)
...


5 commentaires

Une pensée: pourrait [ stackoverflow.com/questions/43234667/... soit le problème? Il semble que la moyenne et la variance ne soient pas mises à jour automatiquement dans tf.layers.batch_normalisation . Je me demande si tf.contrib.rnn.layernormbasiclstmcell souffre le même problème.


@Fariborzghavamian, j'ai utilisé la deuxième méthode pour les deux fonctions de normalisation (c.-à-d. update_ops = tf.get_collection (tf.graphkeys.update_ops) et avec tf.control_dépendances (update_ops): . ..).


À propos du temps d'entraînement: j'ai trouvé cela sur le site Web Tensorflow: tensorflow.org/performance/performance_guide#commmon_fused_op S . Vous pouvez activer un paramètre appelé fusionné et obtenir une vitesse de 12% à 30%.


@Fariborzghavamian, merci pour le lien de guidage. Je vais lire tout le guide sur la performance. Ils semblent tous très utiles. Je vais leur donner (y compris le paramètre fusionné ).


@Fariborzghavamian, le paramètre fusionné est lié à Batch_Mindalization et n'a rien à voir avec couche_normalisation.


3 Réponses :


2
votes

À propos du temps d'entraînement: je suis tombé sur ce blog post: http: / /olavnymoen.com/2016/07/07/RNN-Batch-normalisation . Voir le dernier chiffre. Le LSTM normalisé par lots était plus de 3 fois plus lent que la vanille LSTM. L'écrivain fait valoir que la raison est la calcul des statistiques par lots.

À propos de la précision: je n'ai aucune idée.


3 commentaires

Je n'ai pas lu le poste très attentivement, je pense que le message parle de la normalisation des lots plutôt que de la normalisation de la couche (celle de la question)?


Oui, le message concerne la normalisation du lot. Mais le terrain d'entente entre cela et la normalisation de la couche est le calcul des statistiques (moyenne et variance). Certes que les statistiques soient calculées en fonction de différentes données (BN: Over Lot, LN: Over Countrers), il semble néanmoins un coût de calcul supplémentaire.


Je ne comprends pas pourquoi le calcul simple des statistiques (moyenne ou variance) coûte beaucoup de temps (en particulier avec le GPU).



4
votes

Peut-être dropout_keeke_prob doit être attribué à un espace réservé au lieu d'une valeur constante. Essayez d'assigner 0.5 à la formation et 1.0 à l'inférence. Juste une supposition.


2 commentaires

Ce sera certainement nécessaire. DROSPORT doit évidemment être désactivé pendant l'évaluation, et la cellule n'a aucun moyen de savoir quel mode il se trouve, vous devez donc le dire en définissant dropout_keeke_prob à 1.0 pendant l'évaluation.


Merci d'avoir mentionné la valeur pour dropout_keeke_prob devrait être différent pour la formation et le test. Le code réel a-t-il attribué par une valeur spécifique en mode.



1
votes

Normalisation des lots et normalisation de la couche Ne normalisez pas simplement la distribution d'entrée sur un minibat, elles ajoutent également la nouvelle variables apprenantes Beta et Gamma. C'est un scalaire pour chaque dimension de chaque entrée, donc quatre entrées fois deux fois la dimensionnalité de l'entrée.

Je suppose que c'est ce grand nombre de nouvelles variables formables qui expliquent le ralentissement.

D'ailleurs, si vous désactivez Layer_norm Il accélère massivement, de sorte que cela supporte l'hypothèse que c'est la normalisation de la couche qui est le problème.


2 commentaires

Dans la littérature, la normalisation de la couche ( arxiv.org/pdf/1607.06450.pdf ) accélère effectivement -pez le temps de formation. Donc, disant tourner le calque_nom erfond des vitesses de manière massive est tout à fait faux.


Je voulais dire qu'il accélère l'époque d'un seul lot. Bien sûr, il pourrait signifier que la perte diminue plus rapidement, ce qui rend le temps total pour atteindre une certaine perte.