2. 张量操作
张量操作¶
In [1]:
Copied!
import torch
import numpy as np
# torch.tensor: 从 Python 列表或标量直接创建张量,数据会被深拷贝,可指定 dtype 和 device
x = torch.tensor([[1.0, 2.0], [3.0, 4.0]], dtype=torch.float32)
print(x)
# tensor([[1., 2.],
# [3., 4.]])
import torch
import numpy as np
# torch.tensor: 从 Python 列表或标量直接创建张量,数据会被深拷贝,可指定 dtype 和 device
x = torch.tensor([[1.0, 2.0], [3.0, 4.0]], dtype=torch.float32)
print(x)
# tensor([[1., 2.],
# [3., 4.]])
tensor([[1., 2.],
[3., 4.]])
In [ ]:
Copied!
# torch.from_numpy: 从 NumPy 数组创建张量,与原数组共享内存(修改一方会影响另一方)
arr = np.array([1.0, 2.0, 3.0])
t1 = torch.from_numpy(arr)
print(t1) # tensor([1., 2., 3.], dtype=torch.float64)
# torch.as_tensor: 与 from_numpy 类似,但更通用,支持任意可转换对象;若输入已是张量且 dtype/device 匹配则不拷贝
t2 = torch.as_tensor(arr)
print(t2) # tensor([1., 2., 3.], dtype=torch.float64)
# torch.from_numpy: 从 NumPy 数组创建张量,与原数组共享内存(修改一方会影响另一方)
arr = np.array([1.0, 2.0, 3.0])
t1 = torch.from_numpy(arr)
print(t1) # tensor([1., 2., 3.], dtype=torch.float64)
# torch.as_tensor: 与 from_numpy 类似,但更通用,支持任意可转换对象;若输入已是张量且 dtype/device 匹配则不拷贝
t2 = torch.as_tensor(arr)
print(t2) # tensor([1., 2., 3.], dtype=torch.float64)
tensor([1., 2., 3.], dtype=torch.float64) tensor([1., 2., 3.], dtype=torch.float64)
In [3]:
Copied!
# torch.zeros: 创建指定形状的全零张量
print(torch.zeros(2, 3))
# tensor([[0., 0., 0.],
# [0., 0., 0.]])
# torch.ones: 创建指定形状的全一张量
print(torch.ones(2, 3))
# tensor([[1., 1., 1.],
# [1., 1., 1.]])
# torch.eye: 创建二维单位矩阵(对角线为1,其余为0)
print(torch.eye(3))
# tensor([[1., 0., 0.],
# [0., 1., 0.],
# [0., 0., 1.]])
# torch.zeros: 创建指定形状的全零张量
print(torch.zeros(2, 3))
# tensor([[0., 0., 0.],
# [0., 0., 0.]])
# torch.ones: 创建指定形状的全一张量
print(torch.ones(2, 3))
# tensor([[1., 1., 1.],
# [1., 1., 1.]])
# torch.eye: 创建二维单位矩阵(对角线为1,其余为0)
print(torch.eye(3))
# tensor([[1., 0., 0.],
# [0., 1., 0.],
# [0., 0., 1.]])
tensor([[0., 0., 0.],
[0., 0., 0.]])
tensor([[1., 1., 1.],
[1., 1., 1.]])
tensor([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
In [4]:
Copied!
# torch.zeros_like: 创建与给定张量形状、dtype、device 完全相同的全零张量
ref = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
print(torch.zeros_like(ref))
# tensor([[0., 0.],
# [0., 0.]])
# torch.ones_like: 创建与给定张量形状、dtype、device 完全相同的全一张量
print(torch.ones_like(ref))
# tensor([[1., 1.],
# [1., 1.]])
# torch.zeros_like: 创建与给定张量形状、dtype、device 完全相同的全零张量
ref = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
print(torch.zeros_like(ref))
# tensor([[0., 0.],
# [0., 0.]])
# torch.ones_like: 创建与给定张量形状、dtype、device 完全相同的全一张量
print(torch.ones_like(ref))
# tensor([[1., 1.],
# [1., 1.]])
tensor([[0., 0.],
[0., 0.]])
tensor([[1., 1.],
[1., 1.]])
In [5]:
Copied!
# torch.empty: 创建一个未初始化的张量(值为内存残留数据),仅分配内存,速度快,需后续手动赋值
print(torch.empty(2, 3))
# tensor([[...]]) 值不确定
# torch.clone: 深拷贝一个张量,保留梯度计算图(与 detach().copy_() 不同),常用于保存中间状态
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = x.clone()
print(y) # tensor([1., 2., 3.], grad_fn=<CloneBackward0>)
# torch.empty: 创建一个未初始化的张量(值为内存残留数据),仅分配内存,速度快,需后续手动赋值
print(torch.empty(2, 3))
# tensor([[...]]) 值不确定
# torch.clone: 深拷贝一个张量,保留梯度计算图(与 detach().copy_() 不同),常用于保存中间状态
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = x.clone()
print(y) # tensor([1., 2., 3.], grad_fn=)
tensor([[8.0963e+08, 1.1084e-42, 0.0000e+00],
[0.0000e+00, 0.0000e+00, 0.0000e+00]])
tensor([1., 2., 3.], grad_fn=<CloneBackward0>)
In [6]:
Copied!
# torch.rand: 创建填充了 [0, 1) 均匀分布随机数的张量
print(torch.rand(2, 3))
# torch.randn: 创建填充了标准正态分布(均值0,标准差1)随机数的张量
print(torch.randn(2, 3))
# torch.normal: 创建填充了指定均值和标准差的正态分布随机数的张量
print(torch.normal(mean=5.0, std=2.0, size=(2, 3)))
# torch.rand: 创建填充了 [0, 1) 均匀分布随机数的张量
print(torch.rand(2, 3))
# torch.randn: 创建填充了标准正态分布(均值0,标准差1)随机数的张量
print(torch.randn(2, 3))
# torch.normal: 创建填充了指定均值和标准差的正态分布随机数的张量
print(torch.normal(mean=5.0, std=2.0, size=(2, 3)))
tensor([[0.2371, 0.4549, 0.5133],
[0.2349, 0.9595, 0.6308]])
tensor([[-0.2359, -1.0181, -1.8251],
[ 1.8605, -0.3005, 1.9893]])
tensor([[2.6202, 5.5717, 5.1439],
[8.5762, 7.3996, 7.0859]])
In [7]:
Copied!
# torch.randint: 生成指定形状的整数张量,元素从区间 [low, high) 内均匀随机采样
print(torch.randint(low=0, high=10, size=(2, 4)))
# tensor([[3, 7, 1, 9],
# [0, 5, 4, 2]])
# torch.randint: 生成指定形状的整数张量,元素从区间 [low, high) 内均匀随机采样
print(torch.randint(low=0, high=10, size=(2, 4)))
# tensor([[3, 7, 1, 9],
# [0, 5, 4, 2]])
tensor([[7, 9, 3, 5],
[0, 7, 3, 5]])
In [8]:
Copied!
# torch.full: 生成指定形状的张量,所有元素初始化为同一个指定填充值
print(torch.full((2, 4), fill_value=3.14))
# tensor([[3.1400, 3.1400, 3.1400, 3.1400],
# [3.1400, 3.1400, 3.1400, 3.1400]])
# torch.full: 生成指定形状的张量,所有元素初始化为同一个指定填充值
print(torch.full((2, 4), fill_value=3.14))
# tensor([[3.1400, 3.1400, 3.1400, 3.1400],
# [3.1400, 3.1400, 3.1400, 3.1400]])
tensor([[3.1400, 3.1400, 3.1400, 3.1400],
[3.1400, 3.1400, 3.1400, 3.1400]])
In [9]:
Copied!
# torch.arange: 创建从 start 到 end(不含)按 step 步长递增的一维整数或浮点张量
print(torch.arange(start=0, end=10, step=2))
# tensor([0, 2, 4, 6, 8])
# torch.arange: 创建从 start 到 end(不含)按 step 步长递增的一维整数或浮点张量
print(torch.arange(start=0, end=10, step=2))
# tensor([0, 2, 4, 6, 8])
tensor([0, 2, 4, 6, 8])
In [10]:
Copied!
# torch.linspace: 在 [start, end] 区间内均匀分布生成指定数量的点,构成一维张量
print(torch.linspace(0, 1, steps=5))
# tensor([0.0000, 0.2500, 0.5000, 0.7500, 1.0000])
# torch.logspace: 在 [10^start, 10^end] 区间内对数尺度均匀分布生成指定数量的点
print(torch.logspace(start=0, end=3, steps=4))
# tensor([ 1., 10., 100., 1000.])
# torch.linspace: 在 [start, end] 区间内均匀分布生成指定数量的点,构成一维张量
print(torch.linspace(0, 1, steps=5))
# tensor([0.0000, 0.2500, 0.5000, 0.7500, 1.0000])
# torch.logspace: 在 [10^start, 10^end] 区间内对数尺度均匀分布生成指定数量的点
print(torch.logspace(start=0, end=3, steps=4))
# tensor([ 1., 10., 100., 1000.])
tensor([0.0000, 0.2500, 0.5000, 0.7500, 1.0000]) tensor([ 1., 10., 100., 1000.])
In [8]:
Copied!
# torch.randperm: 生成 0 到 n-1 的随机排列整数张量,常用于数据集随机打乱(shuffle)
print(torch.randperm(8))
# tensor([5, 2, 7, 0, 3, 6, 1, 4]) 每次结果不同
# torch.randperm: 生成 0 到 n-1 的随机排列整数张量,常用于数据集随机打乱(shuffle)
print(torch.randperm(8))
# tensor([5, 2, 7, 0, 3, 6, 1, 4]) 每次结果不同
tensor([1, 5, 6, 2, 3, 4, 0, 7])
In [12]:
Copied!
# torch.cat: 将多个张量在指定的已有维度上拼接(拼接后该维度大小为各张量之和,其余维度不变)
a = torch.zeros(2, 3)
b = torch.ones(2, 3)
print(torch.cat([a, b], dim=0).shape) # torch.Size([4, 3]) 沿行拼接
print(torch.cat([a, b], dim=1).shape) # torch.Size([2, 6]) 沿列拼接
# torch.cat: 将多个张量在指定的已有维度上拼接(拼接后该维度大小为各张量之和,其余维度不变)
a = torch.zeros(2, 3)
b = torch.ones(2, 3)
print(torch.cat([a, b], dim=0).shape) # torch.Size([4, 3]) 沿行拼接
print(torch.cat([a, b], dim=1).shape) # torch.Size([2, 6]) 沿列拼接
torch.Size([4, 3]) torch.Size([2, 6])
In [ ]:
Copied!
# torch.stack: 在新增维度上堆叠一组形状相同的张量,结果比输入多一个维度
a = torch.tensor([1.0, 2.0, 3.0])
b = torch.tensor([4.0, 5.0, 6.0])
print(torch.stack([a, b], dim=0)) # shape: (2, 3),dim=0 处新增维度
# tensor([[1., 2., 3.],
# [4., 5., 6.]])
print(torch.stack([a, b], dim=1)) # shape: (3, 2),dim=1 处新增维度, 从(3,)变为(3,2)
# torch.stack: 在新增维度上堆叠一组形状相同的张量,结果比输入多一个维度
a = torch.tensor([1.0, 2.0, 3.0])
b = torch.tensor([4.0, 5.0, 6.0])
print(torch.stack([a, b], dim=0)) # shape: (2, 3),dim=0 处新增维度
# tensor([[1., 2., 3.],
# [4., 5., 6.]])
print(torch.stack([a, b], dim=1)) # shape: (3, 2),dim=1 处新增维度, 从(3,)变为(3,2)
tensor([[1., 2., 3.],
[4., 5., 6.]])
tensor([[1., 4.],
[2., 5.],
[3., 6.]])
torch.stack(expert_outputs, dim=1)
前提:输入是什么
expert_outputs = [expert(x) for expert in self.experts]
# 每个 expert(x) 的形状:(B, expert_output_dim) = (10, 72)
# expert_outputs 是一个 list,长度 = num_experts = 3
torch.stack 的作用
stack= 在新维度上拼接,要求所有张量形状完全相同。
# 3 个 (10, 72) → 沿 dim=1 新建维度 → (10, 3, 72)
expert_outputs_stacked = torch.stack(expert_outputs, dim=1)
直观理解:
expert_outputs[0]: (10, 72) ─┐
expert_outputs[1]: (10, 72) ─┼─ stack(dim=1) ──→ (10, 3, 72)
expert_outputs[2]: (10, 72) ─┘
↑
新插入的维度,
代表 num_experts
与 torch.cat 的区别
| 操作 | 行为 | 结果形状(3个(10,72)) |
|---|---|---|
torch.stack(expert_outputs, dim=1) |
新建维度再拼接 | (10, 3, 72) |
torch.cat(expert_outputs, dim=1) |
在已有维度上拼接 | (10, 216) |
In [14]:
Copied!
# tensor.view: 在不拷贝数据的情况下重塑张量形状,要求张量在内存中连续存储
x = torch.arange(12.0)
print(x.view(3, 4)) # shape: (3, 4)
print(x.view(3, -1)) # -1 表示自动推断该维度大小,shape: (3, 4)
# tensor.reshape: 功能与 view 相同,但允许非连续张量(内部会自动拷贝),更安全
y = x.reshape(2, 6)
print(y.shape) # torch.Size([2, 6])
# tensor.view: 在不拷贝数据的情况下重塑张量形状,要求张量在内存中连续存储
x = torch.arange(12.0)
print(x.view(3, 4)) # shape: (3, 4)
print(x.view(3, -1)) # -1 表示自动推断该维度大小,shape: (3, 4)
# tensor.reshape: 功能与 view 相同,但允许非连续张量(内部会自动拷贝),更安全
y = x.reshape(2, 6)
print(y.shape) # torch.Size([2, 6])
tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])
tensor([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]])
torch.Size([2, 6])
In [15]:
Copied!
# tensor.squeeze: 移除张量中所有大小为 1 的维度;可指定 dim 只移除特定维度
x = torch.zeros(1, 3, 1, 4)
print(x.squeeze().shape) # torch.Size([3, 4])
print(x.squeeze(dim=0).shape) # torch.Size([3, 1, 4]) 只去除 dim=0
# tensor.unsqueeze: 在指定位置插入一个大小为 1 的新维度(常用于匹配批量维度)
y = torch.tensor([1.0, 2.0, 3.0]) # shape: (3,)
print(y.unsqueeze(0).shape) # torch.Size([1, 3]) 在最前插入
print(y.unsqueeze(1).shape) # torch.Size([3, 1]) 在最后插入
# tensor.squeeze: 移除张量中所有大小为 1 的维度;可指定 dim 只移除特定维度
x = torch.zeros(1, 3, 1, 4)
print(x.squeeze().shape) # torch.Size([3, 4])
print(x.squeeze(dim=0).shape) # torch.Size([3, 1, 4]) 只去除 dim=0
# tensor.unsqueeze: 在指定位置插入一个大小为 1 的新维度(常用于匹配批量维度)
y = torch.tensor([1.0, 2.0, 3.0]) # shape: (3,)
print(y.unsqueeze(0).shape) # torch.Size([1, 3]) 在最前插入
print(y.unsqueeze(1).shape) # torch.Size([3, 1]) 在最后插入
torch.Size([3, 4]) torch.Size([3, 1, 4]) torch.Size([1, 3]) torch.Size([3, 1])
In [11]:
Copied!
# tensor.permute: 按指定顺序重新排列张量的所有维度(是 transpose 的推广,可一次交换多个维度)
x = torch.randn(2, 3, 4) # (batch, height, width)
print(x)
print(x.permute(0, 2, 1))
print(x.permute(0, 2, 1).shape) # torch.Size([2, 4, 3]) 交换 dim1 和 dim2
print(x.permute(2, 0, 1))
print(x.permute(2, 0, 1).shape) # torch.Size([4, 2, 3]) 将 dim2 移至最前
# tensor.permute: 按指定顺序重新排列张量的所有维度(是 transpose 的推广,可一次交换多个维度)
x = torch.randn(2, 3, 4) # (batch, height, width)
print(x)
print(x.permute(0, 2, 1))
print(x.permute(0, 2, 1).shape) # torch.Size([2, 4, 3]) 交换 dim1 和 dim2
print(x.permute(2, 0, 1))
print(x.permute(2, 0, 1).shape) # torch.Size([4, 2, 3]) 将 dim2 移至最前
tensor([[[-0.6740, 0.4821, -1.1511, 1.0163],
[ 0.2780, 0.0963, -0.7990, 0.1237],
[-0.5416, -1.1541, 1.6195, -0.9684]],
[[-1.2399, 0.1513, -0.8133, -0.7371],
[-2.3666, 2.0146, 0.2083, -0.6683],
[-0.6912, -1.0779, 1.4455, -0.2064]]])
tensor([[[-0.6740, 0.2780, -0.5416],
[ 0.4821, 0.0963, -1.1541],
[-1.1511, -0.7990, 1.6195],
[ 1.0163, 0.1237, -0.9684]],
[[-1.2399, -2.3666, -0.6912],
[ 0.1513, 2.0146, -1.0779],
[-0.8133, 0.2083, 1.4455],
[-0.7371, -0.6683, -0.2064]]])
torch.Size([2, 4, 3])
tensor([[[-0.6740, 0.2780, -0.5416],
[-1.2399, -2.3666, -0.6912]],
[[ 0.4821, 0.0963, -1.1541],
[ 0.1513, 2.0146, -1.0779]],
[[-1.1511, -0.7990, 1.6195],
[-0.8133, 0.2083, 1.4455]],
[[ 1.0163, 0.1237, -0.9684],
[-0.7371, -0.6683, -0.2064]]])
torch.Size([4, 2, 3])
In [13]:
Copied!
# tensor.expand_as: 将张量沿大小为 1 的维度扩展到与目标张量相同的形状(不拷贝数据,共享内存)
a = torch.tensor([[1.0], [2.0], [3.0]]) # shape: (3, 1)
ref = torch.zeros(3, 4)
print(a.expand_as(ref))
print(a.expand_as(ref).shape) # torch.Size([3, 4])
# tensor.repeat: 沿每个维度将张量重复指定次数(真实拷贝数据,产生新张量),第 k 个参数 → 第 k 个维度的重复倍数。
x = torch.tensor([[1, 2],[3, 4]])
print(x.repeat(1, 3)) # tensor([1, 2, 3, 1, 2, 3, 1, 2, 3])
print(x.repeat(2, 1)) # torch.Size([2, 3])
# torch.tile: 与 tensor.repeat 等价的函数式接口,NumPy 风格,沿各维度平铺张量
print(torch.tile(x, dims=(2, 3))) # torch.Size([2, 6])
# tensor.expand_as: 将张量沿大小为 1 的维度扩展到与目标张量相同的形状(不拷贝数据,共享内存)
a = torch.tensor([[1.0], [2.0], [3.0]]) # shape: (3, 1)
ref = torch.zeros(3, 4)
print(a.expand_as(ref))
print(a.expand_as(ref).shape) # torch.Size([3, 4])
# tensor.repeat: 沿每个维度将张量重复指定次数(真实拷贝数据,产生新张量),第 k 个参数 → 第 k 个维度的重复倍数。
x = torch.tensor([[1, 2],[3, 4]])
print(x.repeat(1, 3)) # tensor([1, 2, 3, 1, 2, 3, 1, 2, 3])
print(x.repeat(2, 1)) # torch.Size([2, 3])
# torch.tile: 与 tensor.repeat 等价的函数式接口,NumPy 风格,沿各维度平铺张量
print(torch.tile(x, dims=(2, 3))) # torch.Size([2, 6])
tensor([[1., 1., 1., 1.],
[2., 2., 2., 2.],
[3., 3., 3., 3.]])
torch.Size([3, 4])
tensor([[1, 2, 1, 2, 1, 2],
[3, 4, 3, 4, 3, 4]])
tensor([[1, 2],
[3, 4],
[1, 2],
[3, 4]])
tensor([[1, 2, 1, 2, 1, 2],
[3, 4, 3, 4, 3, 4],
[1, 2, 1, 2, 1, 2],
[3, 4, 3, 4, 3, 4]])
In [15]:
Copied!
# torch.where: 条件选择操作,逐元素地从 x 或 y 中选取值:condition 为 True 取 x,否则取 y
x = torch.tensor([1.0, -2.0, 3.0, -4.0])
y = torch.zeros_like(x)
print(torch.where(x > 0, x, y))
# tensor([1., 0., 3., 0.]) —— 相当于 ReLU 操作 = max(x, 0)
# torch.where: 条件选择操作,逐元素地从 x 或 y 中选取值:condition 为 True 取 x,否则取 y
x = torch.tensor([1.0, -2.0, 3.0, -4.0])
y = torch.zeros_like(x)
print(torch.where(x > 0, x, y))
# tensor([1., 0., 3., 0.]) —— 相当于 ReLU 操作 = max(x, 0)
tensor([1., 0., 3., 0.])
In [20]:
Copied!
# torch.any: 测试张量中是否至少有一个元素为非零(True),可指定 dim 沿某维度规约
x = torch.tensor([0, 0, 1, 0])
print(torch.any(x.bool())) # tensor(True)
print(torch.any(x.bool(), dim=0)) # tensor(True)
# torch.all: 测试张量中所有元素是否均为非零(True),可指定 dim 沿某维度规约
print(torch.all(x.bool())) # tensor(False) 存在0元素
y = torch.tensor([1, 2, 3])
print(torch.all(y.bool())) # tensor(True)
# torch.any: 测试张量中是否至少有一个元素为非零(True),可指定 dim 沿某维度规约
x = torch.tensor([0, 0, 1, 0])
print(torch.any(x.bool())) # tensor(True)
print(torch.any(x.bool(), dim=0)) # tensor(True)
# torch.all: 测试张量中所有元素是否均为非零(True),可指定 dim 沿某维度规约
print(torch.all(x.bool())) # tensor(False) 存在0元素
y = torch.tensor([1, 2, 3])
print(torch.all(y.bool())) # tensor(True)
tensor(True) tensor(True) tensor(False) tensor(True)
In [20]:
Copied!
# torch.nonzero: 返回输入张量中所有非零元素的索引,结果形状为 (N, ndim)(推荐用 as_tuple=True)
x = torch.tensor([[0, 1, 0],
[2, 0, 3]])
print(torch.nonzero(x))
# tensor([[0, 1], <- 第0行第1列
# [1, 0], <- 第1行第0列
# [1, 2]]) <- 第1行第2列
# 等价写法(返回各维度索引的元组)
rows, cols = torch.nonzero(x, as_tuple=True)
print(rows, cols) # tensor([0, 1, 1]) tensor([1, 0, 2])
# torch.nonzero: 返回输入张量中所有非零元素的索引,结果形状为 (N, ndim)(推荐用 as_tuple=True)
x = torch.tensor([[0, 1, 0],
[2, 0, 3]])
print(torch.nonzero(x))
# tensor([[0, 1], <- 第0行第1列
# [1, 0], <- 第1行第0列
# [1, 2]]) <- 第1行第2列
# 等价写法(返回各维度索引的元组)
rows, cols = torch.nonzero(x, as_tuple=True)
print(rows, cols) # tensor([0, 1, 1]) tensor([1, 0, 2])
tensor([[0, 1],
[1, 0],
[1, 2]])
tensor([0, 1, 1]) tensor([1, 0, 2])
In [41]:
Copied!
# torch.bernoulli: 从伯努利分布中抽取样本,输入张量中每个元素作为该位置取 1 的概率
p = torch.tensor([0.2, 0.5, 0.8, 0.9])
print(torch.bernoulli(p)) # tensor([0., 1., 1., 1.]) 随机结果
# torch.multinomial: 从多项分布中按权重(不要求归一化)抽取指定数量的样本索引,可选有放回/无放回,
weights = torch.tensor([1.0, 2.0, 3.0, 4.0])
print(torch.multinomial(weights, num_samples=3, replacement=False))
# 高权重索引被选中概率更高,如 tensor([3, 2, 1]),根据权重随机选索引,输出的为索引
# torch.normal: 从指定均值和标准差的正态分布中抽取样本(均值和标准差可以是张量,逐元素独立采样)
mean = torch.tensor([0.0, 5.0, 10.0])
std = torch.tensor([1.0, 0, 3.0])
print(torch.normal(mean, std))
# torch.poisson: 从泊松分布中抽取样本,输入张量的每个元素作为对应位置的 lambda(期望值)
lam = torch.tensor([1.0, 5.0, 10.0])
print(torch.poisson(lam)) # tensor([ 2., 4., 11.]) 随机结果
# torch.bernoulli: 从伯努利分布中抽取样本,输入张量中每个元素作为该位置取 1 的概率
p = torch.tensor([0.2, 0.5, 0.8, 0.9])
print(torch.bernoulli(p)) # tensor([0., 1., 1., 1.]) 随机结果
# torch.multinomial: 从多项分布中按权重(不要求归一化)抽取指定数量的样本索引,可选有放回/无放回,
weights = torch.tensor([1.0, 2.0, 3.0, 4.0])
print(torch.multinomial(weights, num_samples=3, replacement=False))
# 高权重索引被选中概率更高,如 tensor([3, 2, 1]),根据权重随机选索引,输出的为索引
# torch.normal: 从指定均值和标准差的正态分布中抽取样本(均值和标准差可以是张量,逐元素独立采样)
mean = torch.tensor([0.0, 5.0, 10.0])
std = torch.tensor([1.0, 0, 3.0])
print(torch.normal(mean, std))
# torch.poisson: 从泊松分布中抽取样本,输入张量的每个元素作为对应位置的 lambda(期望值)
lam = torch.tensor([1.0, 5.0, 10.0])
print(torch.poisson(lam)) # tensor([ 2., 4., 11.]) 随机结果
tensor([0., 1., 0., 1.]) tensor([0, 2, 1]) tensor([-0.4914, 5.0000, 7.4823]) tensor([ 3., 2., 15.])