pytorch 方法筆記

可大俠發表於2020-11-13

masked_select

torch.masked_select(input, mask, *, out=None) → Tensor

根據mask上的bool取值,對input上的值進行取捨,若mask位置上取值為1那麼input對應位置上的值保留下來,最終輸出一個一維資料

引數

  • input:input tensor
  • mask:這個tensor值應當為bool型別(就是0、1或者True、False這種二取值型別)

>>>a = torch.Tensor([[4,5,7], [3,9,8],[2,3,4]])
>>>b = torch.Tensor([[1,1,0], [0,0,1],[1,0,1]]).type(torch.ByteTensor)
>>>c = torch.masked_select(a,b)
>>>print(c) 
tensor([4.,5.8.2.,4.])

max

torch.Tensor

scatter

sc

官網地址
pytorch中torch.Tensor.scatter用法
scatter_(dim, index, src, reduce=None) → Tensor

引數

  • dim:維度,可以是0,1,2…,表示只在第dim維進行修改
  • index:索引陣列,tensor,資料型別為整數,表示位置
  • src:原陣列,
  • reduce

示例

import torch 
>>>input = torch.randn(2, 4)
>>>print(input)
tensor([[-0.6482,  1.1430,  0.4962,  0.9425],
        [ 0.0092, -0.2958,  0.2240, -0.6358]])
>>>output = torch.zeros(2, 5)
>>>index = torch.tensor([[3, 1, 2, 0], [1, 2, 0, 3]])
>>>output = output.scatter(1, index, input)
>>>print(output)
tensor([[ 0.9425,  1.1430,  0.4962, -0.6482,  0.0000],
        [ 0.2240,  0.0092, -0.2958, -0.6358,  0.0000]])

上例dim=1,表示input陣列中的資料只是在第1維上進行重新分配,第0維不變。

  • input[0][0] -> output[0][index[0][0]] = output[0][3]
  • input[0][1] -> output[0][index[0][1]] = output[0][1]
  • input[0][2] -> output[0][index[0][2]] = output[0][2]
  • input[0][3] -> output[0][index[0][3]] = output[0][0]

unsqueeze

官網地址

torch.unsqueeze(input, dim) → Tensor

相當於在指定的dim上增加一維

>>>a = torch.Tensor([1,2,3,4,5,6])
>>>b = a.unsqueeze(0)
>>>b  #b.shape=(1,6)
 tensor([[1., 2., 3., 4., 5., 6.]])
 >>>b = a.unsqueeze(1)
 >>>b  #b.shape(6,1)
 tensor([[1.],
        [2.],
        [3.],
        [4.],
        [5.],
        [6.]])

squeeze

這個與unsqueeze相反,去掉相應維數

contiguous

contiguous(memory_format=torch.contiguous_format) → Tensor

view只能用在contiguous的variable上。
如果在view之前用了transpose,permute等,需要用contiguous來返回一個contiguous copy

有些tensor並不是佔用一整塊記憶體,而是由不同的資料塊組成,而tensor的view()操作依賴於記憶體是整塊的,這需要執行contiguous()這個函式,把tensor變成在記憶體中連續分佈的形式。

判斷是否contiguous用torch.Tensor.is_contiguous()

expand

torch.nn

torch.nn.utils.rnn.pad_packed_sequence

torch.nn.utils.rnn.pad_packed_sequence(sequence, batch_first=False, padding_value=0.0, total_length=None)

官方文件地址

Pytorch中的RNN之pack_padded_sequence()和pad_packed_sequence()
pytorch學習筆記(二十一): 使用 pack_padded_sequence

為什麼有pad和pack操作?

舉例,假如這個batch有5個sample

在這裡插入圖片描述
如果不用pack和pad操作會有一個問題,什麼問題呢?
上圖中,句子"Yes"只有一個單詞,但是padding了多餘的符號來填充,這回導致LSTM對它的表示通過了很多無用的字元,這樣得到的句子表示會有誤差,更直觀的如下圖:
在這裡插入圖片描述
正確的做法應該是什麼樣呢?
在上面這個例子,我們想要得到的表示僅僅是LSTM過完單詞"Yes"之後的表示,通過了多個無用的得到的表示:如下圖

在這裡插入圖片描述

torch.nn.utils.rnn.pack_padded_sequence()

這裡的pack,理解成壓緊比較好。將一個填充過的變長序列壓緊。(填充時候,會有冗餘,所以壓緊)
在這裡插入圖片描述
pack之後,原來填充的佔位符被刪掉。

輸入的形狀可以是 T × B × ∗ T \times B \times * T×B×.

  • T是最長序列長度
  • B是batch size
  • * 表示任意維度
  • batch_first=True,那麼相應的input size就是 B × T × ∗ B \times T \times * B×T×.

引數說明

  • input(Variable):變長序列 被填充後的 batch
  • lengths(list[int]) Variable中每個序列的長度,保證序列的長度是從大到小排列
  • batch_first(bool,optional):若是 T r u e True True,input的形狀應該是 B × T × s i z e B \times T \times size B×T×size

返回值:
一個PackedSequence物件

torch.nn.utils.rnn.pad_packed_sequence()
填充packed_sequence
上面提到的函式的功能是將一個填充後的變長序列壓緊。 這個操作和pack_padded_sequence()是相反的。把壓緊的序列再填充回來。填充時會初始化為0。

返回的Varaible的值的size是 T × B × ∗ , T×B×*, T×B×, T T T 是最長序列的長度,B 是 batch_size,如果 batch_first= T r u e True True,那麼返回值是 B × T × ∗ B×T×* B×T×

Batch中的元素將會以它們長度的逆序排列。

引數說明:

  • sequence (PackedSequence) – 將要被填充的 batch
  • batch_first (bool, optional) – 如果為 T r u e True True,返回的資料的格式為 B × T × ∗ B×T×* B×T×

相關文章