2017-11-30 178 views
11

Bu ölçümü Keras'ta nasıl uygularım? Aşağıdaki kodum yanlış sonuç veriyor! Ben exp yoluyla (x + 1) dönüşüm (x) önceki günlüğünü geri almayı ediyorum Not - 1, aynı zamanda olumsuz tahminler 0'a kırpılır:Keras özel RMSLE metrik

Karşılaştırma için
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) 

, burada standart numpy uygulama görebilirsiniz:

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 

Neyi yanlış yapıyorum? Teşekkürler!

DÜZENLEME: Ayar axis=0, doğru olana çok yakın bir değer veriyor gibi görünüyor, ancak göründüğüm tüm kodlar axis=-1 kullanıyor olduğundan emin değilim.

cevap

7

Aynı sorunla karşılaştık ve bunun için aradı, bu benim için iş gibi görünüyor, rmsle_K yöntem Keras ve TensorFlow ile uyguladı.

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)) 

Sonuç:

TensorFlow arka uç

0.263978210565 

0.263978210565 

0.263978 
+0

Teşekkürler, ama exp (x) -1 dönüşümü ne olacak? – Fernando

+0

@Fernando Bu dönüşüme ihtiyacınız olduğunu düşünmüyorum, ancak https://www.kaggle.com/wiki/RootMeanSquaredLogarithmicError – LYu

+0

Modelimin log'a (x + 1) uygun olduğundan ihtiyacım var, bu yüzden exp (x + 1) ile geri dönmem gerekiyor) - 1, daha sonra RMSLE'yi uygulayın. – Fernando

3

Sayısal uygulamada bir listenin (to_sum) kullanımıyla, numpy dizininizin (length,) biçiminde olduğundan şüpheleniyorum.

Ve Keras'ta, axis=0 ve axis=1 ile farklı sonuçlara sahip olduğunuzdan, muhtemelen (length,1) gibi bir biçiminiz vardır. to_sum listesi oluştururken

Ayrıca

, sen numpy uygulanmasında axis=0 öğeleri alarak, yani hedef y[i] ve y_pred[i] kullanıyoruz. Numpe uygulaması ayrıca sum(to_sum)'daki ortalamaları hesaplamak için her şeyi özetlemektedir. Bu nedenle, K.mean'da axis'u kullanmanıza gerek yoktur.

Modelinizin çıktı şeklinin (length,) veya (length,1) olduğundan emin olursanız, eksen parametresini geçmeden yalnızca K.mean(value)'u kullanabilirsiniz. Biraz değiştirilmiş sonra

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

ne buldum burada,

+0

kullanarak bunu fark ancak Keras aynı (y, y_pred) çifti için biraz daha farklı bir sonuç vermektedir. Neden olduğuna dair hiçbir fikrim yok. – Fernando