1. 程式人生 > >Pytorch第一課:package-torch(1)之張量初識

Pytorch第一課:package-torch(1)之張量初識

微博:https://weibo.com/wangxiaocaoai/profile?rightmod=1&wvr=6&mod=personinfo
微信公眾號:搜尋"AI躁動街"


本節要點:

1 張量

2 建立張量的方式

3 張量的索引,切片,連線,換位等操作

4 隨機抽樣的操作

5 序列化(儲存與載入)

6 並行化

1 張量Tensor

1.1 判斷是否為張量

torch.is_tensor(obj) 如果obj 是一個pytorch張量,則返回True

import torch

# 建立一個普通數值
a = 1
print
(torch.is_tensor(a)) # 建立一個float型別的tensor b = torch.FloatTensor(a) print(torch.is_tensor(b))
False
True

1.2 判斷是否為一維陣列

torch.Storage是單個數據型別的連續的一維陣列,每個torch.Tensor都具有相同資料型別的相應儲存。他是torch.tensor底層資料結構,他除了像Tensor一樣定義數值,還可以直接把檔案對映到記憶體中進行操作

torch.is_storage(obj),如何obj 是一個pytorch storage物件,則返回True

# 建立torch.storage,共有以下8中型別
torch.FloatStorage([1,2,3,4,5])
torch.ByteStorage([1,2,3,4,5])
torch.ShortStorage([1,2,3,4,5])
torch.IntStorage([1,2,3,4,5])
torch.LongStorage([1,2,3,4,5])
torch.FloatStorage([1,2,3,4,5])
torch.DoubleStorage([1,2,3,4,5])
torch.ShortStorage([1,2,3,4,5])

# 判斷是否為torch.storage
# 隨機建立長度為5的一維陣列 a = torch.FloatStorage(5) print(a) # 判斷 print(torch.is_storage(a))
 0.0
 -0.0
 821.166015625
 4.657746965897047e-10
 5.000000953674316
[torch.FloatStorage of size 5]
True

1.3 設定預設的tensor型別

torch.set_default_tensor_type(torch.FloatTensor)
torch.get_default_dtype()
torch.float32

1.4 獲取張量中元素的個數

# 隨機建立1*2*3維的tensor
a = torch.randn(1,2,3)
print(a)

# 輸出元素個數
print(torch.numel(a))
tensor([[[-1.9520, -1.2041, -0.8372],
         [-0.8017, -0.5982,  0.5224]]])
6

1.5 設定列印選項

完全參考numpy

引數:

precision – 浮點數輸出的精度位數 (預設為8 )

threshold – 閾值,觸發彙總顯示而不是完全顯示(repr)的陣列元素的總數 (預設為1000)

edgeitems – 彙總顯示中,每維(軸)兩端顯示的項數(預設值為3)

linewidth – 用於插入行間隔的每行字元數(預設為80)。Thresholded matricies will ignore this parameter.

profile – pretty列印的完全預設值。 可以覆蓋上述所有選項 (預設為short, full)

torch.set_printoptions(precision=None, threshold=None, edgeitems=None, linewidth=None, profile=None)

2 建立操作 Creation Ops

2.1 建立對角位置為1的2維張量

torch.eye(n, m=None, out=None)

引數:

n (int ) – 行數

m (int, optional) – 列數.如果為None,則預設為n

out (Tensor, optinal) - Output tensor

a = torch.eye(4, 4)
print(a)
tensor([[ 1.,  0.,  0.,  0.],
        [ 0.,  1.,  0.,  0.],
        [ 0.,  0.,  1.,  0.],
        [ 0.,  0.,  0.,  1.]])

2.2 將numpy.ndarray 轉換為pytorch的 Tensor

返回的張量tensor和numpy的ndarray共享同一記憶體空間。修改一個會導致另外一個也被修改。返回的張量不能改變大小。

import numpy as np

# 互換
a = np.array([1,2,3,4])
print('a:',a)
t = torch.from_numpy(a)
print('t:', t)

