Basitçe söylemek gerekirse, torch.Tensor.view()
esinlenerek numpy.ndarray.reshape()
veya esinlenerek , yeni şekil orijinal tensörün şekli ile uyumlu olduğu sürece, tensörün yeni bir görünümününumpy.reshape()
oluşturur .
Somut bir örnek kullanarak bunu ayrıntılı olarak anlayalım.
In [43]: t = torch.arange(18)
In [44]: t
Out[44]:
tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17])
Bu t
şekil tensörü ile , yalnızca aşağıdaki şekiller için (18,)
yeni görünümler oluşturulabilir:
(1, 18)
ya da eşdeğer (1, -1)
ya da eşdeğer ya da eşdeğer ya da eşdeğer ya da eşdeğer ya da eşdeğer ya da(-1, 18)
(2, 9)
(2, -1)
(-1, 9)
(3, 6)
(3, -1)
(-1, 6)
(6, 3)
(6, -1)
(-1, 3)
(9, 2)
(9, -1)
(-1, 2)
(18, 1)
(18, -1)
(-1, 1)
Yukarıdaki şekil tüplerinden zaten gözlemleyebileceğimiz gibi, şekil demetinin elemanlarının (örn. 2*9
, 3*6
Vb.) Çoğaltılması her zaman orijinal tensördeki toplam 18
örneğe eşit olmalıdır ( örneğimizde).
Gözlemlenecek bir başka şey -1
de, şekil tupleslerinin her birinde bir yer kullanmış olmamızdır . A kullanarak -1
, hesaplamayı kendimiz yapmakta tembel davranıyoruz ve yeni görünümü oluştururken şekil için bu değerin hesaplanmasını yapmak için görevi PyTorch'a devrediyoruz . Unutulmaması gereken önemli bir nokta, şekil demetinde sadece bir tane kullanabileceğimizdir -1
. Kalan değerler bizim tarafımızdan açıkça belirtilmelidir. Else PyTorch atarak şikayet edecek RuntimeError
:
RuntimeError: yalnızca bir boyut çıkarılabilir
Bu nedenle, yukarıda belirtilen şekillerin hepsiyle, PyTorch her zaman orijinal tensörün yeni bir görünümünü döndürecektir t
. Bu temel olarak, istenen yeni görünümlerin her biri için sadece tensörün adım bilgilerini değiştirdiği anlamına gelir.
Aşağıda, her yeni görünümde tansörlerin adımlarının nasıl değiştiğini gösteren bazı örnekler verilmiştir .
# stride of our original tensor `t`
In [53]: t.stride()
Out[53]: (1,)
Şimdi, yeni görünümlerin adımlarını göreceğiz :
# shape (1, 18)
In [54]: t1 = t.view(1, -1)
# stride tensor `t1` with shape (1, 18)
In [55]: t1.stride()
Out[55]: (18, 1)
# shape (2, 9)
In [56]: t2 = t.view(2, -1)
# stride of tensor `t2` with shape (2, 9)
In [57]: t2.stride()
Out[57]: (9, 1)
# shape (3, 6)
In [59]: t3 = t.view(3, -1)
# stride of tensor `t3` with shape (3, 6)
In [60]: t3.stride()
Out[60]: (6, 1)
# shape (6, 3)
In [62]: t4 = t.view(6,-1)
# stride of tensor `t4` with shape (6, 3)
In [63]: t4.stride()
Out[63]: (3, 1)
# shape (9, 2)
In [65]: t5 = t.view(9, -1)
# stride of tensor `t5` with shape (9, 2)
In [66]: t5.stride()
Out[66]: (2, 1)
# shape (18, 1)
In [68]: t6 = t.view(18, -1)
# stride of tensor `t6` with shape (18, 1)
In [69]: t6.stride()
Out[69]: (1, 1)
İşte bu view()
fonksiyonun büyüsü . Yeni görünümün şekli orijinal şekliyle uyumlu olduğu sürece, yalnızca yeni görünümlerin her biri için (orijinal) tensörün adımlarını değiştirir .
Adımlar dizilerini gözlemlemek olabilir bir başka ilginç olan bir 0 elemanın değeri olmasıdır inci pozisyon 1 'de elemanının değerine eşittir st şekil başlığın konumu.
In [74]: t3.shape
Out[74]: torch.Size([3, 6])
|
In [75]: t3.stride() |
Out[75]: (6, 1) |
|_____________|
Bunun nedeni ise:
In [76]: t3
Out[76]:
tensor([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17]])
adım (6, 1)
olduğunu 0 boyunca sonraki öğeye bir öğeden gitmek diyor inci Zorunda, boyutun atlamak ya da 6 adımları atın. (yani gitmek için 0
için 6
. bir 6 adım atması gerekir,) Ama 1'de sonraki öğeye bir öğeden gitmek st (örn dan gitmek için boyutun, sadece tek bir adım gerekir 2
için 3
).
Bu nedenle, adım bilgileri, hesaplamayı gerçekleştirmek için öğelere bellekten nasıl erişildiğinin merkezindedir.
Bu işlev bir görünüm döndürür torch.Tensor.view()
ve yeni şekil orijinal tensörün şekliyle uyumlu olduğu sürece kullanmakla tamamen aynıdır . Aksi takdirde bir kopyasını döndürür.
Ancak, notlar şunları torch.reshape()
uyarıyor:
bitişik girişler ve uyumlu adımlara sahip girişler kopyalamadan yeniden şekillendirilebilir, ancak kopyalama ve görüntüleme davranışına bağlı olmamalıdır.
reshape
numpy'nin yeniden şekillenmesine benziyor" - neden sadece PyTorch'ta çağırmadılar ?!