I have a model that returns two values per sample in a batch where the first value must be >=0 and the second must be <=0. My first attempt at a custom error function follows:
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
Which is where I got the error
TypeError: 'Tensor' object does not support item assignment
As you can see I tried using y_pred.numpy() but the object but type(y_pred) is <class 'tensorflow.python.framework.ops.Tensor'> and returns the error:
AttributeError: 'Tensor' object has no attribute 'numpy'
I have checked a number of other posts. This one suggests unstacking and restacking
TypeError: 'Tensor' object does not support item assignment in TensorFlow
This next longer article was helpful, it suggested decomposing based on conditions and then remaking the tensor. I am still working towards a solution with this approach:
Unfortunately, since the dimensions of my Tensor are (batch_size, 2) I still have not figured out a solution that works. My difficulty is that, after I get the True/False vector for dim1 (>=0) and dim2 (<=0) with the following code:
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)
I am not sure how to replace only the values in the 1st dimension that need to be replaced and only the values in the second that need to be replaced.
As a side note, i also ran into this issue but was able to solve it.