Classification de texte Multilabel à L'aide de TensorFlow

Les données textuelles sont organisées en vecteur avec 20 000 éléments, comme [2, 1, 0, 0, 5, ...., 0]. i-ième élément indique la fréquence du i-ième mot dans un texte.

Les données de l'étiquette de vérité au sol sont également représentées sous forme de vecteur avec 4 000 éléments, comme [0, 0, 1, 0, 1, ...., 0]. i-ième élément indique si l'étiquette i-ième est une étiquette positive pour un texte. Le nombre d'étiquettes pour un texte diffère selon les textes.

J'ai un code pour la classification de texte à étiquette unique.

Comment puis-je modifier le code suivant pour la classification de texte multilabel?

Surtout, je voudrais savoir les points suivants.

  • comment calculer la précision en utilisant TensorFlow.
  • comment définir un seuil qui juge si une étiquette est positive ou négative. Par exemple, si la sortie est [0.80, 0.43, 0.21, 0.01, 0.32] et la vérité fondamentale est [1, 1, 0, 0, 1], les étiquettes avec des scores supérieurs à 0,25 devraient être jugées positives.

Merci.

import tensorflow as tf

# hidden Layer
class HiddenLayer(object):
    def __init__(self, input, n_in, n_out):
        self.input = input

        w_h = tf.Variable(tf.random_normal([n_in, n_out],mean = 0.0,stddev = 0.05))
        b_h = tf.Variable(tf.zeros([n_out]))

        self.w = w_h
        self.b = b_h
        self.params = [self.w, self.b]

    def output(self):
        linarg = tf.matmul(self.input, self.w) + self.b
        self.output = tf.nn.relu(linarg)

        return self.output

# output Layer
class OutputLayer(object):
    def __init__(self, input, n_in, n_out):
        self.input = input

        w_o = tf.Variable(tf.random_normal([n_in, n_out], mean = 0.0, stddev = 0.05))
        b_o = tf.Variable(tf.zeros([n_out]))

        self.w = w_o
        self.b = b_o
        self.params = [self.w, self.b]

    def output(self):
        linarg = tf.matmul(self.input, self.w) + self.b
        self.output = tf.nn.relu(linarg)

        return self.output

# model
def model():
    h_layer = HiddenLayer(input = x, n_in = 20000, n_out = 1000)
    o_layer = OutputLayer(input = h_layer.output(), n_in = 1000, n_out = 4000)

    # loss function
    out = o_layer.output()
    cross_entropy = -tf.reduce_sum(y_*tf.log(out + 1e-9), name='xentropy')    

    # regularization
    l2 = (tf.nn.l2_loss(h_layer.w) + tf.nn.l2_loss(o_layer.w))
    lambda_2 = 0.01

    # compute loss
    loss = cross_entropy + lambda_2 * l2

    # compute accuracy for single label classification task
    correct_pred = tf.equal(tf.argmax(out, 1), tf.argmax(y, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_pred, "float"))

    return loss, accuracy
29
demandé sur Benben 2016-02-15 04:10:07

2 réponses

Change relu en sigmoïde de la couche de sortie. Modifier la perte d'entropie croisée en formule mathématique explicite de la perte d'entropie croisée sigmoïde (la perte explicite fonctionnait dans mon cas / version de tensorflow)

import tensorflow as tf

# hidden Layer
class HiddenLayer(object):
    def __init__(self, input, n_in, n_out):
        self.input = input

        w_h = tf.Variable(tf.random_normal([n_in, n_out],mean = 0.0,stddev = 0.05))
        b_h = tf.Variable(tf.zeros([n_out]))

        self.w = w_h
        self.b = b_h
        self.params = [self.w, self.b]

    def output(self):
        linarg = tf.matmul(self.input, self.w) + self.b
        self.output = tf.nn.relu(linarg)

        return self.output

# output Layer
class OutputLayer(object):
    def __init__(self, input, n_in, n_out):
        self.input = input

        w_o = tf.Variable(tf.random_normal([n_in, n_out], mean = 0.0, stddev = 0.05))
        b_o = tf.Variable(tf.zeros([n_out]))

        self.w = w_o
        self.b = b_o
        self.params = [self.w, self.b]

    def output(self):
        linarg = tf.matmul(self.input, self.w) + self.b
        #changed relu to sigmoid
        self.output = tf.nn.sigmoid(linarg)

        return self.output

# model
def model():
    h_layer = HiddenLayer(input = x, n_in = 20000, n_out = 1000)
    o_layer = OutputLayer(input = h_layer.output(), n_in = 1000, n_out = 4000)

    # loss function
    out = o_layer.output()
    # modified cross entropy to explicit mathematical formula of sigmoid cross entropy loss
    cross_entropy = -tf.reduce_sum( (  (y_*tf.log(out + 1e-9)) + ((1-y_) * tf.log(1 - out + 1e-9)) )  , name='xentropy' )    

    # regularization
    l2 = (tf.nn.l2_loss(h_layer.w) + tf.nn.l2_loss(o_layer.w))
    lambda_2 = 0.01

    # compute loss
    loss = cross_entropy + lambda_2 * l2

    # compute accuracy for single label classification task
    correct_pred = tf.equal(tf.argmax(out, 1), tf.argmax(y, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_pred, "float"))

    return loss, accuracy
12
répondu Alok Nayak 2017-02-03 08:58:31

Vous devez utiliser des variations de la fonction d'entropie croisée dans other pour prendre en charge la classification multilabel. Dans le cas où vous avez moins de mille sorties, vous devriez utiliser sigmoid_cross_entropy_with_logits, dans votre cas que vous avez 4000 sorties, vous pouvez considérer candidate sampling car il est plus rapide que le précédent.

Comment calculer la précision en utilisant TensorFlow.

Cela dépend de votre problème et de ce que vous voulez réaliser. Si vous ne voulez pas manquer n'importe quel objet dans une image alors si le classificateur obtient tout droit mais un, alors vous devriez considérer l'image entière une erreur. Vous pouvez également considérer qu'un objet manqué ou missclassified est une erreur. Ce dernier je pense qu'il est supporté par sigmoid_cross_entropy_with_logits.

Comment définir un seuil qui juge si une étiquette est positive ou négatif. Par exemple, si la sortie est [0.80, 0.43, 0.21, de 0,01, 0.32] et la vérité du terrain est [1, 1, 0, 0, 1], les étiquettes avec des scores plus de 0,25 devrait être jugé positif.

Seuil est une façon d'aller, vous devez décider lequel. Mais c'est une sorte de hack, pas une vraie classification multilable. Pour cela, vous avez besoin des fonctions précédentes que j'ai déjà dites.

13
répondu jorgemf 2016-05-05 13:28:48