# 共享記憶體,修改一個,另一個改變
t[0] = -10
print('a:',a)
a: [1 2 3 4]
t: tensor([ 1,  2,  3,  4])
a: [-10   2   3   4]

2.3 linspace建立1維張量:等差數列

包含在區間start 和 end 上均勻間隔的steps個點。 輸出1維張量的長度為steps。

引數:

start (float) – 序列的起始點

end (float) – 序列的最終值

steps (int) – 在start 和 end間生成的樣本數

out (Tensor, optional) – 結果張量

a = torch.linspace(start=1, end=20, steps=10)
print(a)
tensor([  1.0000,   3.1111,   5.2222,   7.3333,   9.4444,  11.5556,
         13.6667,  15.7778,  17.8889,  20.0000])

2.4 logspace建立1維張量:等比數列

返回一個1維張量,包含在區間 10start 和 10end上以對數刻度均勻間隔的steps個點。 輸出1維張量的長度為steps。

引數:

start (float) – 序列的起始點

end (float) – 序列的最終值

steps (int) – 在start 和 end間生成的樣本數

out (Tensor, optional) – 結果張量

a = torch.logspace(start=-10, end=10, steps=5)
print(a)
tensor([ 1.0000e-10,  1.0000e-05,  1.0000e+00,  1.0000e+05,  1.0000e+10])

2.5 建立全為1的張量

torch.ones(*sizes, out=None) → Tensor

引數:

sizes (int…) – 整數序列,定義了輸出形狀

out (Tensor, optional) – 結果張量

a = torch.ones(3, 4)
print(a)
tensor([[ 1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.],
        [ 1.,  1.,  1.,  1.]])

2.6 建立0-1隨機張量

回一個張量,包含了從區間[0,1)的均勻分佈中抽取的一組隨機數,形狀由可變引數sizes 定義。

引數:

sizes (int…) – 整數序列,定義了輸出形狀

out (Tensor, optinal) - 結果張量 例子:

a = torch.rand(3, 4)
print(a)
tensor([[ 0.4617,  0.3783,  0.5476,  0.6975],
        [ 0.9122,  0.4346,  0.7784,  0.4307],
        [ 0.6557,  0.1655,  0.3513,  0.8785]])

2.7 建立標準正態分佈隨機張量

返回一個張量,包含了從標準正態分佈(均值為0,方差為 1,即高斯白噪聲)中抽取一組隨機數,形狀由可變引數sizes定義。

引數:

sizes (int…) – 整數序列,定義了輸出形狀

out (Tensor, optinal) - 結果張量

a = torch.randn(3, 4)
print(a)
tensor([[ 0.4216,  0.0764,  0.5121, -0.6687],
        [-0.2173,  1.3139, -1.9322, -0.9506],
        [-0.1711, -0.4935, -0.0649, -0.0772]])

2.8 建立隨機整數排列

給定引數n,返回一個從0 到n -1 的隨機整數排列。

引數:

n (int) – 上邊界(不包含)

a = torch.randperm(10)
print(a)
tensor([ 6,  0,  7,  3,  2,  1,  8,  5,  4,  9])

2.9 建立有序序列(前閉後開)

torch.arange(start, end, step=1, out=None) → Tensor

返回一個1維張量,長度為 floor((end−start)/step)。包含從start到end,以step為步長的一組序列值(預設步長為1)。

引數:

start (float) – 序列的起始點

end (float) – 序列的終止點

step (float) – 相鄰點的間隔大小

out (Tensor, optional) – 結果張量

a = torch.arange(10, 20, 2)
print(a)
tensor([ 10.,  12.,  14.,  16.,  18.])

2.10 建立有序序列(前閉後閉)

警告:建議使用函式 torch.arange()

a = torch.range(10, 20, 2)
print(a)
tensor([ 10.,  12.,  14.,  16.,  18.,  20.])

2.11 建立全為0的張量

返回一個全為標量 0 的張量,形狀由可變引數sizes 定義。

