Clasificación de Texto Multilabel usando TensorFlow


Los datos de texto se organizan como vectores con 20.000 elementos, como [2, 1, 0, 0, 5, ...., 0]. el elemento i-ésimo indica la frecuencia de la palabra i-ésima en un texto.

Los datos de la etiqueta ground truth también se representan como vectores con 4.000 elementos, como [0, 0, 1, 0, 1, ...., 0]. el elemento i-ésimo indica si la etiqueta i-ésima es una etiqueta positiva para un texto. El número de etiquetas de un texto varía en función de los textos.

Tengo un código para la clasificación de texto de etiqueta única.

¿Cómo puedo editar el siguiente código para la clasificación de texto multilabel?

Especialmente, me gustaría saber los siguientes puntos.

  • Cómo calcular la precisión usando TensorFlow.
  • Cómo establecer un umbral que juzgue si una etiqueta es positiva o negativa. Por ejemplo, si la salida es [0.80, 0.43, 0.21, 0.01, 0.32] y la verdad de la tierra es [1, 1, 0, 0, 1], las etiquetas con puntuaciones superiores a 0,25 deben considerarse positivas.

Gracias.

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
Author: Benben, 2016-02-15

2 answers

Cambie relu a sigmoide de la capa de salida. Modify cross entropy loss to explicit mathematical formula of sigmoid cross entropy loss (explicit loss was working in my case/version of 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
Author: Alok Nayak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-03 08:58:31

Tiene que usar variaciones de la función de entropía cruzada en otros para soportar la clasificación multilabel. En caso de que tenga menos de mil salidas debe usar sigmoid_cross_entropy_with_logits, en su caso que tenga 4000 salidas puede considerar muestreo candidato ya que es más rápido que el anterior.

Cómo calcular la precisión usando TensorFlow.

Esto depende de su problema y de lo que desea lograr. Si no quieres pierda cualquier objeto en una imagen entonces si el clasificador consigue todo bien pero uno, entonces usted debe considerar la imagen entera un error. También puede considerar que un objeto perdido o mal clasificado es un error. Este último creo que está soportado por sigmoid_cross_entropy_with_logits.

Cómo establecer un umbral que juzgue si una etiqueta es positiva o negativo. Por ejemplo, si la salida es [0.80, 0.43, 0.21, 0.01, 0.32] y la verdad sobre el terreno es [1, 1, 0, 0, 1], las etiquetas con partituras más de 0,25 debe considerarse positivo.

El umbral es una manera de ir, tienes que decidir cuál. Pero eso es una especie de hackeo, no una clasificación multilable real. Para eso necesitas las funciones anteriores que dije antes.

 13
Author: jorgemf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-05 13:28:48