python - sentimientos - Clasificación de texto Multilabel con TensorFlow
procesar texto python (2)
Cambiar relu a sigmoid de la capa de salida. Modificar la pérdida de entropía cruzada a la fórmula matemática explícita de la pérdida de entropía cruzada sigmoidea (la pérdida explícita estaba funcionando en mi caso / versión 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
Los datos de texto se organizan como vector con 20,000 elementos, como [2, 1, 0, 0, 5, ...., 0]. El elemento i-ésimo indica la frecuencia de la i-ésima palabra en un texto.
Los datos de la etiqueta de verdad del suelo también se representan como vector 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. La cantidad de etiquetas para un texto varía según 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 con TensorFlow.
- Cómo establecer un umbral que juzga si una etiqueta es positiva o negativa. Por ejemplo, si el resultado es [0.80, 0.43, 0.21, 0.01, 0.32] y la verdad del terreno es [1, 1, 0, 0, 1], las etiquetas con puntajes superiores a 0.25 se deben considerar 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
Tienes que usar variaciones de la función de entropía cruzada en otra para admitir la clasificación multilable. En caso de que tenga menos de mil salidas, debe usar sigmoid_cross_entropy_with_logits , en su caso que tiene 4000 salidas, puede considerar el muestreo de candidatos ya que es más rápido que el anterior.
Cómo calcular la precisión con TensorFlow.
Esto depende de tu problema y de lo que quieras lograr. Si no quieres perderte ningún objeto en una imagen, entonces si el clasificador está bien, solo uno, entonces debes considerar la imagen completa como un error. También puede considerar que un objeto perdido o falta de clasificación es un error. Este último creo que es compatible con sigmoid_cross_entropy_with_logits.
Cómo establecer un umbral que juzga si una etiqueta es positiva o negativa. Por ejemplo, si el resultado es [0.80, 0.43, 0.21, 0.01, 0.32] y la verdad del terreno es [1, 1, 0, 0, 1], las etiquetas con puntajes superiores a 0.25 se deben considerar positivas.
El umbral es un camino por recorrer, tienes que decidir cuál. Pero eso es algún tipo de hackeo, no una clasificación real multilable. Para eso necesitas las funciones previas que dije antes.