引數:

sizes (int…) – 整數序列,定義了輸出形狀

out (Tensor, optional) – 結果張量

a = torch.zeros(3, 4)
print(a)
tensor([[ 0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.],
        [ 0.,  0.,  0.,  0.]])

3 索引,切片,連線,換位Indexing, Slicing, Joining, Mutating Ops

3.1 張量連線操作

torch.cat(inputs, dimension=0) → Tensor

引數:

inputs (sequence of Tensors) – 可以是任意相同Tensor 型別的python 序列

dimension (int, optional) – 沿著此維連線張量序列。

a = torch.randn(2, 4)
b = torch.randn(2, 4)
a_b_0 = torch.cat((a, b), 0)
a_b_1 = torch.cat((a, b), 1)

print(a)
print(b)
print(a_b_0)
print(a_b_1)

tensor([[ 0.6137,  0.1970, -0.2391, -0.9429],
        [ 1.8466,  1.6018,  1.4970,  0.2305]])
tensor([[ 0.7776,  0.1084, -0.8127, -1.3126],
        [ 1.1053,  0.3898,  0.1087, -0.4667]])
tensor([[ 0.6137,  0.1970, -0.2391, -0.9429],
        [ 1.8466,  1.6018,  1.4970,  0.2305],
        [ 0.7776,  0.1084, -0.8127, -1.3126],
        [ 1.1053,  0.3898,  0.1087, -0.4667]])
tensor([[ 0.6137,  0.1970, -0.2391, -0.9429,  0.7776,  0.1084, -0.8127,
         -1.3126],
        [ 1.8466,  1.6018,  1.4970,  0.2305,  1.1053,  0.3898,  0.1087,
         -0.4667]])

3.2 張量分塊操作

torch.chunk(tensor, chunks, dim=0)

在給定維度(軸)上將輸入張量進行分塊兒。

引數:

tensor (Tensor) – 待分塊的輸入張量

chunks (int) – 分塊的個數

dim (int) – 沿著此維度進行分塊

a = torch.randn(4, 6)
a_chunk = torch.chunk(a, 2, 0)
print('a_chunk:', a_chunk)
print('type:', type(a_chunk))  # 返回的是一個tuple
a_chunk: (tensor([[-0.9597, -0.6585, -1.1580,  0.2790, -0.5184,  1.8365],
        [ 0.5250,  1.1513, -0.8885,  0.1913,  1.2182, -0.0828]]), tensor([[ 2.3396, -0.6564,  0.2860, -1.0066, -0.1558,  0.4544],
        [-1.4732,  0.6251, -1.3311,  2.0909, -0.5014,  1.0714]]))
type: <class 'tuple'>
a_chunk = torch.chunk(a, 2, 1) # 在維度=1上進行分塊
print('a_chunk:', a_chunk)
a_chunk: (tensor([[-0.9597, -0.6585, -1.1580],
        [ 0.5250,  1.1513, -0.8885],
        [ 2.3396, -0.6564,  0.2860],
        [-1.4732,  0.6251, -1.3311]]), tensor([[ 0.2790, -0.5184,  1.8365],
        [ 0.1913,  1.2182, -0.0828],
        [-1.0066, -0.1558,  0.4544],
        [ 2.0909, -0.5014,  1.0714]]))

3.3 張量聚合操作

torch.gather(input, dim, index, out=None) → Tensor

其實是根據dim和index去取出input中的元素

引數:

input (Tensor) – 源張量

dim (int) – 索引的軸

index (LongTensor) – 聚合元素的下標

out (Tensor, optional) – 目標張量

a = torch.Tensor([[1, 2, 3],[4, 5, 6]])
print(a)
tensor([[ 1.,  2.,  3.],
        [ 4.,  5.,  6.]])
# 其實就是在維度1上取出下標為[[0, 1], [2, 0]]的a中的元素
a_gather = torch.gather(a, 1, torch.LongTensor([[0, 1], [2, 0]]))
print(a_gather)
tensor([[ 1.,  3.,  2.],
        [ 5.,  6.,  4.]])
