2017-03-24 2 views
2

Je tente d'implémenter une couche Lambda qui produira une fonction de perte personnalisée. Dans la couche, je dois être capable de comparer chaque élément d'un lot à tous les autres éléments du lot afin de calculer le coût. Idéalement, je veux un code qui ressemble à ceci:Couche Lambda Keras pour perte personnalisée

for el_1 in zip(y_pred, y_true): 
    for el_2 in zip(y_pred, y_true): 
     if el_1[1] == el_2[1]: 
      # Perform a calculation 
     else: 
      # Perform a different calculation 

Quand je vrai, je reçois:

TypeError: TensorType does not support iteration. 

J'utilise la version 2.0.2 Keras avec une version 0.9.0 Théano back-end. Je comprends que j'ai besoin d'utiliser les fonctions de tenseurs de Keras pour faire cela, mais je ne peux pas trouver de fonctions de tenseurs qui font ce que je veux.

En outre, j'ai de la difficulté à comprendre précisément quelle devrait être ma fonction Lambda. Est-ce un tenseur du coût total pour chaque échantillon, ou est-ce juste un coût total pour le lot?

Je me bats la tête depuis des jours. Toute aide est très appréciée.

+0

Bon, en utilisant Keras callbacks, j'ai déterminé ce que le Lambda est censé renvoyer - un scalaire par lot. Cependant, je n'arrive toujours pas à comprendre comment itérer sur les tenseurs pendant l'entraînement. Je pense que cela pourrait avoir à voir avec le découpage en tranches ... – gaw89

+0

Avez-vous lu ma réponse? – nemo

+0

Désolé, passé le week-end. Juste accepté. Merci beaucoup! – gaw89

Répondre

2

Un tenseur dans Keras a généralement au moins 2 dimensions, le lot et la dimension neurone/unité/nœud/.... Une couche dense de 128 unités entraînées avec une taille de lot de 64 donnerait donc un tenseur de forme (64,128). Votre LambdaLayer traite les tenseurs comme n'importe quelle autre couche, en les branchant après votre couche dense d'avant, vous obtiendrez un tenseur de la forme (64,128) à traiter. Le traitement d'un tenseur fonctionne de la même façon que les calculs sur les tableaux numpy (ou toute autre bibliothèque de traitement vectoriel): vous spécifiez une opération à diffuser sur tous les éléments de la structure de données.

Par exemple, le coût personnalisé est la différence pour chaque valeur dans le lot, vous mettre en œuvre comme si:

cost_layer = LambdaLayer(lambda a,b: a - b) 

L'opération - est diffusée sur a et b et renverra un résultat approprié prévu les dimensions correspondent. Le point à retenir est que vous ne pouvez vraiment spécifier qu'une seule opération pour chaque valeur. Si vous voulez effectuer des tâches plus complexes, par exemple des calculs basés sur la valeur, vous avez besoin d'opérations uniques qui prennent deux opérations et appliquent la bonne en conséquence, c'est-à-dire l'opération switch.

La syntaxe de K.switch est

K.switch(condition, then_expression, else_expression) 

Par exemple, si vous voulez soustraire les deux valeurs quand a != b mais les ajouter quand ils sont égaux, vous écrivez:

import keras.backend as K 
cost_layer = LambdaLayer(lambda a,b: K.switch(a != b, a - b, a + b))