22

テキストデータは、[2,1,0,0,5、...、0]のように20,000要素のベクトルとして編成されます。 i番目の要素は、テキスト中のi番目の単語の頻度を示します。TensorFlowを使用したマルチラベルテキスト分類

グラウンドトゥルースラベルデータは、[0,0,1,0,1、...、0]のように4,000要素のベクトルとしても表されます。 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 
+0

(明示的な損失がtensorflowの私の場合/バージョンで働いていた)シグモイドクロスエントロピー損失の明示的な数式にクロスエントロピー損失を変更します。 – Aaron

+0

マルチラベル分類の問題には、1誤差精度、ランクロス、平均平均精度など、さまざまな精度指標があります。私はまだTensorFlowを自分自身で学習しており、まだそれらのどれかを正しく実装することはできませんでした。しかし、おそらくこのペーパーはあなたを助けるでしょう:http://arxiv.org/pdf/1312.5419v3.pdfあなたが進歩をするかどうか教えてください! –

+0

正確さのより良い考え方のために、精度とリコールの計算を検討してください。 –

答えて

8

出力レイヤーのシグモイドに変更します。 は、私は、クロスエントロピー以外に使用するためのより良い損失関数があるかもしれないと思う

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 
11

マルチラベル分類をサポートするには、クロスエントロピー関数の変形を使用する必要があります。 1000万未満のアウトプットをお持ちの場合は、sigmoid_cross_entropy_with_logitsを使用してください。4000アウトプットをお持ちの場合は、candidate samplingと考えてよいでしょう。

TensorFlowを使用して精度を計算する方法。

これは、問題と達成したいことによって異なります。イメージ内のオブジェクトを見逃したくない場合は、クラシファイアがすべて正しいものを取得する場合は、イメージ全体をエラーと見なす必要があります。また、オブジェクトの欠落やミスクラスミスがエラーであると考えることもできます。後者は、sigmoid_cross_entropy_with_logitsによってサポートされていると思います。

ラベルが正であるか、または が負であるかを判断するしきい値を設定する方法。例えば、出力が[0.80,0.43,0.21,0.01, 0.32]であり、地上真理値が[1,1,0,0,1]である場合、0.25を超えるスコアを有するラベルは、正と判定されるべきである。

しきい値は1つの方法で、どちらを決定する必要があります。しかし、それは実際のマルチクラス分類ではなく、何らかのハックです。そのためには、私が前に言った以前の機能が必要です。

+1

なぜ人々が 'sigmoid_cross_entropy_with_logits'を提案するのか分かりません。その名前が示唆するもの、すなわち-Y * ln(Sigmoid(logits))です。それから、すべてのクラスに高い確率を与えて、それが私の場合にそれを与えていたからです。 –

+0

この関数は確率を返しません。そして私はそれが高い価値を与えることによって損失を最小限に抑える方法を見ません。クラスに1を設定し、クラスが存在しない場合に0を設定すると、オブジェクトに画像がない場合はネットワークが0に近い値を返し、オブジェクトが存在する場合は1以上に近い値を設定します画像。私はそれを使用して、かなりうまく動作します。 – jorgemf

+0

0とラベル付けされたクラスに高い値を与えるためのペナルティ(0損失)がないので、すべてのクラスに高い値を与えることによって損失を最小限に抑えます。したがって、バイナリクロスエントロピー(y * ln(シグモイド(ロジット))+ 1-y * ln(シグモイド(1ロジット)))。 sigmoid_cross_entropy_with_logitsはバイナリクロスエントロピーを内部実装していません。私はあなたのケースで働いている理由は驚いています、あなたはtheano等を使用しています –

関連する問題