2017-11-30 11 views
11

Keras에서 어떻게이 메트릭을 구현합니까? 내 코드는 잘못된 결과를 제공합니다! I는 EXP 비아 (X + 1) 변형 (X) 이전에 로그를 취소있어 주 - 1, 또한 부정적인 예측을 0으로 클리핑된다Keras 커스텀 RMSLE 메트릭

비교 용
def rmsle_cust(y_true, y_pred): 
    first_log = K.clip(K.exp(y_pred) - 1.0, 0, None) 
    second_log = K.clip(K.exp(y_true) - 1.0, 0, None) 
    return K.sqrt(K.mean(K.square(K.log(first_log + 1.) - K.log(second_log + 1.)), axis=-1) 

가 여기 표준 NumPy와 구현이다 :

def rmsle_cust_py(y, y_pred, **kwargs): 
    # undo 1 + log 
    y = np.exp(y) - 1 
    y_pred = np.exp(y_pred) - 1 

    y_pred[y_pred < 0] = 0.0 
    to_sum = [(math.log(y_pred[i] + 1) - math.log(y[i] + 1)) ** 2.0 for i,pred in enumerate(y_pred)] 
    return (sum(to_sum) * (1.0/len(y))) ** 0.5 

내가 뭘 잘못하고있어? 감사!

EDIT : 설정 axis=0은 올바른 값을 제공하는 것으로 보이지만 모든 코드가 사용 된 것 같아서 잘 모르겠습니다. axis=-1.

답변

7

저도 같은 문제로 실행해도 검색이 나를 위해 작동하는 것 같다, rmsle_K 방법은 KerasTensorFlow로 구현.

import numpy as np 
import math 
from keras import backend as K 
import tensorflow as tf 

def rmsle(y, y0): 
    assert len(y) == len(y0) 
    return np.sqrt(np.mean(np.power(np.log1p(y)-np.log1p(y0), 2))) 

def rmsle_loop(y, y0): 
    assert len(y) == len(y0) 
    terms_to_sum = [(math.log(y0[i] + 1) - math.log(y[i] + 1)) ** 2.0 for i,pred in enumerate(y0)] 
    return (sum(terms_to_sum) * (1.0/len(y))) ** 0.5 

def rmsle_K(y, y0): 
    return K.sqrt(K.mean(K.square(tf.log1p(y) - tf.log1p(y0)))) 

r = rmsle(y=[5, 20, 12], y0=[8, 16, 12]) 
r1 = rmsle_loop(y=[5, 20, 12], y0=[8, 16, 12]) 
r2 = rmsle_K(y=[5., 20., 12.], y0=[8., 16., 12.]) 

print(r) 

print(r1) 

sess = tf.Session() 

print(sess.run(r2)) 

결과 :

는 TensorFlow 백엔드

0.263978210565 

0.263978210565 

0.263978 
+0

감사합니다.하지만 exp (x) - 1 변환은 어떻게됩니까? – Fernando

+0

@ 페르난도 나는 당신이 그 변환이 필요하다고 생각하지 않는다. https://www.kaggle.com/wiki/RootMeanSquaredLogarithmicError – LYu

+0

내 모델이 로그 (x + 1)에 맞기 때문에 필자는 exp (x) - 1을 입력 한 다음 RMSLE을 적용하십시오. – Fernando

3

numpy 구현에 목록 (to_sum)을 사용하여 numpy 배열의 모양이 (length,) 인 것으로 의심됩니다.

Keras의 경우 axis=0axis=1의 결과가 서로 다르므로 (length,1)과 같은 모양 일 가능성이 큽니다. to_sum 목록을 만들 때

또한

, 당신은 당신이 NumPy와 구현에 axis=0에서 요소를 복용하고 의미 y[i]y_pred[i]을 사용하고 있습니다.

numpy 구현은 평균을 계산할 때도 모두 sum(to_sum)입니다. 따라서 K.mean에는 axis을 사용할 필요가 없습니다.

모델의 출력 모양이 (length,) 또는 (length,1)인지 확인하려면 축 매개 변수를 전달하지 않고 K.mean(value) 만 사용할 수 있습니다. 약간 수정 후 내가

https://www.kaggle.com/jpopham91/rmlse-vectorized

을 찾았는지 여기,

+0

를 사용하여 나는 것으로 나타났습니다하지만 Keras 같은 (Y, y_pred) 쌍에 대한 약간 다른 결과를주고있다. 나는 이유를 모른다. – Fernando

관련 문제