使用 TensorFlow 进行多标签文本分类
Multilabel Text Classification using TensorFlow
文本数据被组织为具有 20,000 个元素的向量,例如 [2, 1, 0, 0, 5, ...., 0]。
第 i 个元素表示第 i 个词在文本中出现的频率。
地面实况标签数据也表示为具有 4,000 个元素的向量,例如 [0, 0, 1, 0, 1, ...., 0]。
第 i 个元素表示第 i 个标签是否是文本的正标签。
文本的标签数量因文本而异。
我有一个单标签文本分类代码。
如何为多标签文本分类编辑以下代码?
特别想知道以下几点。
- 如何使用 TensorFlow 计算准确率。
- 如何设置判断标签是正负的阈值。例如,如果输出为 [0.80, 0.43, 0.21, 0.01, 0.32],ground truth 为 [1, 1, 0, 0, 1],则得分超过 0.25 的标签应被判断为正。
谢谢。
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
您必须使用其他交叉熵函数的变体来支持多标签分类。如果你的输出少于一千,你应该使用 sigmoid_cross_entropy_with_logits, in your case that you have 4000 outputs you may consider candidate sampling,因为它比以前的更快。
How to compute accuracy using TensorFlow.
这取决于您的问题和您想要实现的目标。如果您不想遗漏图像中的任何对象,那么如果分类器除了一个对象之外一切正常,那么您应该将整个图像视为一个错误。您还可以认为错过或错误分类的对象是一个错误。后者我认为 sigmoid_cross_entropy_with_logits.
支持
How to set a threshold which judges whether a label is positive or
negative. For instance, if the output is [0.80, 0.43, 0.21, 0.01,
0.32] and the ground truth is [1, 1, 0, 0, 1], the labels with scores over 0.25 should be judged as positive.
门槛是一种方式,你必须决定选择哪一种。但那是某种 hack,不是真正的多标签分类。为此,您需要我之前说过的功能。
将relu改为输出层的sigmoid。
将交叉熵损失修改为 sigmoid 交叉熵损失的显式数学公式(显式损失在我的 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
文本数据被组织为具有 20,000 个元素的向量,例如 [2, 1, 0, 0, 5, ...., 0]。 第 i 个元素表示第 i 个词在文本中出现的频率。
地面实况标签数据也表示为具有 4,000 个元素的向量,例如 [0, 0, 1, 0, 1, ...., 0]。 第 i 个元素表示第 i 个标签是否是文本的正标签。 文本的标签数量因文本而异。
我有一个单标签文本分类代码。
如何为多标签文本分类编辑以下代码?
特别想知道以下几点。
- 如何使用 TensorFlow 计算准确率。
- 如何设置判断标签是正负的阈值。例如,如果输出为 [0.80, 0.43, 0.21, 0.01, 0.32],ground truth 为 [1, 1, 0, 0, 1],则得分超过 0.25 的标签应被判断为正。
谢谢。
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
您必须使用其他交叉熵函数的变体来支持多标签分类。如果你的输出少于一千,你应该使用 sigmoid_cross_entropy_with_logits, in your case that you have 4000 outputs you may consider candidate sampling,因为它比以前的更快。
How to compute accuracy using TensorFlow.
这取决于您的问题和您想要实现的目标。如果您不想遗漏图像中的任何对象,那么如果分类器除了一个对象之外一切正常,那么您应该将整个图像视为一个错误。您还可以认为错过或错误分类的对象是一个错误。后者我认为 sigmoid_cross_entropy_with_logits.
支持How to set a threshold which judges whether a label is positive or negative. For instance, if the output is [0.80, 0.43, 0.21, 0.01, 0.32] and the ground truth is [1, 1, 0, 0, 1], the labels with scores over 0.25 should be judged as positive.
门槛是一种方式,你必须决定选择哪一种。但那是某种 hack,不是真正的多标签分类。为此,您需要我之前说过的功能。
将relu改为输出层的sigmoid。 将交叉熵损失修改为 sigmoid 交叉熵损失的显式数学公式(显式损失在我的 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