Условная замена для пользовательского ограничения функции потерь? TypeError: объект Tensor не поддерживает присвоение элементов - PullRequest
1 голос
/ 16 июня 2020

У меня есть модель, которая возвращает два значения на выборку в пакете, где первое значение должно быть> = 0, а второе - <= 0. Моя первая попытка использовать пользовательскую функцию ошибки: </p>

def maxMinDiffLossConstrained(y_true, y_pred, sample_weight=None):
 
    y_pred_shape = list(y_pred.shape) # y_pred returns a tuple, we want a list so we can construct another tensor 
    #y_pred_data = y_pred.numpy() # get the tensor data as a numpy array 
        
    y_pred[y_pred[:,0] < 0, 0] = -10            
    y_pred[y_pred[:,1] > 0, 1] = 10            
        
    y_mod = tf.reshape(y_pred, y_pred_shape)   
   
    mse = MeanSquaredError()
    loss = mse(y_true, y_mod)

    return loss

Вот где я получил ошибку

TypeError: 'Tensor' object does not support item assignment

Как видите, я пытался использовать y_pred.numpy(), но объект, но type(y_pred) равно <class 'tensorflow.python.framework.ops.Tensor'> и возвращает ошибку:

AttributeError: 'Tensor' object has no attribute 'numpy'

Я проверил ряд других сообщений. Здесь предлагается распаковка и переупаковка

TypeError: объект 'Tensor' не поддерживает назначение элементов в TensorFlow

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

https://towardsdatascience.com/how-to-replace-values-by-index-in-a-tensor-with-tensorflow-2-0-510994fe6c5f

К сожалению, поскольку размеры моего Tensor равны (batch_size, 2), я до сих пор не понял решение, которое работает. Моя трудность заключается в том, что после того, как я получу вектор True / False для dim1 (> = 0) и dim2 (<= 0) со следующим кодом: </p>

maxes_to_remove = y_pred[:,0] < 0 
mins_to_remove = y_pred[:,1] > 0

idx_maxes = tf.where(maxes_to_remove == True)
idx_mins = tf.where(mins_to_remove == True)

, я не уверен, как заменить только значения в 1-м измерении, которые необходимо заменить, и только значения во втором, которые необходимо заменить.

В качестве примечания, я также столкнулся с этой проблемой , но смог решить.

1 Ответ

1 голос
/ 16 июня 2020

Я считаю, что тензоры в tf неизменяемы , поэтому вы не можете присваивать значения индексам в массиве. Два обходных пути:

  1. Определите новый тензор, который создается с использованием исходного тензора и некоторых дополнительных операций. Я рекомендую использовать tf.keras.backend.switch(), который позволяет вам присваивать значения новому тензору из одного из двух входных тензоров (который для вас будет тензором -10 и тензором 10) на основе тензора логических значений (для вас это, возможно, будет idx_maxes?)

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

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