0

I have a 2-channel numpy array of shape (64, 64, 2) as input to my CNN. I want to build a customized loss function as described in https://www.tensorflow.org/guide/keras/train_and_evaluate :

def basic_loss_function(y_true, y_pred):
    return tf.math.reduce_mean(tf.abs(y_true - y_pred))

model.compile(optimizer=keras.optimizers.Adam(),
              loss=basic_loss_function)

model.fit(x_train, y_train, batch_size=64, epochs=3)

But I want to something more complicated that this basic one. What I need is to do an inverse DFT (ifft2d) and my y_pred and y_true are expected to be each of shape (64,64,2), with the 2 channels being the real and imaginary parts of a fft2. How can I access correctly the y_pred and y_true channels (which are some kind of keras/tensor layer I guess?) to rebuild a complex number in the form RealPart+1j*ImagPart (in numpy it would be y_pred[:,:,0] and y_pred[:,:,1] ) ?

--> In summary, does someone know exactly what kind of object is y_pred and y_true and how to access their channels/elements? (This is not easy to debug since would need to be run in a compiled CNN, so better know it beforehand)

desertnaut
  • 57,590
  • 26
  • 140
  • 166
SheppLogan
  • 322
  • 3
  • 18

1 Answers1

1

y_true and y_pred are Tensors of shape (batchsize, ...[output shape]...). Your input has shape (64,64,2) but I'm not sure what your output looks like, if your output is indeed (64,64,2) then y_pred or y_true have shape (64,64,64,2) given your batchsize=64.

Dealing with Tensors is very much like numpy's syntax so You can use slice notation with tensors e.g., y_true[:,:,:,0] (note the added batch dimension).

Tensorflow has functions for computing DFT,FFT,..etc. See tf.signal and tf.signal.rfft2d

If your loss function involves operations on the input, not just the outputs y_true and y_pred, then you can use model.add_loss instead of model.compile(loss= basic_loss_function) as follows

x = Input(shape=(64,64,2))
y_true = Input(shape=...))
# your CNN layers
y_pred = Dense(128)(net)

model = Model(input=[x, y_true], output=y_pred)
model.add_loss(basic_loss_function(x, y_true, y_pred))

note that the labels (aka y_true) is now an input to the model.

MohamedEzz
  • 2,830
  • 3
  • 20
  • 26
  • great thanks, it does work. I have another question now ... since I m using tf2.1.0 my generators don't work anymore... in case you're interested :https://stackoverflow.com/questions/60583696/data-generators-with-tf2-1-0 – SheppLogan Mar 08 '20 at 01:11
  • I have implemented it, but have some problems... mind looking at : https://stackoverflow.com/questions/60590403/custom-keras-tf-loss-function-with-fft2d-ifft2d-inside-does-not-work – SheppLogan Mar 08 '20 at 18:06
  • @MohamedEzz Looks like you're using `output`, but never defined it. Can I safely assume that's a typo and you meant `y_pred`? – Mike Martin Aug 09 '20 at 01:27