Compréhension de la fonction Contiguous() dans pytorch
Annuaire d'articles
文章抄自
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 !