0
votes

I have this numpy code I wish to use inside my loss function:

import numpy as np

y_true = np.random.randint(10, size=10000)
y_pred = np.random.randint(10, size=10000)
A = np.random.randint(12, size=(12,12))

S = -np.sum(A[y_true[:], y_pred[:]]) 

Obs: The "A" is 2-dimensional numpy array, the "penalty matrix" I need to use for my loss function and its dimensions are 12x12. Both y_true and y_pred are nx1 numpy arrays It works fine, but what I actually want is the Tensor version of it. I have tried the following already:

import keras.backend as K
import tensorflow as tf

A = tf.constant(A)
y_true = tf.constant(y_true)
y_pred = tf.constant(y_pred)

S = -K.sum(A[y_true[:], y_pred[:]])

Obs: The "A" in this case is a 2-dimensional tensor, the "penalty matrix" I need to use for my loss function and its dimensions are 12x12. Both y_true and y_pred are Nx1 tensors. I want to performs the same operation but using Tensors. I have tried the following already: But I got the following error:

InvalidArgumentError: Expected begin, end, and strides to be 1D equal size tensors, but got shapes [2,12,1], [2,12,1], and [2] instead. [Op:StridedSlice] name: strided_slice/
1
Please provide a minimal, reproducible example. Something that users can copy and paste and run without having to change anything. - jakub
Ok, added some sample data just now. - João

1 Answers

0
votes

You can use tf.gather_nd for this.

tf.gather_nd(A, tf.stack((y_true, y_pred), axis=-1))

is equivalent to

A[y_true, y_pred]

Please see below for complete numpy and tensorflow code.

import numpy as np
import tensorflow as tf

K = tf.keras.backend

y_true = np.random.randint(10, size=10000)
y_pred = np.random.randint(10, size=10000)
A = np.random.randint(12, size=(12,12))

S_np = -np.sum(A[y_true, y_pred])
S_tf = -K.sum(tf.gather_nd(A, tf.stack((y_true, y_pred), axis=-1)))

assert S_np == S_tf.numpy()

By the way, y_true[:] is redundant in this case and can be written as y_true.

Also, do not mix tf.keras and keras. I am not sure if you were, but please stick to one or the other, preferably tf.keras.