# 換成0維度感受一下
a_gather = torch.gather(a, 0, torch.LongTensor([[1, 0, 1], [0, 1, 1]]))
print(a_gather)
tensor([[ 4.,  2.,  6.],
        [ 1.,  5.,  6.]])

3.4 根據索引切割張量

沿著指定維度對輸入進行切片,取index中指定的相應項(index為一個LongTensor),然後返回到一個新的張量, 返回的張量與原始張量_Tensor_有相同的維度(在指定軸上)。

注意: 返回的張量不與原始張量共享記憶體空間。

torch.index_select(input, dim, index, out=None) → Tensor

引數:

input (Tensor) – 輸入張量

dim (int) – 索引的軸

index (LongTensor) – 包含索引下標的一維張量

out (Tensor, optional) – 目標張量

a = torch.rand(4, 6)
print(a)
tensor([[ 0.6482,  0.9216,  0.7734,  0.5927,  0.9646,  0.5529],
        [ 0.9330,  0.5138,  0.4323,  0.5836,  0.2940,  0.8188],
        [ 0.8988,  0.1239,  0.6988,  0.0342,  0.3798,  0.8176],
        [ 0.4482,  0.5771,  0.9904,  0.6088,  0.9014,  0.6419]])
# 在維度1上切割
a_select = torch.index_select(a, 1, torch.LongTensor([0, 3]))
print(a_select)
tensor([[ 0.6482,  0.5927],
        [ 0.9330,  0.5836],
        [ 0.8988,  0.0342],
        [ 0.4482,  0.6088]])
# 在維度0上切割
a_select = torch.index_select(a, 0, torch.LongTensor([0,2]))
print(a_select)
tensor([[ 0.6482,  0.9216,  0.7734,  0.5927,  0.9646,  0.5529],
        [ 0.8988,  0.1239,  0.6988,  0.0342,  0.3798,  0.8176]])

3.5 根據掩碼選擇張量

根據掩碼張量mask中的二元值,取輸入張量中的指定項( mask為一個 ByteTensor),將取值返回到一個新的1D張量,

張量 mask須跟input張量有相同數量的元素數目,但形狀或維度不需要相同。 注意: 返回的張量不與原始張量共享記憶體空間。

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

引數:

input (Tensor) – 輸入張量

mask (ByteTensor) – 掩碼張量,包含了二元索引值

out (Tensor, optional) – 目標張量

a = torch.rand(2, 4)
print(a)
tensor([[ 0.6390,  0.5035,  0.6042,  0.8629],
        [ 0.3294,  0.6633,  0.3334,  0.5081]])
mask = torch.ByteTensor([[0, 0, 1, 0], [1, 1, 0, 1]])
a_mask_select = torch.masked_select(a, mask)
print(a_mask_select)  # 注意,返回的是一個一維的張量, 該張量裡的元素是a中mask裡1對應位置的元素
tensor([ 0.6042,  0.3294,  0.6633,  0.5081])

3.6 選擇非0張量

返回一個包含輸入input中非零元素索引的張量。輸出張量中的每行包含輸入中非零元素的索引。

如果輸入input有n維,則輸出的索引張量output的形狀為 z x n, 這裡 z 是輸入張量input中所有非零元素的個數。

torch.nonzero(input, out=None) → LongTensor

引數:

input (Tensor) – 源張量

out (LongTensor, optional) – 包含索引值的結果張量

a = torch.Tensor([[1, 2, 3, 0, 5], [6, 7, 0, 7, 9]])
print(a)
tensor([[ 1.,  2.,  3.,  0.,  5.],
        [ 6.,  7.,  0.,  7.,  9.]])
a_nonzero = torch.nonzero(a)
print(a_nonzero)  # 注意,輸出的是非零元素的索引哦
tensor([[ 0,  0],
        [ 0,  1],
        [ 0,  2],
        [ 0,  4],
        [ 1,  0],
        [ 1,  1],
        [ 1,  3],
        [ 1,  4]])

