J'essaie de créer une fonction de perte personnalisée dans keras. Malheureusement, j'ai peu de connaissances sur le flux tensoriel. Existe-t-il un moyen de convertir les tenseurs entrants en un tableau numpy pour pouvoir calculer ma fonction de perte?
Voici ma fonction:
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
Si ce n'est pas possible d'utiliser numpy array, quel est le meilleur moyen de calculer cette fonction avec tensorflow? Toute direction serait grandement appréciée, merci!
Edit 1: Voici quelques détails de mon modèle. J'utilise un réseau LSTM avec un fort décrochage. Les entrées sont un pas multi-variable multi-temps . Les sorties sont un tableau 2D de chiffres binaires (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))
(a pris la liberté de normaliser les noms de variables)
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
Bienvenue chez SO. Comme vous le savez peut-être, nous devons calculer le gradient de la fonction de perte. Nous ne pouvons pas calculer correctement le dégradé sur des tableaux numpy (ce sont juste des constantes).
Ce qui est fait (dans keras/theano, quels sont les systèmes utilisés avec keras), c’est la différenciation automatique sur les tenseurs (par exemple tf.placeholder()
). défaut sur des opérateurs comme tf.max
, tf.sum
.
Cela signifie pour vous que toutes les opérations sur les tenseurs (y_true
et y_pred
) doivent être réécrites pour utiliser les opérateurs tf/theeano.
Je vais commenter avec ce que je pense serait réécrit et vous pouvez substituer en conséquence et tester.
Voir tf.round utilisé en tant que K.tf.round
où K est la référence au backend de keras importé en tant que import keras.backend as K
x_true = np.round(x_true)
x_pred = np.round(x_pred)
Prenez la forme du tenseur x_true. K.shape. Calculer le ratio sur une constante pourrait rester aussiit comme ici
NumberOfBars = len(x_true)
NumberOfHours = NumberOfBars/60
Voir tf.where
utilisé comme K.tf.where
TradeIndex = np.where( x_pred[:,1] == 0 )[0]
Vous pouvez masquer le tenseur avec une condition au lieu de supprimer - voir masquer
##remove predictions that are not tradable
x_true = np.delete(x_true[:,0], TradeIndex)
x_pred = np.delete(x_pred[:,0], TradeIndex)
Voir tf.confusion_matrix
CM = confusion_matrix(x_true, x_pred)
Les calculs qui suivent sont des constantes de calcul et restent donc essentiellement les mêmes (conditionnés par
quels que soient les changements à apporter avec la nouvelle API)
J'espère pouvoir mettre à jour cette réponse avec une substitution valide qui s'exécute. Mais j'espère que cela va dans le bon sens.
Une suggestion sur le style de codage: je vois que vous utilisez trois versions de nommage de variable dans votre code, choisissez-en une et respectez-la.