0

J'essaie de produire un modèle nn de sélection d'opération mathématique, basé sur l'entrée scalaire. L'opération est sélectionnée en fonction du résultat softmax produit par nn. Cette opération doit ensuite être appliquée à l'entrée scalaire pour produire la sortie finale. Jusqu'à présent, je suis arrivé à appliquer argmax et onehot sur la sortie softmax afin de produire un masque qui est ensuite appliqué sur la matrice de valeurs concaténées à partir de toutes les opérations possibles à effectuer (comme le montre le pseudo code ci-dessous). Le problème est que ni argmax ni onehot ne semble être différentiable. Je suis nouveau à cela, donc tout serait très apprécié. Merci d'avance.Comment effectuer une sélection d'opération différentiable dans TensorFlow?

#perform softmax  
    logits = tf.matmul(current_input, W) + b 
    softmax = tf.nn.softmax(logits) 

    #perform all possible operations on the input 
    op_1_val = tf_op_1(current_input) 
    op_2_val = tf_op_2(current_input) 
    op_3_val = tf_op_2(current_input) 
    values = tf.concat([op_1_val, op_2_val, op_3_val], 1) 

    #create a mask 
    argmax = tf.argmax(softmax, 1) 
    mask = tf.one_hot(argmax, num_of_operations) 

    #produce the input, by masking out those operation results which have not been selected 
    output = values * mask 

Répondre

0

Je crois que ce n'est pas possible. Ceci est similaire à Hard Attention décrit dans ce paper. Une attention particulière est utilisée dans le sous-titrage Image pour permettre au modèle de se concentrer uniquement sur une certaine partie de l'image à chaque étape. L'attention dure n'est pas différentiable mais il y a 2 manières de contourner ceci:

1- Utilisez l'apprentissage par renforcement (RL): RL est fait pour former des modèles qui prend des décisions. Même si la fonction de perte ne rétrograde pas les gradients au softmax utilisé pour la décision, vous pouvez utiliser les techniques RL pour optimiser la décision. Pour un exemple simplifié, vous pouvez considérer la perte comme une pénalité et envoyer au nœud, avec la valeur maximale dans la couche softmax, un gradient de politique proportionnel à la pénalité afin de diminuer le score de la décision si elle était mauvaise (résultats en perte élevée).

2- Utilisez quelque chose comme une attention douce: au lieu de choisir une seule opération, mélangez-les avec des poids basés sur la softmax. donc au lieu de:

output = values * mask 

Utilisation:

output = values * softmax 

Maintenant, les opérations vont converger vers zéro en fonction de combien le softmax ne pas les sélectionner. Ceci est plus facile à former par rapport à RL mais cela ne fonctionnera pas si vous devez complètement supprimer les opérations non sélectionnées du résultat final (les mettre à zéro complètement).

C'est une autre réponse qui parle dur et une attention douce que vous trouverez peut-être utile: https://stackoverflow.com/a/35852153/6938290

+0

Merci beaucoup pour votre réponse. J'ai expérimenté avec le softmax lui-même, et il ressemble à produire des valeurs proches de 1 pour les max et 0 pour les plus petits si la différence entre les logits est très grande. Est-il raisonnable de générer mon masque avec quelque chose comme 'softmax = tf.nn.softmax (10000 * logits)' pour produire la grande différence dans logits tout de suite ou je devrais former le nn pour ramasser cela à travers les poids? – user59271

+0

Je pense que vous devriez former le nn pour ramasser cela à travers les poids. Le seul problème avec la multiplication avec un grand nombre comme 1000 est qu'il va saturer le softmax tôt dans le processus d'entraînement. Le gradient de softmax pour les grandes valeurs de logits est proche de 0 donc les poids derrière le softmax recevront moins de mises à jour, même au début du processus d'entraînement. Bien que la multiplication par 1000 devrait augmenter les gradients, elle ne correspondra probablement pas à la dégradation exponentielle du gradient dans le softmax. –