3.7 等分張量

將輸入張量分割成相等形狀的chunks(如果可分)。 如果沿指定維的張量形狀大小不能被split_size 整分, 則最後一個分塊會小於其它分塊。

torch.split(tensor, split_size, dim=0)

引數:

tensor (Tensor) – 待分割張量

split_size (int) – 單個分塊的形狀大小

dim (int) – 沿著此維進行分割

a = torch.randn(4, 7)
print(a)
tensor([[ 1.9670,  1.0551,  0.1469, -0.2239, -1.7594, -1.2708, -0.4926],
        [-0.8019, -0.4658,  0.4625,  1.3451,  0.3857, -0.8660, -1.1791],
        [ 1.4074, -0.8085, -1.2970, -0.7953,  0.2780,  0.9627, -1.0428],
        [ 1.2674, -1.3966, -0.7654,  1.2177,  0.9083, -0.1382, -0.3038]])
a_split = torch.split(a, 2, dim=1)
print(a_split)   # 注意當不能整分的時候,最後一個分塊是小於其他分塊的
(tensor([[ 1.9670,  1.0551],
        [-0.8019, -0.4658],
        [ 1.4074, -0.8085],
        [ 1.2674, -1.3966]]), tensor([[ 0.1469, -0.2239],
        [ 0.4625,  1.3451],
        [-1.2970, -0.7953],
        [-0.7654,  1.2177]]), tensor([[-1.7594, -1.2708],
        [ 0.3857, -0.8660],
        [ 0.2780,  0.9627],
        [ 0.9083, -0.1382]]), tensor([[-0.4926],
        [-1.1791],
        [-1.0428],
        [-0.3038]]))

torch_chunk與torch_split區別:
torch_chunk傳入的引數是要分多少塊,torch_split傳入的引數是每塊多少大。

3.8 壓縮張量

將輸入張量形狀中的1 去除並返回。 如果輸入是形如(A×1×B×1×C×1×D),那麼輸出形狀就為: (A×B×C×D)
當給定dim時,那麼擠壓操作只在給定維度上。例如,輸入形狀為: (A×1×B), squeeze(input, 0) 將會保持張量不變,只有用 squeeze(input, 1),形狀會變成 (A×B)。

注意: 返回張量與輸入張量共享記憶體,所以改變其中一個的內容會改變另一個。

torch.squeeze(input, dim=None, out=None)

引數:

input (Tensor) – 輸入張量

dim (int, optional) – 如果給定,則input只會在給定維度擠壓

out (Tensor, optional) – 輸出張量

建立一個4維的張量,其中有兩個維度的大小為1
a = torch.rand(2,1,3,1)
print(a)
tensor([[[[ 0.3762],
          [ 0.8454],
          [ 0.6275]]],


        [[[ 0.5402],
          [ 0.9575],
          [ 0.6968]]]])
# 把所有大小為1的維度給去掉了
a_squeeze = torch.squeeze(a)
print(a_squeeze)
print('size:', a_squeeze.size())  # 壓縮之後維度變成了2*3
tensor([[ 0.3762,  0.8454,  0.6275],
        [ 0.5402,  0.9575,  0.6968]])
size: torch.Size([2, 3])
# 也可以指定維度壓縮
a_squeeze = torch.squeeze(a, 1)
print(a_squeeze)
print('size:', a_squeeze.size()) # 於是只去掉了第1維度上的1
tensor([[[ 0.3762],
         [ 0.8454],
         [ 0.6275]],

        [[ 0.5402],
         [ 0.9575],
         [ 0.6968]]])
size: torch.Size([2, 3, 1])

3. 9 新維度連線張量

沿著一個新維度對輸入張量序列進行連線。 序列中所有的張量都應該為相同形狀。
注意和torch.cat的區別,torch.stack是在新的維度上進行拼接,也就是說拼接後維度數會+1

