Подтвердить что ты не робот

Многоуровневая текстовая классификация с использованием TensorFlow

Текстовые данные организованы как вектор с 20 000 элементами, такими как [2, 1, 0, 0, 5,...., 0]. i-й элемент указывает частоту i-го слова в тексте.

Данные метки наземной истины также представлены как вектор с 4000 элементами, такими как [0, 0, 1, 0, 1,...., 0]. i-й элемент указывает, является ли i-я метка положительной меткой для текста. Количество меток для текста различается в зависимости от текстов.

У меня есть код для классификации текста с одним ярлыком.

Как я могу изменить следующий код для классификации многозначных текстов?

В частности, я хотел бы знать следующие моменты.

  • Как вычислить точность с помощью TensorFlow.
  • Как установить порог, который определяет, является ли метка положительной или отрицательной. Например, если выход равен [0,80, 0,43, 0,21, 0,01, 0,32], а основная истина равна [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
4b9b3361

Ответ 1

Измените relu на сигмоид выходного слоя. Измените потерю кросс-энтропии в явной математической формуле потери сигмоидной кросс-энтропии (явная потеря работала в моем случае/версии тензорного потока)

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

Ответ 2

Вы должны использовать вариации функции кросс-энтропии в других для поддержки многосетевой классификации. Если у вас меньше тысячи выходов, вы должны использовать sigmoid_cross_entropy_with_logits, в вашем случае, если у вас есть 4000 выходов, вы можете рассмотреть выборка кандидатов, поскольку она быстрее предыдущей.

Как вычислить точность с помощью TensorFlow.

Это зависит от вашей проблемы и того, чего вы хотите достичь. Если вы не хотите пропустить какой-либо объект на изображении, тогда, если классификатор будет в порядке, но один, тогда вы должны рассмотреть все изображение ошибки. Вы также можете считать, что пропущенный объект или missclassiffied является ошибкой. Последнее, на мой взгляд, поддерживается sigmoid_cross_entropy_with_logits.

Как установить порог, который определяет, является ли метка положительной или отрицательный. Например, если выход равен [0,80, 0,43, 0,21, 0,01, 0.32], а основная истина равна [1, 1, 0, 0, 1], метки с оценками более 0,25 следует оценивать как положительные.

Порог - это один из способов пойти, вы должны решить, какой из них. Но это какая-то хачка, а не настоящая многоступенчатая классификация. Для этого вам нужны предыдущие функции, о которых я говорил раньше.