Jane Sully
Jane Sully

Reputation: 3347

"Tensor objects are only iterable when eager execution is enabled" error when trying to create custom loss function in Keras

I am trying to do SVD using a neural network. My input is a matrix (let's say 4x4 matrices only) and the output is a vector representing the decomposed form (given that the input is 4x4 this would be a 36 element vector with 16 elements for U, 4 elements for S, and 16 elements for V.T).

I am trying to define a custom loss function instead of using something like MSE on the decomposed form. So instead of comparing the 36 length vectors for loss, I want to compute the loss between the reconstructed matrices. So if A = U * S * V.T (actual) and A' = U' * S' * V.T' (predicted), I want to compute the loss between A and A'.

I am pretty new to tensorflow and keras, so I may be doing some naive things, but here is what I have so far. While the logic seems okay to me, I get a TypeError: Tensor objects are only iterable when eager execution is enabled. To iterate over this tensor use tf.map_fn. I am not sure why this is the case and how to fix it? Also, do I need to flatten the output from the reconstruct_matrix, as I am currently doing, or should I just leave it as is?

# This function takes the decomposed matrix (vector of U, S, V.T)
# and reconstructs the original matrix

def reconstruct_matrix(decomposed_vector):
  example = decomposed_vector
  s = np.zeros((4,4))
  for en, i in enumerate(example[16:20]):
    s[en, en] = i
  u = example[:16].reshape(4,4)
  vt = example[20:].reshape(4,4)
  orig = np.matmul(u, s)
  orig = np.matmul(orig, vt)
  return orig.flatten() # Given that matrices are 4x4, this will be a length 16 vector

# Custom loss that essentially computes MSE on reconstructed matrices 

def custom_loss(y_true, y_pred):
    Y = reconstruct_matrix(y_true)
    Y_prime = reconstruct_matrix(y_pred)
    return K.mean(K.square(Y - Y_prime)) 

model.compile(optimizer='adam',
              loss=custom_loss)

Note: My keras version is 2.2.4 and my tensorflow version is 1.14.0.

Upvotes: 1

Views: 3486

Answers (1)

Szymon Maszke
Szymon Maszke

Reputation: 24884

In tf1.x eager execution is disabled by default (it's on for version 2 onwards).

You have to enable it by calling at the top of your script:

import tensorflow as tf

tf.enable_eager_execution()

This mode allows you to use Python-like abstractions for flow control (e.g. if statements and for loop you've been using in your code). If it's disabled you need to use Tensorflow functions (tf.cond and tf.while_loop for if and for respectively).

More information about it in the docs.

BTW. I'm not sure about flatten, but remember your y_true and y_pred need the same shape and samples have to be respective to each other, if that's fulfilled you should be fine.

Upvotes: 1

Related Questions