2016-09-20 13 views
3

私はTensorFlowで学習するコスト重視のバイナリ分類を設定しようとしています。これは、偽陽性と偽陰性に違った罰則を課すことになります。誰もが(真陽性、偽陽性、偽陰性、真陰性)のためにペナルティウェイト$(w_1、w_2、w_3、w_4)$のセットから損失関数を作成する方法を知っていますか?Tensorflowのコストに敏感な学習

私は標準的なコスト関数を提示しましたが、それらを組み合わせて上記のようなものを得る方法を理解することはできません。

答えて

3

私は、コストに敏感な神経回路網分類器を構築してきましたが、Alejandro Correa Bahnsencost sensitive logistic regressioncost sensitive decision treesのための学術論文を発表し、非常によくパイソンcost sensitive classification library named CostClaを文書化したことのある人に気づいていないです。あなたがscikit-learnに精通しているなら、CostClaは使いやすいです。

ライブラリ内のBayes minimum risk modelをニューラルネットワークのminimize the costに使用できるようにする必要があります。これは、どの分類子の予測確率を出力するコストモデルにも適しているからです。

CostClaは、サンプルごとに異なるコストが発生する可能性があることに注意してください。トレーニングサンプルとテストサンプルのコストマトリックスを与えます。ただし、問題に該当する場合は、コストマトリックスのすべての行を同じにすることができます。ここで

は、サブジェクトに関する追加の学術論文のカップルです:

+0

を下回っていることは非常に有用だった、ありがとう – LazyCat

0

cost_matrix:

[[0,1,100], 
[1,0,1], 
[1,20,0]] 

ラベル:

[1,2] 

のY *:

[[0,1,0], 
[0,0,1]] 

Y(予測):

[[0.2,0.3,0.5], 
[0.1,0.2,0.7]] 

ラベル、cost_matrix - > cost_embedding:

[[1,0,1], 
[1,20,0]] 

それ明らか0.3で[0.2,0.3 、0.5]は[0,1,0]の右確率確率を指しているので、損失に繋がるべきではない。

[0.1,0.2,0.7]の0.7は同じです。言い換えれば、y *の値が1のposは損失に繋がりません。

だから(1-Y *)を有する:

[[1,0,1], 
[1,1,0]] 

そしてエントロピーYに目標*ログ(予測)+(1-ターゲット)*ログ(1-予測)、および値0であります*(1-Y)前記(1-予測)

1-yは(1-ターゲット)*ログ(1-予測)を使用し、私は使用する必要があります

[[0.8,*0.7*,0.5], 
[0.9,0.8,*0.3*]] 

(イタリックNUMであります役に立たない)

カスタム損失は

[[1,0,1], [1,20,0]] * log([[0.8,0.7,0.5],[0.9,0.8,0.3]]) * 
[[1,0,1],[1,1,0]] 

であり、あなたがここにドロップすることができます(1-Y *)を見ることができます

そう損失である-tf.reduce_mean(cost_embeddingの*ログ(1-Y)) へそれが適用できるよう、次のようになります。

-tf.reduce_mean(cost_embedding*log(tf.clip((1-y),1e-10))) 

デモは

import tensorflow as tf 
import numpy as np 
hidden_units = 50 
num_class = 3 
class Model(): 
    def __init__(self,name_scope,is_custom): 
     self.name_scope = name_scope 
     self.is_custom = is_custom 
     self.input_x = tf.placeholder(tf.float32,[None,hidden_units]) 
     self.input_y = tf.placeholder(tf.int32,[None]) 

     self.instantiate_weights() 
     self.logits = self.inference() 
     self.predictions = tf.argmax(self.logits,axis=1) 
     self.losses,self.train_op = self.opitmizer() 

    def instantiate_weights(self): 
     with tf.variable_scope(self.name_scope + 'FC'): 
      self.W = tf.get_variable('W',[hidden_units,num_class]) 
      self.b = tf.get_variable('b',[num_class]) 

      self.cost_matrix = tf.constant(
       np.array([[0,1,100],[1,0,100],[20,5,0]]), 
       dtype = tf.float32 
      ) 

    def inference(self): 
     return tf.matmul(self.input_x,self.W) + self.b 

    def opitmizer(self): 
     if not self.is_custom: 
      loss = tf.nn.sparse_softmax_cross_entropy_with_logits\ 
       (labels=self.input_y,logits=self.logits) 
     else: 
      batch_cost_matrix = tf.nn.embedding_lookup(
       self.cost_matrix,self.input_y 
      ) 
      loss = - tf.log(1 - tf.nn.softmax(self.logits))\ 
        * batch_cost_matrix 

     train_op = tf.train.AdamOptimizer().minimize(loss) 
     return loss,train_op 

import random 
batch_size = 128 
norm_model = Model('norm',False) 
custom_model = Model('cost',True) 
split_point = int(0.9 * dataset_size) 
train_set = datasets[:split_point] 
test_set = datasets[split_point:] 


with tf.Session() as sess: 
    sess.run(tf.global_variables_initializer()) 
    for i in range(100): 
     batch_index = random.sample(range(split_point),batch_size) 
     train_batch = train_set[batch_index] 
     train_labels = lables[batch_index] 
     _,eval_predict,eval_loss = sess.run([norm_model.train_op, 
        norm_model.predictions,norm_model.losses], 
        feed_dict={ 
         norm_model.input_x:train_batch, 
         norm_model.input_y:train_labels 
     }) 
     _,eval_predict1,eval_loss1 = sess.run([custom_model.train_op, 
        custom_model.predictions,custom_model.losses], 
        feed_dict={ 
         custom_model.input_x:train_batch, 
         custom_model.input_y:train_labels 
     }) 
     # print '默认',eval_predict,'\n自定义',eval_predict1 
     print np.sum(((eval_predict == train_labels)==True).astype(np.int)),\ 
      np.sum(((eval_predict1 == train_labels)==True).astype(np.int)) 
     if i%10 == 0: 
      print '默认测试',sess.run(norm_model.predictions, 
        feed_dict={ 
         norm_model.input_x:test_set, 
         norm_model.input_y:lables[split_point:] 
     }) 
      print '自定义测试',sess.run(custom_model.predictions, 
        feed_dict={ 
         custom_model.input_x:test_set, 
         custom_model.input_y:lables[split_point:] 
     }) 
関連する問題