torch.stack(sequence, dim=0)

引數:

sqequence (Sequence) – 待連線的張量序列

dim (int) – 插入的維度。必須介於 0 與 待連線的張量序列數之間。

a = torch.randn(2, 2)
b = torch.ones(2, 2)
c = torch.zeros(2, 2)

stack = torch.stack((a, b, c), 0)
print(stack)
tensor([[[ 1.1905,  0.0067],
         [ 0.1899, -0.0446]],

        [[ 1.0000,  1.0000],
         [ 1.0000,  1.0000]],

        [[ 0.0000,  0.0000],
         [ 0.0000,  0.0000]]])
# 指定其他維度
stack = torch.stack((a, b, c), 1)
print(stack)
tensor([[[ 1.1905,  0.0067],
         [ 1.0000,  1.0000],
         [ 0.0000,  0.0000]],

        [[ 0.1899, -0.0446],
         [ 1.0000,  1.0000],
         [ 0.0000,  0.0000]]])
# 指定其他維度
stack = torch.stack((a, b, c), 2)
print(stack)
tensor([[[ 1.1905,  1.0000,  0.0000],
         [ 0.0067,  1.0000,  0.0000]],

        [[ 0.1899,  1.0000,  0.0000],
         [-0.0446,  1.0000,  0.0000]]])

3.10 轉置2維張量

輸入一個矩陣(2維張量),並轉置0, 1維。 可以被視為函式transpose(input, 0, 1)的簡寫函式。

torch.t(input, out=None) → Tensor

引數:

input (Tensor) – 輸入張量

out (Tensor, optional) – 結果張量

a = torch.randn(2, 3)
print(a)
tensor([[-0.0530,  0.3038,  0.9280],
        [ 0.0992,  0.6662, -0.4005]])
a_t = torch.t(a)
print(a_t)
tensor([[-0.0530,  0.0992],
        [ 0.3038,  0.6662],
        [ 0.9280, -0.4005]])

3.11 通用的轉置

返回輸入矩陣input的轉置。交換維度dim0和dim1。 輸出張量與輸入張量共享記憶體,所以改變其中一個會導致另外一個也被修改。

torch.transpose(input, dim0, dim1, out=None) → Tensor

引數:

input (Tensor) – 輸入張量

dim0 (int) – 轉置的第一維

dim1 (int) – 轉置的第二維

a = torch.randn(2, 3, 2)
print(a)
tensor([[[ 0.8596,  0.6972],
         [ 0.8587, -0.4417],
         [-2.0626, -1.9395]],

        [[-0.5063, -0.9338],
         [-0.0316, -1.2842],
         [ 0.7219, -1.5864]]])
# 指定要交換的兩個維度
a_trans = torch.transpose(a, 1, 2)
print(a_trans)
tensor([[[ 0.8596,  0.8587, -2.0626],
         [ 0.6972, -0.4417, -1.9395]],

        [[-0.5063, -0.0316,  0.7219],
         [-0.9338, -1.2842, -1.5864]]])

3.12 移除指定維度

移除指定維後,返回一個元組,包含了沿著指定維切片後的各個切片

torch.unbind(tensor, dim=0)

引數:

tensor (Tensor) – 輸入張量

dim (int) – 刪除的維度

a = torch.randn(2, 3, 2)
print(a)
tensor([[[-0.6012, -0.4857],
         [-0.5015, -0.6248],
         [-0.7119, -0.9076]],

        [[ 1.4232,  0.0932],
         [-0.6209,  1.1310],
         [-0.7734,  0.0066]]])
a_unbind = torch.unbind(a, 0)
print(a_unbind)  # 移除維度0, 拆分成了兩個3*2的矩陣
(tensor([[-0.6012, -0.4857],
        [-0.5015, -0.6248],
        [-0.7119, -0.9076]]), tensor([[ 1.4232,  0.0932],
        [-0.6209,  1.1310],
        [-0.7734,  0.0066]]))

