web-dev-qa-db-fra.com

Tensorflow: ne peut pas comprendre la séquence de sortie de ctc_beam_search_decoder ()

J'utilise la fonction tf.nn.ctc_beam_search_decoder() de Tensorflow pour décoder la sortie d'un RNN en faisant un mappage plusieurs à plusieurs (c'est-à-dire plusieurs sorties softmax pour chaque cellule du réseau).

Une version simplifiée de la sortie du réseau et du décodeur de recherche de faisceau est:

import numpy as np
import tensorflow as tf

batch_size = 4
sequence_max_len = 5
num_classes = 3

y_pred = tf.placeholder(tf.float32, shape=(batch_size, sequence_max_len, num_classes))
y_pred_transposed = tf.transpose(y_pred,
                                 perm=[1, 0, 2])  # TF expects dimensions [max_time, batch_size, num_classes]
logits = tf.log(y_pred_transposed)
sequence_lengths = tf.to_int32(tf.fill([batch_size], sequence_max_len))
decoded, log_probabilities = tf.nn.ctc_beam_search_decoder(logits,
                                                           sequence_length=sequence_lengths,
                                                           beam_width=3,
                                                           merge_repeated=False, top_paths=1)

decoded = decoded[0]
decoded_paths = tf.sparse_tensor_to_dense(decoded)  # Shape: [batch_size, max_sequence_len]

with tf.Session() as session:
    tf.global_variables_initializer().run()

    softmax_outputs = np.array([[[0.1, 0.1, 0.8], [0.8, 0.1, 0.1], [0.8, 0.1, 0.1], [0.8, 0.1, 0.1], [0.8, 0.1, 0.1]],
                                [[0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7]],
                                [[0.1, 0.7, 0.2], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7]],
                                [[0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7]]])

    decoded_paths = session.run(decoded_paths, feed_dict = {y_pred: softmax_outputs})
    print(decoded_paths)

La sortie dans ce cas est:

[[0]
 [1]
 [1]
 [1]]

Ma compréhension est que le tenseur de sortie doit être de dimensions [batch_size, max_sequence_len], chaque ligne contenant les indices des classes pertinentes dans le chemin trouvé.

Dans ce cas, je m'attendrais à ce que la sortie soit similaire à:

[[2, 0, 0, 0, 0],
 [2, 2, 2, 2, 2],
 [1, 2, 2, 2, 2],
 [2, 2, 2, 2, 2]]

Qu'est-ce que je ne comprends pas sur la façon dont ctc_beam_search_decoder travaux?

24
Nur L

Comme indiqué dans documentation tf.nn.ctc_beam_search_decoder , la forme de la sortie n'est pas [batch_size, max_sequence_len]. Au lieu de cela, il est

[batch_size, max_decoded_length[j]]

(avec j=0 dans votre cas).

Basé sur le début de la section 2 de cet article (qui est cité dans le dépôt github ), max_decoded_length[0] Est délimité par le haut par max_sequence_len, mais ils ne sont pas nécessairement égaux. La citation pertinente est:

Soit S un ensemble d'exemples d'apprentissage tirés d'une distribution fixe D_ {XxZ}. L'espace d'entrée X = (R ^ m) est l'ensemble de toutes les séquences de m vecteurs à valeurs réelles dimensionnelles. L'espace cible Z = L * est l'ensemble de toutes les séquences sur l'alphabet (fini) L des étiquettes. En général, nous appelons les éléments de L * des séquences d'étiquettes ou des étiquetages. Chaque exemple en S consiste en une paire de séquences (x, z). La séquence cible z = (z1, z2, ..., zU) est au plus aussi longue que la séquence d'entrée x = (x1, x2, ..., xT), c'est-à-dire U <= T. Etant donné que les séquences d'entrée et cible n'ont généralement pas la même longueur, il n'y a a priori aucun moyen de les aligner.

En fait, max_decoded_length[0] Dépend de la matrice spécifique softmax_outputs. En particulier, deux de ces matrices ayant exactement les mêmes dimensions peuvent entraîner des max_decoded_length[0] Différents.

Par exemple, si vous remplacez la ligne

softmax_outputs = np.array([[[0.1, 0.1, 0.8], [0.8, 0.1, 0.1], [0.8, 0.1, 0.1], [0.8, 0.1, 0.1], [0.8, 0.1, 0.1]],
                                [[0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7]],
                                [[0.1, 0.7, 0.2], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7]],
                                [[0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7], [0.1, 0.2, 0.7]]])

avec les rangées

np.random.seed(7)
r=np.random.randint(0,100,size=(4,5,3))
softmax_outputs=r/np.sum(r,2).reshape(4,5,1)

vous obtiendrez la sortie

[[1 0 1]
 [1 0 1]
 [1 0 0]
 [1 0 0]]

(dans les exemples ci-dessus, softmax_outputs se compose de logits et a exactement les mêmes dimensions que la matrice que vous avez fournie).

D'un autre côté, changer la graine en np.random.seed(50) donne la sortie

[[1 0]
 [1 0]
 [1 0]
 [0 1]]

P.S.

Concernant la dernière partie de votre question:

Dans ce cas, je m'attendrais à ce que la sortie soit similaire à:

[[2, 0, 0, 0, 0],
 [2, 2, 2, 2, 2],
 [1, 2, 2, 2, 2],
 [2, 2, 2, 2, 2]]

Notez que, d'après la documentation , num_classes Représente en fait num_labels + 1. Plus précisément:

La taille de dimension la plus à l'intérieur des entrées de Tensor, num_classes, Représente les classes num_labels + 1, Où num_labels Est le nombre d'étiquettes vraies et la plus grande valeur (num_classes - 1) Est réservé à l'étiquette vierge.

Par exemple, pour un vocabulaire contenant 3 étiquettes [a, b, c], num_classes = 4 Et l'indexation des étiquettes est {a: 0, b: 1, c: 2, vide: 3}.

Ainsi, les véritables étiquettes dans votre cas sont 0 et 1, et 2 est réservé à l'étiquette vierge. L'étiquette vierge représente la situation sans observation d'étiquette (section 3.1 ici ):

Un réseau CTC a une couche de sortie softmax (Bridle, 1990) avec une unité de plus qu'il n'y a d'étiquettes en L. Les activations du premier | L | les unités sont interprétées comme les probabilités d'observer les étiquettes correspondantes à des moments particuliers. L'activation de l'unité supplémentaire est la probabilité d'observer un `` blanc '', ou aucune étiquette. Ensemble, ces sorties définissent les probabilités de toutes les manières possibles de aligner toutes les séquences d'étiquettes possibles avec la séquence d'entrée.

24
Miriam Farber