web-dev-qa-db-fra.com

Opérations sur place avec PyTorch

Je me demandais comment gérer les opérations sur place à PyTorch. Si je me souviens bien, l'utilisation du fonctionnement sur place avec Autograd a toujours été problématique.

Et en fait, je suis surpris que ce code ci-dessous fonctionne, même si je ne l'ai pas testé, je pense que ce code aurait soulevé une erreur dans la version 0.3.1.

Fondamentalement, je veux faire est de définir une certaine position d'un vecteur tensoriel à une certaine valeur dans un similaire:

my_tensor[i] = 42

Exemple de code de travail:

# test parameter a
a = torch.Rand((2), requires_grad=True)
print('a ', a)
b = torch.Rand(2)

# calculation
c = a + b

# performing in-place operation
c[0] = 0
print('c ', c)
s = torch.sum(c)
print('s ', s)

# calling backward()
s.backward()

# optimizer step
optim = torch.optim.Adam(params=[a], lr=0.5)
optim.step()

# changed parameter a
print('changed a', a)

Sortie:

a  tensor([0.2441, 0.2589], requires_grad=True)
c  tensor([0.0000, 1.1511], grad_fn=<CopySlices>)
s  tensor(1.1511, grad_fn=<SumBackward0>)
changed a tensor([ 0.2441, -0.2411], requires_grad=True)

Alors évidemment dans la version 0.4.1. cela fonctionne très bien sans avertissements ni erreurs.

En référence à cet article dans la documentation: autograd-mechanics

La prise en charge des opérations sur place dans Autograd est une question difficile et nous déconseillons leur utilisation dans la plupart des cas . La libération et la réutilisation agressives du tampon d'Autograd le rendent très efficace et il y a très peu d'occasions où les opérations sur place réduisent réellement l'utilisation de la mémoire de manière significative. À moins que vous n'utilisiez une pression de mémoire élevée, vous n'aurez peut-être jamais besoin de les utiliser.

Mais même si cela fonctionne, l'utilisation des opérations sur place est déconseillée dans la plupart des cas.


Mes questions sont donc:

  • Comment beaucoup l'utilisation des opérations sur place affecte-t-elle les performances?

  • Comment puis-je me déplacer en utilisant des opérations sur place dans les cas où je veux définir un élément d'un tenseur à une certaine valeur?

Merci d'avance!

14
MBT

Je ne sais pas dans quelle mesure les opérations sur place affectent les performances, mais je peux répondre à la deuxième requête. Vous pouvez utiliser un masque au lieu d'opérations sur place.

a = torch.Rand((2), requires_grad=True)
print('a ', a)
b = torch.Rand(2)

# calculation
c = a + b

# performing in-place operation
mask = np.zeros(2)
mask[1] =1
mask = torch.tensor(mask)
c = c*mask
...
2
Umang Gupta

Pour votre deuxième requête, lorsque vous effectuez une c[i] = i ou opérations similaires, __setitem__ est généralement appelé. Pour effectuer cette opération sur place, vous pouvez essayer d'appeler le __setitem__ fonction (si c'est ce qui exécute le c[i] = i opération.

0
BBloggsbott