PyTorch contigus()
J'allais à travers cet exemple de la LSTM modèle de langue sur github (lien).
Ce qu'il fait, en général, est assez clair pour moi. Mais j'ai encore des difficultés à comprendre ce que l'appel de contiguous()
ne, ce qui se produit plusieurs fois dans le code.
Par exemple en ligne 74/75 du code de l'entrée et des séquences cibles de la LSTM sont créés.
De données (stockées dans ids
) est de 2 dimensions où la première dimension est la taille du lot.
for i in range(0, ids.size(1) - seq_length, seq_length):
# Get batch inputs and targets
inputs = Variable(ids[:, i:i+seq_length])
targets = Variable(ids[:, (i+1):(i+1)+seq_length].contiguous())
Donc comme un simple exemple, lors de l'utilisation de la taille des lots 1 et seq_length
10 inputs
et targets
ressemble à ceci:
inputs Variable containing:
0 1 2 3 4 5 6 7 8 9
[torch.LongTensor of size 1x10]
targets Variable containing:
1 2 3 4 5 6 7 8 9 10
[torch.LongTensor of size 1x10]
Donc, en général, ma question est, qu'est - contiguous()
et pourquoi en ai-je besoin?
De plus je ne comprends pas pourquoi la méthode est appelée pour la séquence cible et mais pas la séquence d'entrée que les deux variables sont composés des mêmes données.
Comment pourrait - targets
être uncontiguous et inputs
encore être contigus?
EDIT:
J'ai essayé de laisser de côté l'appel de contiguous()
, mais cela conduit à un message d'erreur lors du calcul de la perte.
RuntimeError: invalid argument 1: input is not contiguous at .../src/torch/lib/TH/generic/THTensor.c:231
Alors, évidemment, l'appel de contiguous()
dans cet exemple est nécessaire.
(Pour garder cette lisibles j'ai évité de poster le code complet ici, il peut être trouvé en utilisant le GitHub lien ci-dessus.)
Merci d'avance!
OriginalL'auteur blue-phoenox | 2018-02-21
Vous devez vous connecter pour publier un commentaire.
Il y a quelques opérations sur les Tenseurs en PyTorch qui ne change pas vraiment le contenu du tenseur, mais seulement la façon de convertir les indices de tenseur des octets de l'emplacement. Ces opérations comprennent:
Par exemple: lorsque vous appelez
transpose()
, PyTorch ne pas générer de nouvelles tenseur avec la nouvelle mise en page, c'est juste modifie les méta-informations dans Tenseur objet, afin de compenser et de la foulée sont de nouveau en forme. Le tenseur transposé et tenseur d'origine sont en effet le partage de la mémoire!C'est là que le concept de contiguë. Au-dessus de
x
est contigus, maisy
n'est pas parce que sa mémoire mise en page est différente de celle d'un tenseur de même forme, fabriqué à partir de zéro. Notez que le mot "contigu" est un peu trompeur, car ce n'est pas que le contenu du tenseur s'étale autour d'déconnecté des blocs de mémoire. Ici octets sont toujours attribuées dans un bloc de mémoire, mais l'ordre des éléments est différent!Lorsque vous appelez
contiguous()
, il est en fait une copie de tenseur de l'ordre des éléments serait même que si le tenseur de même forme créée à partir de zéro.Normalement, vous n'avez pas besoin de vous inquiéter à ce sujet. Si PyTorch attend contiguë tenseur mais si ses pas, puis vous obtiendrez
RuntimeError: input is not contiguous
et puis il suffit d'ajouter un appel àcontiguous()
.Je ne peux pas répondre de façon définitive à cela, mais ma conjecture est que certains de la PyTorch code utilise de haute performance vectorisé mise en œuvre des opérations mises en œuvre en C++ et ce code ne peut pas utiliser arbitraire offset/progrès spécifié dans Tenseur de méta-informations. C'est juste une supposition bien.
Pourquoi ne pas le destinataire de l'appel appelez simplement
contiguous()
par lui-même?OriginalL'auteur Shital Shah
De la pytorch documentation:
Où
contiguous
signifie ici contigus en mémoire. Ainsi, lecontiguous
fonction n'affecte pas votre cible tenseur du tout, il a juste fait en sorte qu'il est stocké dans un espace contigu de mémoire.C'est juste pour la performance. Je ne sais pas pourquoi les codes-t-il pour cibles, mais pas pour les entrées.
mh.. il doit aussi y avoir une raison pour appeler la méthode, j'ai essayé sans et obtenu un message d'erreur. J'ai édité la question ci-dessus.
Donc, apparemment, pytorch exige que les objectifs de la perte à la continguous dans la mémoire, mais les entrées de neuralnet n'avez pas besoin de répondre à cette exigence.
Un grand merci à vous! Je pense que cela fait sens pour moi, j'ai remarqué que contiguë() est également appliqué à la sortie de données (ce qui bien entendu était autrefois l'entrée) dans la fonction de transfert, de sorte que les résultats et les objectifs sont contigus, lors du calcul de la perte. Merci beaucoup!
OriginalL'auteur patapouf_ai
Comme dans la réponse précédente états contigus() alloue états contigus segments de mémoire, il sera utile quand nous sommes passant tenseur c ou c++ backend code où les tenseurs sont passé en tant que pointeurs
OriginalL'auteur p. vignesh