пользовательская функция потерь в классе в тензорном потоке - PullRequest
0 голосов
/ 02 мая 2019

Для моей проблемы я хочу предсказать клиента оценки оценки в диапазоне от 1 до 5 .Я подумал, что было бы хорошо реализовать это как регрессионную проблему , потому что предсказанное 1 из модели, в то время как 5 является истинным значением, должно быть "худшим" ​​предсказанием, чем 4. Также желательно, чтобы модельвыполняет как-то одинаково хорошо для всех классов оценки .Поскольку мой набор данных сильно несбалансирован , я хочу создать метрику / потерю , которая способна зафиксировать это (я думаю, что просто как F1 для классификации).Поэтому я создал следующую метрику (на данный момент только mse имеет значение):

def custom_metric(y_true, y_pred):
    df = pd.DataFrame(np.column_stack([y_pred, y_true]), columns=["Predicted", "Truth"])
    class_mse = 0
    #class_mae = 0
    print("MAE for Classes:")
    for i in df.Truth.unique():
        temp = df[df["Truth"]==i]
        mse = mean_squared_error(temp.Truth, temp.Predicted)
        #mae = mean_absolute_error(temp.Truth, temp.Predicted)
        print("Class {}: {}".format(i, mse))
        class_mse += mse
        #class_mae += mae
    print()
    print("AVG MSE over Classes {}".format(class_mse/len(df.Truth.unique())))
    #print("AVG MAE over Classes {}".format(class_mae/len(df.Truth.unique())))

Теперь примерный прогноз:

import numpy as np
import pandas as pd
from sklearn.metrics import mean_squared_error, mean_absolute_error

# sample predictions: "model" messed up at class 2 and 3 
y_true = np.array((1,1,1,2,2,2,3,3,3,4,4,4,5,5,5))
y_pred = np.array((1,1,1,2,2,3,5,4,3,4,4,4,5,5,5))

custom_metric(y_true, y_pred)

Теперь мой вопрос: может ли он создать пользовательскую потерю тензорного потокафункция, которая может действовать в подобном поведении?Я также работал над этой реализацией, которая еще не готова к тензорному потоку, но, возможно, более похожа:

def custom_metric(y_true, y_pred):
    mse_class = 0
    num_classes = len(np.unique(y_true))
    stacked = np.vstack((y_true, y_pred))
    for i in np.unique(stacked[0]):     
        y_true_temp = stacked[0][np.where(stacked[0]==i)]
        y_pred_temp = stacked[1][np.where(stacked[0]==i)]
        mse = np.mean(np.square(y_pred_temp - y_true_temp))
        mse_class += mse
    return mse_class/num_classes

Но, тем не менее, я не уверен, как обойти цикл for для определения тензорного потока, подобного определению.

Заранее спасибо за любую помощь!

1 Ответ

1 голос
/ 02 мая 2019

Цикл for должен обрабатываться точно с помощью операций numpy / tenorflow над тензором.

Примером пользовательской метрики будет:

  from keras import backend as K

  def custom_mean_squared_error(y_true, y_pred):
        return K.mean(K.square(y_pred - y_true), axis=-1)

где y_true - метка истинности земли, y_pred - ваши прогнозы. Вы можете видеть, что нет явных циклов for.

Мотивация не использовать циклы заключается в том, что векторизованные операции (которые присутствуют как в numpy, так и в тензорном потоке) используют преимущества современных архитектур ЦП, превращая множественные итеративные операции в матричные. Учтите, что реализация dot-product в numpy занимает примерно в 30 раз меньше, чем обычный цикл for в Python.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...