3.13 擴張指定維度

返回一個新的張量,對輸入的制定位置插入維度 1

注意: 返回張量與輸入張量共享記憶體,所以改變其中一個的內容會改變另一個。

如果dim為負,則將會被轉化dim+input.dim()+1

torch.unsqueeze(input, dim, out=None)

引數:

tensor (Tensor) – 輸入張量

dim (int) – 插入維度的索引

out (Tensor, optional) – 結果張量

# 先建立一個只有一個維度的tensor
a = torch.rand(4)
print('a:', a)
print('size:', a.size())
a: tensor([ 0.2107,  0.0282,  0.5163,  0.3185])
size: torch.Size([4])
# 在維度1上新增一個維度
a_1 = torch.unsqueeze(a, 1)
print('a_1', a_1)
print('size:', a_1.size())  # 維度變成了2維:4*1
a_1 tensor([[ 0.2107],
        [ 0.0282],
        [ 0.5163],
        [ 0.3185]])
size: torch.Size([4, 1])

4 隨機抽樣

4.1 人為設定種子

設定生成隨機數的種子,並返回一個 torch._C.Generator 物件.

引數: seed (int or long) – 種子.

x = torch.manual_seed(10)
print(x)
<torch._C.Generator object at 0x106619e90>

4.2 獲得種子值

x = torch.initial_seed()
print(x)
10

4.3 獲得與設定隨機生成器狀態

# 獲得當前狀態
print(torch.get_rng_state())
tensor([  10,    0,    0,  ...,    0,    0,    0], dtype=torch.uint8)
# 設定狀態
torch.set_rng_state(torch.get_rng_state())

4.4 獲得預設的隨機生成器

print(torch.default_generator)
<torch._C.Generator object at 0x106619e90>

4.5 從不同分佈中獲取隨機數

4.5.1 伯努利分佈

從伯努利分佈中抽取二元隨機數(0 或者 1)。

輸入張量須包含用於抽取上述二元隨機值的概率。 因此,輸入中的所有值都必須在[0,1]區間,即 0<=inputi<=1
輸出張量的第i個元素值, 將會以輸入張量的第i個概率值等於1。

返回值將會是與輸入相同大小的張量,每個值為0或者1 引數:

input (Tensor) – 輸入為伯努利分佈的概率值

out (Tensor, optional) – 輸出張量(可選)

# 建立一個0-1分佈的矩陣,表示概率
a = torch.Tensor(3, 3).uniform_(0,1)
print(a)
tensor([[ 0.4581,  0.4829,  0.3125],
        [ 0.6150,  0.2139,  0.4118],
        [ 0.6938,  0.9693,  0.6178]])
# 轉換成0/1伯努利分佈,即在伯努利分佈中抽取隨機數,1表示抽取出的數
b = torch.bernoulli(a)
print(b)
tensor([[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 1.,  1.,  1.]])

4.5.2 多項式分佈

返回一個張量,每行包含從input相應行中定義的多項分佈中抽取的num_samples個樣本。

[注意]:輸入input每行的值不需要總和為1 (這裡我們用來做權重),但是必須非負且總和不能為0。

當抽取樣本時,依次從左到右排列(第一個樣本對應第一列)。

如果輸入input是一個向量,輸出out也是一個相同長度num_samples的向量。如果輸入input是有 m行的矩陣,輸出out是形如m×n的矩陣。

如果引數replacement 為 True, 則樣本抽取可以重複。否則,一個樣本在每行不能被重複抽取。

引數num_samples必須小於input長度(即,input的列數,如果是input是一個矩陣)。

引數:

input (Tensor) – 包含概率值的張量

num_samples (int) – 抽取的樣本數

replacement (bool, optional) – 布林值,決定是否能重複抽取

out (Tensor, optional) – 結果張量

weights = torch.Tensor([0, 10, 3, 0])

# 無放回,num_samples 必須小於等於weights的長度
b = torch.multinomial(weights, 3