2017-04-05 1 views
0

내 모델 (평균 상호 순위)에 대한 새 평가 메트릭을 만들고 싶습니다. 형상의 (None, n_class)랭크가 알려지지 않은 Tensor에 함수 적용

  • logits 텐서 및 0에서 n_class-1int 값을 포함하는 형태의 (None,)
  • y_target 텐서 :
    내가 가진 가정한다.
  • None은 배치 크기입니다.

내 출력이 (None,) 인 텐서 모양이되도록하고 해당하는 역수가 y_target 인 것으로하고 싶습니다. 먼저 logits에 요소 순위를 매기고 인덱스 y_target에있는 요소의 순위를 얻은 다음 마지막으로 역수 (또는 순위 프로 시저에 따라 x + 1의 역수)를 얻습니다.

(단일 관찰) 간단한 예를

:
만약 내 y_target=1logits=[0.5, -2.0, 1.1, 3.5],
다음 순위는 logits_rank=[3, 4, 2, 1]
하고 상호는 1.0/logits_rank[y_target] = 0.25이 될 것입니다.

순위는 알 수 없으므로 (그래프 수준에서) 축을 통해 함수를 적용하는 것이 좋습니다. tf.nn.top_k(logits, k=n_class, sorted=True).indices을 사용하여 일부 결과를 얻을 수 있었지만 session.run(sess, feed_dict) 내에 만 결과를 얻을 수있었습니다.

도움이 될 것입니다.

답변

0

해결!

def tf_get_rank_order(input, reciprocal): 
    """ 
    Returns a tensor of the rank of the input tensor's elements. 
    rank(highest element) = 1. 
    """ 
    assert isinstance(reciprocal, bool), 'reciprocal has to be bool' 
    size = tf.size(input) 
    indices_of_ranks = tf.nn.top_k(-input, k=size)[1] 
    indices_of_ranks = size - tf.nn.top_k(-indices_of_ranks, k=size)[1] 
    if reciprocal: 
     indices_of_ranks = tf.cast(indices_of_ranks, tf.float32) 
     indices_of_ranks = tf.map_fn(
      lambda x: tf.reciprocal(x), indices_of_ranks, 
      dtype=tf.float32) 
     return indices_of_ranks 
    else: 
     return indices_of_ranks 


def get_reciprocal_rank(logits, targets, reciprocal=True): 
    """ 
    Returns a tensor containing the (reciprocal) ranks 
    of the logits tensor (wrt the targets tensor). 
    The targets tensor should be a 'one hot' vector 
    (otherwise apply one_hot on targets, such that index_mask is a one_hot). 
    """ 
    function_to_map = lambda x: tf_get_rank_order(x, reciprocal=reciprocal) 
    ordered_array_dtype = tf.float32 if reciprocal is not None else tf.int32 
    ordered_array = tf.map_fn(function_to_map, logits, 
           dtype=ordered_array_dtype) 

    size = int(logits.shape[1]) 
    index_mask = tf.reshape(
      targets, [-1,size]) 
    if reciprocal: 
     index_mask = tf.cast(index_mask, tf.float32) 

    return tf.reduce_sum(ordered_array * index_mask,1) 

# use: 
recip_rank = tf.reduce_mean(
       get_reciprocal_rank(logits[-1], 
            y_, 
            True) 
관련 문제