Compréhension de la fonction Contiguous() dans pytorch

Compréhension de la fonction Contiguous() dans pytorch




文章抄自 Compréhension de la fonction contigu() dans Pytorch - la lumière du matin - RPSC ,仅用作个人学习和记录。如有帮助,请关注原作者,给原作者点赞。


introduction

Dans pytorch, il n'y a que quelques opérations qui ne changent pas le contenu du tenseur lui-même , mais redéfinissent seulement la correspondance entre les indices et les éléments . En d'autres termes, cette opération ne copie ni ne modifie des données, mais des métadonnées .

Les opérations qui modifient les métadonnées sont :

  • étroit()
  • voir()
  • développer()
  • transposer()

Lors de l'utilisation de transpose() pour transposer, pytorch ne crée pas un nouveau tenseur transposé, mais modifie certaines propriétés (c'est-à-dire des métadonnées) dans le tenseur, de sorte que le décalage et la foulée à ce moment soient les mêmes que Transposer le tenseur correspondant. La mémoire du tenseur transposé est partagée avec le tenseur d'origine !

Modifier les métadonnées après transpose(), exemple de code :

x = torch.randn(3, 2)
y = torch.transpose(x, 0, 1)
print("修改前:")
print("x-", x)
print("y-", y)

print("\n修改后:")
y[0, 0] = 11
print("x-", x)
print("y-", y)

résultat de l'opération :

修改前:
x- tensor([[-0.5670, -1.0277],
           [ 0.1981, -1.2250],
           [ 0.8494, -1.4234]])
y- tensor([[-0.5670,  0.1981,  0.8494],
           [-1.0277, -1.2250, -1.4234]])
 
修改后:
x- tensor([[11.0000, -1.0277],
           [ 0.1981, -1.2250],
           [ 0.8494, -1.4234]])
y- tensor([[11.0000,  0.1981,  0.8494],
           [-1.0277, -1.2250, -1.4234]])

On peut voir que lorsque la valeur de l'élément de y est modifiée, la valeur de l'élément de x change également .

On peut donc dire que x est contigu mais que y ne l'est pas (car les données internes ne sont pas disposées de la manière habituelle). Attention à ne pas se méprendre sur le sens littéral de contigu, les données du tenseur sont toujours dans une zone de la mémoire, c'est juste une question de mise en page !

Pourquoi je dis cela : Parce que la façon dont les données sont disposées en y n'est pas la même que la création d'une disposition de tenseur régulière à partir de zéro . Cela peut être juste une copie superficielle qui était couramment utilisée en python auparavant. y pointe toujours vers l'emplacement de la variable x, juste pour enregistrer la disposition modifiée de transpose .


utiliser contigu()

Si vous voulez rompre la dépendance entre ces deux variables (x lui-même est contigu), vous devez utiliser contigu() pour changer x, ce que nous considérons comme une copie profonde .
Lors de l'appel de contiguous(), il forcera une copie de tensor afin que sa disposition soit exactement la même que celle créée à partir de zéro, mais les deux tenseurs sont complètement indépendants .

Exemple de code :

x = torch.randn(3, 2)
y = torch.transpose(x, 0, 1).contiguous()
print("修改前:")
print("x-", x)
print("y-", y)

print("\n修改后:")
y[0][0] = 11
print("x-", x)
print("y-", y)

résultat de l'opération :

修改前:
x- tensor([[ 0.9730,  0.8559],
           [ 1.6064,  1.4375],
           [-1.0905,  1.0690]])
y- tensor([[ 0.9730,  1.6064, -1.0905],
           [ 0.8559,  1.4375,  1.0690]])
 
修改后:
x- tensor([[ 0.9730,  0.8559],
           [ 1.6064,  1.4375],
           [-1.0905,  1.0690]])
y- tensor([[11.0000,  1.6064, -1.0905],
           [ 0.8559,  1.4375,  1.0690]])

Comme vous pouvez le voir, lorsque vous modifiez la valeur de y après avoir utilisé .contiguous() sur y , x n'a aucun effet !

post-scriptum

D'une manière générale, ne vous inquiétez pas trop à ce sujet. Lorsque vous rencontrez un endroit où vous devez appeler contiguous() , vous serez invité à l'exécution :

RuntimeError: input is not contiguous

Pour le moment, il vous suffit d'ajouter .contiguous() après la variable !

おすすめ

転載: blog.csdn.net/weixin_51524504/article/details/129145009