Pytorch'ta yeniden şekillendirme ve görüntüleme arasındaki fark nedir?


93

Numpy'de ndarray.reshape()bir diziyi yeniden şekillendirmek için kullanırız .

Pytorch'ta insanların torch.view(...)aynı amaç için kullandıklarını fark ettim , ama aynı zamanda bir de torch.reshape(...)var.

Bu yüzden aralarındaki farkların ne olduğunu ve bunlardan birini ne zaman kullanmam gerektiğini merak ediyorum.

Yanıtlar:


99

torch.viewuzun zamandır var. Yeni şekli ile bir tensör döndürecektir. Döndürülen tensör, temel veriyi orijinal tensörle paylaşacaktır. Buradaki belgelere bakın .

Öte yandan, torch.reshape son zamanlarda 0.4 sürümünde tanıtıldığı görülüyor . Göre belgede , bu yöntem olacak

Girdi ile aynı veriye ve öğe sayısına sahip, ancak belirtilen şekle sahip bir tensör döndürür. Mümkün olduğunda, geri dönen tensör bir girdi görünümü olacaktır. Aksi takdirde bir kopya olacaktır. Uyumlu adımlarla bitişik girişler ve girişler kopyalamadan yeniden şekillendirilebilir, ancak kopyalama ve görüntüleme davranışına bağlı olmamalısınız.

Bu torch.reshape, orijinal tensörün bir kopyasını veya bir görünümünü döndürebileceği anlamına gelir . Bir görünümü veya bir kopyasını iade edeceğinize güvenemezsiniz. Geliştiriciye göre:

Bir kopyaya ihtiyacınız varsa, aynı depolamaya ihtiyacınız varsa, clone () öğesini kullanın, view () öğesini kullanın. Reshape () 'nin anlam bilgisi, depolamayı paylaşabilir veya paylaşmayabilir ve önceden bilmediğinizdir.

Diğer bir fark, reshape()hem bitişik hem de bitişik olmayan tensör view()üzerinde çalışabilirken, yalnızca bitişik tensör üzerinde çalışabilmesidir. Ayrıca anlamı için buraya bakın contiguous.


30
Torch.view'un yalnızca bitişik tensörler üzerinde çalışabileceğini, torch.reshape'in her ikisinde de çalışabileceğini vurgulamak da yardımcı olabilir.
p13rr0m

6
@pierrom contiguous burada bitişik bellekte depolanan tensörlere mi yoksa başka bir şeye mi atıfta bulunuyor?
gokul_uf

3
@gokul_uf Evet, burada yazılan yanıta bir göz atabilirsiniz: stackoverflow.com/questions/48915810/pytorch-contiguous
MBT

"tensörün görünümü" ifadesi pytorch'ta mı ifade ediliyor?
Charlie Parker

"Uyumlu adımların" ne olduğu konusunda bir açıklama yapmak faydalı olacaktır. Teşekkürler!
bruin

45

Her ikisi de torch.viewve torch.reshapetensörleri yeniden şekillendirmek için kullanılsa da, aralarındaki farklar aşağıdadır.

  1. Adından da anlaşılacağı gibi, torch.viewyalnızca orijinal tensörün bir görünümünü oluşturur . Yeni tensör , verilerini her zaman orijinal tensörle paylaşacaktır. Bu, orijinal tensörü değiştirirseniz, yeniden şekillendirilmiş tensörün değişeceği ve bunun tersi olacağı anlamına gelir.
>>> z = torch.zeros(3, 2)
>>> x = z.view(2, 3)
>>> z.fill_(1)
>>> x
tensor([[1., 1., 1.],
        [1., 1., 1.]])
  1. Yeni tensörün verilerini her zaman orijinalle paylaştığından emin olmak için torch.view, iki tensörün [ docs ] şekillerine bazı bitişiklik kısıtlamaları getirir . Çoğu zaman bu bir sorun değildir, ancak bazen torch.viewiki tensörün şekilleri uyumlu olsa bile bir hata verir. İşte ünlü bir karşı örnek.
>>> z = torch.zeros(3, 2)
>>> y = z.t()
>>> y.size()
torch.Size([2, 3])
>>> y.view(6)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: invalid argument 2: view size is not compatible with input tensor's
size and stride (at least one dimension spans across two contiguous subspaces).
Call .contiguous() before .view().
  1. torch.reshapeherhangi bir bitişiklik kısıtlaması getirmez, ancak veri paylaşımını da garanti etmez. Yeni tensör, orijinal tensörün bir görünümü olabilir veya tamamen yeni bir tensör olabilir.
>>> z = torch.zeros(3, 2)
>>> y = z.reshape(6)
>>> x = z.t().reshape(6)
>>> z.fill_(1)
tensor([[1., 1.],
        [1., 1.],
        [1., 1.]])
>>> y
tensor([1., 1., 1., 1., 1., 1.])
>>> x
tensor([0., 0., 0., 0., 0., 0.])

TL; DR:
Sadece tensörleri yeniden şekillendirmek istiyorsanız kullanın torch.reshape. Bellek kullanımı konusunda da endişeleriniz varsa ve iki tensörün aynı verileri paylaştığından emin olmak istiyorsanız, kullanın torch.view.


1
Belki sadece benim, ama yeniden şekillendirmenin veriyi paylaşıp paylaşmaması arasındaki belirleyici faktörün bitişiklik olduğunu düşünmeye başladım. Kendi deneylerime göre, durum böyle değil. (Sizin xve yüstünüzün ikisi de bitişiktir). Belki bu açıklığa kavuşturulabilir? Belki yeniden şekillendirmenin ne zaman kopyalayıp kopyalayamayacağına dair bir yorum yardımcı olabilir mi?
RMurphy

7

Tensor.reshape()daha sağlamdır. İken, herhangi bir tensör üzerinde çalışacak Tensor.view()tensör üzerinde çalışır tnerede t.is_contiguous()==True.

Bitişik olmayan ve bitişik hakkında açıklama yapmak başka bir zaman öyküsüdür, ancak tensörü her zaman tbitişik yapabilirsin, ararsan t.contiguous()ve sonra view()hatasız arayabilirsin .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.