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