13

I am trying to create my own loss function:

def custom_mse(y_true, y_pred):
    tmp = 10000000000
    a = list(itertools.permutations(y_pred))
    for i in range(0, len(a)): 
     t = K.mean(K.square(a[i] - y_true), axis=-1)
     if t < tmp :
        tmp = t
     return tmp

It should create permutations of predicted vector, and return the smallest loss.

   "Tensor objects are not iterable when eager execution is not "
TypeError: Tensor objects are not iterable when eager execution is not enabled. To iterate over this tensor use tf.map_fn.

error. I fail to find any source for this error. Why is this happening?

Red
  • 26,798
  • 7
  • 36
  • 58
Darlyn
  • 4,715
  • 12
  • 40
  • 90

1 Answers1

11

The error is happening because y_pred is a tensor (non iterable without eager execution), and itertools.permutations expects an iterable to create the permutations from. In addition, the part where you compute the minimum loss would not work either, because the values of tensor t are unknown at graph creation time.

Instead of permuting the tensor, I would create permutations of the indices (this is something you can do at graph creation time), and then gather the permuted indices from the tensor. Assuming that your Keras backend is TensorFlow and that y_true/y_pred are 2-dimensional, your loss function could be implemented as follows:

def custom_mse(y_true, y_pred):
    batch_size, n_elems = y_pred.get_shape()
    idxs = list(itertools.permutations(range(n_elems)))
    permutations = tf.gather(y_pred, idxs, axis=-1)  # Shape=(batch_size, n_permutations, n_elems)
    mse = K.square(permutations - y_true[:, None, :])  # Shape=(batch_size, n_permutations, n_elems)
    mean_mse = K.mean(mse, axis=-1)  # Shape=(batch_size, n_permutations)
    min_mse = K.min(mean_mse, axis=-1)  # Shape=(batch_size,)
    return min_mse
rvinas
  • 11,824
  • 36
  • 58
  • 1
    my y_true/y_pred are actually 1 dimensional vector – Darlyn Apr 01 '18 at 10:55
  • This seems quite weird to me. Are you permuting along the batch size dimension, then? – rvinas Apr 01 '18 at 10:56
  • seems like i am not, would you please elaborate? I am quite new to this. Thanks. – Darlyn Apr 01 '18 at 11:12
  • What do you get when you print `y_pred.get_shape()`? If you get 2 numbers (most common) my answer should be doing what you expect. The first number (batch size) indicates the number of examples that you feed into your network, and the second is the output dimensionality (i.e. number of outputs for each example). – rvinas Apr 01 '18 at 11:23
  • weird, i get (?,40), i am using batch_size = 5 – Darlyn Apr 01 '18 at 11:33
  • That's right! You'll usually get '?' for the batch dimension, which means that it is unknown at graph creation time. My function should be doing what you intended. – rvinas Apr 01 '18 at 12:20
  • howeve it seems like it enters in infite loop or something using this function. When i start the program it just waits, also it froze the pc – Darlyn Apr 01 '18 at 12:26
  • This happens because computing the permutations of 40 elements is prohibitive (there are 40!=40*39*...*2 permutations). – rvinas Apr 01 '18 at 14:26
  • i see. Is there any other way how to retrieve wanted result? I mean when output is vector , and find the smallest loss. Are there any others way how to calculate it without permutations? – Darlyn Apr 01 '18 at 14:46
  • Computing permutations of the predicted tensor seems quite strange to me, and I can't think of any example where this would be useful. There might be other ways to do something similar to what you want at a cheaper cost, but I think I can't help you because this depends a lot on your problem. – rvinas Apr 01 '18 at 14:55
  • Well i am detecting objects , so the output vector is (xmin,ymin,xmax,ymax....) and so on .. i am detecting max 10 objects ( 4 * 10 = 40 ). What i am trying to achieve is fix when for example my predicted vectors first 4 elements are closer to my second 4 elements ( so predicted box should be treated as my 2nd inputed box ) – Darlyn Apr 01 '18 at 15:07
  • I don't have experience in object detection, but if that's the case I wouldn't compute these permutations (in fact, this could even be harmful). Instead, I would reorder your labels (i.e. from top to bottom and from left to right) in order to encourage the network to predict the bounding boxes in the same manner (i.e. the network will first predict the bounding box having the top-left vertex closer to the top-left corner). Then, you could just use the standard MSE as the loss function. – rvinas Apr 01 '18 at 16:31
  • would you please elaborate or send some link for the topic? I have really hard time looking for some info on this. Also my label input is also 1D vector ( 40 elements ) – Darlyn Apr 01 '18 at 16:32
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/167998/discussion-between-rvinas-and-darlyn). – rvinas Apr 01 '18 at 16:36