Пользовательская функция потерь без использования библиотеки keras - PullRequest
2 голосов
/ 25 июня 2019

Я применяю модель ML к экспериментальной установке, чтобы оптимизировать сигнал движения. Сам движущий сигнал - это то, что оптимизируется, но его качество оценивается косвенно (он применяется к экспериментальной установке для получения другого сигнала).

Я могу запускать и собирать данные из эксперимента с помощью функций в Python.

Я хотел бы настроить модель ML с пользовательской функцией потерь, которая вызывает функции драйвера эксперимента с оптимизированным сигналом, чтобы получить ошибку, используемую для обратной поддержки.

Я рассмотрел использование keras, однако ограничение необходимости использовать внутренние функции keras исключительно означает, что я не могу вызывать свои функции драйвера в функции.

Я хотел бы знать, есть ли способ сделать то, что я хочу, если бы я использовал тензорный поток без внешнего интерфейса keras, а также если это позволяет другой API ML?

Спасибо.

1 Ответ

5 голосов
/ 25 июня 2019

Если я понял вопрос, вы хотите иметь возможность генерировать убытки на основе кода, который вы запускаете, когда модель оценивает функцию потерь.

Это будет пример:

import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.layers import *
from tensorflow.keras.models import Model
from tensorflow.keras import backend as K

FACTORS = np.array([[0.5, 2.0, 4.0]])

def ext_function(inputs):
  """ This can be an arbitrary python function of the inputs
  inputs is a tf.EagerTensor which can be converted into a numpy array.
  """
  r = np.dot(inputs, FACTORS.T)
  return r

class LossFunction(object):
  def __init__(self, model):
    # Use model to obtain the inputs
    self.model = model

  def __call__(self, y_true, y_pred, sample_weight=None):
    """ ignore y_true value from fit params and compute it instead using
    ext_function
    """
    y_true = tf.py_function(ext_function, [self.model.inputs[0]], Tout=tf.float32)
    v = keras.losses.mean_squared_error(y_true, y_pred)
    return K.mean(v)

def make_model():
  inp = Input(shape=(3,))
  out = Dense(1, use_bias=False)(inp)
  model = Model(inp, out)
  model.compile('adam', LossFunction(model))
  return model

model = make_model()
model.summary()

Тест:

import numpy as np


N_SAMPLES=100
X = np.random.rand(N_SAMPLES, 3)
Y_dummy = np.random.rand(N_SAMPLES)

history = model.fit(X, Y_dummy, epochs=1000, verbose=False)
print(history.history['loss'][-1])

И это действительно что-то делает:

model.layers[1].get_weights()

Обратите внимание, что будет гораздо проще просто сгенерировать правильное значение Y в качестве ввода. Я не знаю точно условия вашей проблемы. Но если это вообще возможно, попытайтесь предварительно сгенерировать Y. Вместо того, чтобы использовать приведенный выше пример.

Я использовал уловку выше для создания пользовательских метрик, которые будут взвешены классом. то есть в сценариях, где один из входных параметров является классом, а желаемая функция потерь является средневзвешенным по классу потерями.

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