web-dev-qa-db-fra.com

Comment appliquer la fonction torch.inverse () de PyTorch à chaque échantillon du lot?

Cela peut sembler une question fondamentale, mais je suis incapable de la résoudre.

Dans le passage en avant de mon réseau de neurones, j'ai un tenseur de sortie de forme 8x3x3, où 8 est la taille de mon lot. Nous pouvons supposer que chaque tenseur 3x3 est une matrice non singulière. Je dois trouver l'inverse de ces matrices. La fonction PyTorch inverse () ne fonctionne que sur les matrices carrées. Depuis que j'ai maintenant 8x3x3, comment puis-je appliquer cette fonction à chaque matrice du lot de manière différentiable?

Si je parcourt les exemples et que j'ajoute les inverses à une liste python que je convertis ensuite en tenseur PyTorch, cela devrait-il poser un problème pendant le backprop? (Je demande depuis la conversion des tenseurs de PyTorch en numpy d'effectuer certaines opérations, puis de revenir à un tenseur ne calculera pas les gradients pendant le backprop pour de telles opérations)

Je reçois également l'erreur suivante lorsque j'essaie de faire quelque chose comme ça.

a = torch.arange(0,8).view(-1,2,2)
b = [m.inverse() for m in a]
c = torch.FloatTensor(b)

TypeError: l'objet 'torch.FloatTensor' ne supporte pas l'indexation

5
phoenixwing

EDIT:

Depuis la version 1.0 de Pytorch, torch.inverse prend désormais en charge les lots de tenseurs. Voir ici . Vous pouvez donc simplement utiliser la fonction intégrée torch.inverse

ANCIENNE REPONSE

Il est prévu d'implémenter l'inverse en batch prochainement. Pour en savoir plus, voir par exemple numéro 7500 ou numéro 9102 . Toutefois, à la date de rédaction de la version stable actuelle (0.4.1), aucune opération inverse en mode batch n’est disponible. 

Cela dit, la prise en charge par lots pour torch.gesv a récemment été ajoutée. Cela peut être (ab) utilisé pour définir votre propre opération inverse par lots selon les lignes suivantes:

def b_inv(b_mat):
    eye = b_mat.new_ones(b_mat.size(-1)).diag().expand_as(b_mat)
    b_inv, _ = torch.gesv(eye, b_mat)
    return b_inv

J'ai trouvé que cela donne de bonnes accélérations par rapport à une boucle for lors de l'exécution sur GPU. 

4
mexmex

Vous pouvez scinder le tenseur à l'aide de torch.functional.unbind(), appliquer l'inverse à chaque élément du résultat, puis empiler:

a = torch.arange(0,8).view(-1,2,2)
b = [t.inverse() for t in torch.functional.unbind(a)]
c = torch.functional.stack(b)
0