【问题标题】:Cost-sensitive loss function in TensorflowTensorflow 中的成本敏感损失函数
【发布时间】:2018-03-01 06:03:39
【问题描述】:

我正在研究基于 Tensorflow 的成本敏感型神经网络。 但是由于Tensorflow的静态图结构。一些NN结构我自己无法实现。

我的损失函数(成本)、成本矩阵和计算过程描述如下,我的目标是计算总成本,然后优化神经网络:

大概的计算进度:

  • y_ 是形状为(1024,5) 的 CNN 的最后一个全连接输出
  • y 是一个张量,其形状为 (1024),表示 x[i] 的基本事实
  • y_soft[i] [j] 表示x[i] 成为j 类的概率

如何在 Tensorflow 中实现这一点?

【问题讨论】:

    标签: tensorflow tensor cost-based-optimizer


    【解决方案1】:

    成本矩阵:

    [[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]]
    

    label,cost_matrix-->cost_embedding:

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

    [0.2,0.3,0.5] 中的 0.3 显然是指 [0,1,0] 的正确标签概率,所以它不应该造成损失。

    [0.1,0.2,0.7] 中的 0.7 是相同的。换言之,y* 中值为 1 的 pos 不会导致 loss。

    所以我有 (1-y*):

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

    那么熵就是target*log(predict) + (1-target) * log(1-predict),y*中的值为0,应该使用(1-target)*log(1-predict),所以我用 (1-predict) 表示 (1-y)

    1-y:

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

    (斜体数字没用)

    自定义损失是

    [[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*log(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 'norm',eval_predict,'\ncustom',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  'norm_test',sess.run(norm_model.predictions,
                      feed_dict={
                          norm_model.input_x:test_set,
                          norm_model.input_y:lables[split_point:]
            })
                print  'custom_test',sess.run(custom_model.predictions,
                      feed_dict={
                          custom_model.input_x:test_set,
                          custom_model.input_y:lables[split_point:]
            })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-22
      • 1970-01-01
      • 2019-01-20
      • 1970-01-01
      • 2019-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多