Il existe de nombreuses fonctions objectives dans Keras ici.
Mais comment pouvez-vous créer votre propre fonction objectif, j'ai essayé de créer une fonction objectif très basique mais cela donne une erreur et il n'y a aucun moyen de connaître la taille des paramètres passés à la fonction au moment de l'exécution.
def loss(y_true,y_pred):
loss = T.vector('float64')
for i in range(1):
flag = True
for j in range(y_true.ndim):
if(y_true[i][j] == y_pred[i][j]):
flag = False
if(flag):
loss = loss + 1.0
loss /= y_true.shape[0]
print loss.type
print y_true.shape[0]
return loss
Je reçois 2 erreurs contradictoires,
model.compile(loss=loss, optimizer=ada)
File "/usr/local/lib/python2.7/dist-packages/Keras-0.0.1-py2.7.Egg/keras/models.py", line 75, in compile
updates = self.optimizer.get_updates(self.params, self.regularizers, self.constraints, train_loss)
File "/usr/local/lib/python2.7/dist-packages/Keras-0.0.1-py2.7.Egg/keras/optimizers.py", line 113, in get_updates
grads = self.get_gradients(cost, params, regularizers)
File "/usr/local/lib/python2.7/dist-packages/Keras-0.0.1-py2.7.Egg/keras/optimizers.py", line 23, in get_gradients
grads = T.grad(cost, params)
File "/usr/local/lib/python2.7/dist-packages/theano/gradient.py", line 432, in grad
raise TypeError("cost must be a scalar.")
TypeError: cost must be a scalar.
Il dit que le coût ou la perte retourné dans la fonction doit être un scalaire mais si je change la ligne 2 de loss = T.vector ('float64')
à
perte = T.scalar ('float64')
il montre cette erreur
model.compile(loss=loss, optimizer=ada)
File "/usr/local/lib/python2.7/dist-packages/Keras-0.0.1-py2.7.Egg/keras/models.py", line 75, in compile
updates = self.optimizer.get_updates(self.params, self.regularizers, self.constraints, train_loss)
File "/usr/local/lib/python2.7/dist-packages/Keras-0.0.1-py2.7.Egg/keras/optimizers.py", line 113, in get_updates
grads = self.get_gradients(cost, params, regularizers)
File "/usr/local/lib/python2.7/dist-packages/Keras-0.0.1-py2.7.Egg/keras/optimizers.py", line 23, in get_gradients
grads = T.grad(cost, params)
File "/usr/local/lib/python2.7/dist-packages/theano/gradient.py", line 529, in grad
handle_disconnected(elem)
File "/usr/local/lib/python2.7/dist-packages/theano/gradient.py", line 516, in handle_disconnected
raise DisconnectedInputError(message)
theano.gradient.DisconnectedInputError: grad method was asked to compute the gradient with respect to a variable that is not part of the computational graph of the cost, or is used only by a non-differentiable operator: <TensorType(float64, matrix)>
Voici mon petit extrait pour écrire de nouvelles fonctions de perte et les tester avant d'utiliser:
import numpy as np
from keras import backend as K
_EPSILON = K.epsilon()
def _loss_tensor(y_true, y_pred):
y_pred = K.clip(y_pred, _EPSILON, 1.0-_EPSILON)
out = -(y_true * K.log(y_pred) + (1.0 - y_true) * K.log(1.0 - y_pred))
return K.mean(out, axis=-1)
def _loss_np(y_true, y_pred):
y_pred = np.clip(y_pred, _EPSILON, 1.0-_EPSILON)
out = -(y_true * np.log(y_pred) + (1.0 - y_true) * np.log(1.0 - y_pred))
return np.mean(out, axis=-1)
def check_loss(_shape):
if _shape == '2d':
shape = (6, 7)
Elif _shape == '3d':
shape = (5, 6, 7)
Elif _shape == '4d':
shape = (8, 5, 6, 7)
Elif _shape == '5d':
shape = (9, 8, 5, 6, 7)
y_a = np.random.random(shape)
y_b = np.random.random(shape)
out1 = K.eval(_loss_tensor(K.variable(y_a), K.variable(y_b)))
out2 = _loss_np(y_a, y_b)
assert out1.shape == out2.shape
assert out1.shape == shape[:-1]
print np.linalg.norm(out1)
print np.linalg.norm(out2)
print np.linalg.norm(out1-out2)
def test_loss():
shape_list = ['2d', '3d', '4d', '5d']
for _shape in shape_list:
check_loss(_shape)
print '======================'
if __name__ == '__main__':
test_loss()
Ici, comme vous pouvez le voir, je teste la perte binary_crossentropy, et j'ai 2 pertes distinctes définies, une version numpy (_loss_np) une autre version tensor (_loss_tensor) [Remarque: si vous utilisez simplement les fonctions keras, cela fonctionnera avec Theano et Tensorflow ... mais si vous dépendez de l'un d'eux, vous pouvez également les référencer par K.theano.tensor.function ou K.tf.function]
Plus tard, je compare les formes de sortie et la norme L2 des sorties (qui devraient être presque égales) et la norme L2 de la différence (qui devrait être vers 0)
Une fois que vous êtes convaincu que votre fonction de perte fonctionne correctement, vous pouvez l'utiliser comme:
model.compile(loss=_loss_tensor, optimizer=sgd)
(Réponse corrigée) Un moyen simple de le faire est d'appeler le backend Keras:
import keras.backend as K
def custom_loss(y_true,y_pred):
return K.mean((y_true - y_pred)**2)
Ensuite:
model.compile(loss=custom_loss, optimizer=sgd,metrics = ['accuracy'])
c'est égal
model.compile(loss='mean_squared_error', optimizer=sgd,metrics = ['accuracy'])