Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting Tensor to Numpy Array - Custom Loss function In keras

I am trying to build a custom loss function in keras. Unfortunately i have little knowledge with tensor flow. Is there a way i can convert the incoming tensors into a numpy array so i can compute my loss function?

Here is my function:

def getBalance(x_true, x_pred):

    x_true = np.round(x_true)
    x_pred = np.round(x_pred)

    NumberOfBars = len(x_true)
    NumberOfHours = NumberOfBars/60

    TradeIndex = np.where( x_pred[:,1] == 0 )[0]

    ##remove predictions that are not tradable
    x_true = np.delete(x_true[:,0], TradeIndex)
    x_pred = np.delete(x_pred[:,0], TradeIndex)

    CM = confusion_matrix(x_true, x_pred)

    correctPredictions = CM[0,0]+CM[1,1]
    wrongPredictions = CM[1,0]+CM[0,1]
    TotalTrades = correctPredictions+wrongPredictions
    Accuracy = (correctPredictions/TotalTrades)*100

    return Accuracy 

If its not possible to use numpy array's what is the best way to compute that function with tensorflow? Any direction would be greatly appreciated, thank you!

Edit 1: Here are some details of my model. I am using a LSTM network with heavy drop out. The inputs are a multi-variable multi-time step. The outputs are a 2d array of binary digits (20000,2)

model = Sequential()

model.add(Dropout(0.4, input_shape=(train_input_data_NN.shape[1], train_input_data_NN.shape[2])))

model.add(LSTM(30, dropout=0.4, recurrent_dropout=0.4))

model.add(Dense(2))

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

history = model.fit(train_input_data_NN, outputs_NN, epochs=50,  batch_size=64, verbose=1, validation_data=(test_input_data_NN, outputs_NN_test))
like image 461
Aaron Isaac Avatar asked Mar 18 '18 15:03

Aaron Isaac


People also ask

Can you convert a tensor to NumPy array?

To convert back from tensor to numpy array you can simply run . eval() on the transformed tensor.

How do I create a custom loss function in keras?

Creating custom loss functions in Keras A custom loss function can be created by defining a function that takes the true values and predicted values as required parameters. The function should return an array of losses. The function can then be passed at the compile stage.

What does NumPy () do in TensorFlow?

numpy . This allows running NumPy code, accelerated by TensorFlow, while also allowing access to all of TensorFlow's APIs.

Is TensorFlow faster than NumPy?

Tensorflow is consistently much slower than Numpy in my tests.


1 Answers

EDIT: 1 Here is an untested substitution:

(took the liberty of normalizing the variable names )

def get_balance(x_true, x_pred):

    x_true = K.tf.round(x_true)
    x_pred = K.tf.round(x_pred)

    # didnt see the  need for these
    # NumberOfBars = (x_true)
    # NumberOfHours = NumberOfBars/60

    trade_index = K.tf.not_equal(x_pred[:,1], 0 )

    ##remove predictions that are not tradable
    x_true_tradeable = K.tf.boolean_mask(x_true[:,0], trade_index)
    x_pred_tradeable = K.tf.boolean_mask(x_pred[:,0], trade_index)

    cm = K.tf.confusion_matrix(x_true_tradeable, x_pred_tradeable)

    correct_predictions = cm[0,0]+cm[1,1]
    wrong_predictions = cm[1,0]+cm[0,1]
    total_trades = correction_predictions + wrong_predictions
    accuracy = (correct_predictions/total_trades)*100

    return accuracy 

Original Answer

Welcome to SO. As you might know we need to compute the the gradient on the loss function. We can't compute the gradient correctly on numpy arrays (they're just constants).

What is done ( in keras/theano which are the backends one uses with keras) is automatic differentiation on Tensors (e.g tf.placeholder()).This is not the entire story but what you should know at this point is that tf / theano gives us gradients by default on operators like tf.max, tf.sum.

What that means for you is all the operations on tensors (y_true and y_pred) should be rewritten to use tf / theano operators.

I'll comment with what I think would be rewritten and you can substitute accordingly and test.

See tf.round used as K.tf.round where K is the reference to the keras backend imported as import keras.backend as K

x_true = np.round(x_true)  
x_pred = np.round(x_pred)

Grab the shape of the tensor x_true. K.shape. Compute the ratio over a constant could remain as it as Here

NumberOfBars = len(x_true) 
NumberOfHours = NumberOfBars/60

See tf.where used as K.tf.where

TradeIndex = np.where( x_pred[:,1] == 0 )[0] 

You could mask the tensor w/ a condition instead of deleting - see masking

##remove predictions that are not tradable
x_true = np.delete(x_true[:,0], TradeIndex) 
x_pred = np.delete(x_pred[:,0], TradeIndex)

See tf.confusion_matrix

CM = confusion_matrix(x_true, x_pred)

The computation that follow are computation overs constants and so remain essentially the same ( conditioned on
whatever changes have to made given the new API )

Hopefully I can update this answer with a valid substitution that runs. But I hope this sets on the right path.

A suggestion on coding style: I see you use three version of variable naming in your code choose one and stick with it.

like image 184
parsethis Avatar answered Oct 31 '22 12:10

parsethis