2017-11-30 41 views
11

मैं केरस में इस मीट्रिक को कैसे कार्यान्वित करूं? नीचे मेरा कोड गलत परिणाम देता है! नोट है कि मैं एक पिछले लॉग (x + 1) exp के माध्यम से परिवर्तन (एक्स) नाश कर रहा हूँ - 1, भी नकारात्मक भविष्यवाणियों को 0 पर काटा जाता है:केरास कस्टम आरएमएसएल मीट्रिक

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 

मैं क्या गलत कर रहा हूं? धन्यवाद!

संपादित करें: axis=0 सेट करना सही मान के बहुत करीब है, लेकिन मुझे यकीन नहीं है क्योंकि मेरे द्वारा प्रतीत होता है कि सभी कोड axis=-1 का उपयोग करता है।

उत्तर

7

मैं एक ही समस्या में पड़ गए और इसके लिए खोज की है, यहाँ है कि मैं क्या

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

पाया थोड़ा संशोधित करने के बाद, यह मेरे लिए काम करने लगता है, rmsle_K विधि Keras और TensorFlow के साथ लागू किया।

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, फिर आरएमएसएलई लागू करें। – Fernando

3

numpy कार्यान्वयन में एक सूची (to_sum) के उपयोग से, मुझे संदेह है कि आपकी numpy सरणी आकार (length,) है।

और केरास पर, क्योंकि आपके पास axis=0 और axis=1 के साथ अलग-अलग परिणाम हैं, तो शायद आपको (length,1) जैसे कुछ आकार मिल गए हैं।

इसके अलावा, जब to_sum सूची बनाते समय, आप y[i] और y_pred[i] उपयोग कर रहे हैं, जिसका अर्थ है आप numpy कार्यान्वयन में axis=0 से तत्वों ले जा रहे हैं।

numpy कार्यान्वयन sum(to_sum) में माध्य की गणना के लिए सबकुछ भी बताता है। तो, आपको K.mean में किसी भी axis का उपयोग करने की आवश्यकता नहीं है।

यदि आप सुनिश्चित करते हैं कि आपके मॉडल का आउटपुट आकार (length,) या (length,1) है, तो आप अक्ष पैरामीटर को पार किए बिना केवल K.mean(value) का उपयोग कर सकते हैं।

+0

का उपयोग करते हुए मैंने देखा है कि है, लेकिन Keras ही (y, y_pred) जोड़ी के लिए एक अलग परिणाम दे रहा है। मुझे कोई जानकारी नहीं है की क्यों। – Fernando

संबंधित मुद्दे