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!
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
...
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.