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
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
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.