Keras custom metric iteration

前端 未结 3 2031
一整个雨季
一整个雨季 2021-01-18 11:16

I\'m pretty new to Keras and I\'m trying to define my own metric. It calculates concordance index which is a measure for regression problems.

def cindex_scor         


        
3条回答
  •  野趣味
    野趣味 (楼主)
    2021-01-18 11:32

    If you are comfortable using tensorflow, then you can try using this code instead:

    def cindex_score(y_true, y_pred):
    
        g = tf.subtract(tf.expand_dims(y_pred, -1), y_pred)
        g = tf.cast(g == 0.0, tf.float32) * 0.5 + tf.cast(g > 0.0, tf.float32)
    
        f = tf.subtract(tf.expand_dims(y_true, -1), y_true) > 0.0
        f = tf.matrix_band_part(tf.cast(f, tf.float32), -1, 0)
    
        g = tf.reduce_sum(tf.multiply(g, f))
        f = tf.reduce_sum(f)
    
        return tf.where(tf.equal(g, 0), 0.0, g/f)
    

    Here is some code that verifies that both approaches are equivalent:

    def _ref(J, K):
        _sum = 0
        _pair = 0
        for _i in range(1, len(J)):
            for _j in range(0, _i):
                if _i is not _j:
                    if(J[_i] > J[_j]):
                      _pair +=1
                      _sum +=  1* (K[_i] > K[_j]) + 0.5 * (K[_i] == K[_j])
        return 0 if _pair == 0 else _sum / _pair
    
    def _raw(J, K):
    
        g = tf.subtract(tf.expand_dims(K, -1), K)
        g = tf.cast(g == 0.0, tf.float32) * 0.5 + tf.cast(g > 0.0, tf.float32)
    
        f = tf.subtract(tf.expand_dims(J, -1), J) > 0.0
        f = tf.matrix_band_part(tf.cast(f, tf.float32), -1, 0)
    
        g = tf.reduce_sum(tf.multiply(g, f))
        f = tf.reduce_sum(f)
    
        return tf.where(tf.equal(g, 0), 0.0, g/f)
    
    
    for _ in range(100):
        with tf.Session() as sess:
            inputs = [tf.placeholder(dtype=tf.float32),
                      tf.placeholder(dtype=tf.float32)]
            D = np.random.randint(low=10, high=1000)
            data = [np.random.rand(D), np.random.rand(D)]
    
            r1 = sess.run(_raw(inputs[0], inputs[1]),
                          feed_dict={x: y for x, y in zip(inputs, data)})
            r2 = _ref(data[0], data[1])
    
            assert np.isclose(r1, r2)
    

    Please note that this only works for 1D-tensors (rarely a case you will have in keras).

提交回复
热议问题