区别:概率分布(最根本)
| 特性 | torch.rand() |
torch.randn() |
|---|---|---|
| 分布类型 | 均匀分布(Uniform Distribution) | 标准正态分布(Standard Normal Distribution) |
| 数学定义 | 所有值在 [0, 1) 区间内等概率出现 |
均值(μ)= 0,方差(σ²)= 1,呈钟形曲线分布 |
| 数值范围 | 严格落在 [0, 1)(包含0,不包含1) |
理论上 (-∞, +∞),99.7% 的值落在 [-3, 3] |
| 均值/方差 | 均值≈0.5,方差≈1/12≈0.083 | 均值≈0,方差≈1 |
代码验证分布特性
import torch
# 生成大量样本,验证统计特征(样本数越多越接近理论值)
sample_size = 100000
rand_uniform = torch.rand(sample_size)
rand_normal = torch.randn(sample_size)
# 输出核心统计值
print("=== torch.rand() 均匀分布 ===")
print(f"数值范围:[{rand_uniform.min():.4f}, {rand_uniform.max():.4f}]")
print(f"均值:{rand_uniform.mean():.4f}(理论值0.5)")
print(f"方差:{rand_uniform.var():.4f}(理论值≈0.0833)")
print("\n=== torch.randn() 标准正态分布 ===")
print(f"数值范围:[{rand_normal.min():.4f}, {rand_normal.max():.4f}]")
print(f"均值:{rand_normal.mean():.4f}(理论值0)")
print(f"方差:{rand_normal.var():.4f}(理论值1)")
典型输出:
=== torch.rand() 均匀分布 ===
数值范围:[0.0000, 1.0000]
均值:0.5002(理论值0.5)
方差:0.0833(理论值≈0.0833)
=== torch.randn() 标准正态分布 ===
数值范围:[-4.5678, 4.8901]
均值:0.0012(理论值0)
方差:0.9989(理论值1)
用法与参数区别
两者的函数参数完全一致(*size, dtype=None, device=None, requires_grad=False),用法也完全相同,仅数值分布不同:
# 生成2×3张量,参数用法一致,仅数值分布不同
a = torch.rand(2, 3) # [0,1) 均匀分布
b = torch.randn(2, 3) # 标准正态分布
print("torch.rand() 结果:\n", a)
print("torch.randn() 结果:\n", b)
输出示例:
torch.rand() 结果:
tensor([[0.1234, 0.5678, 0.9012],
[0.3456, 0.7890, 0.2345]])
torch.randn() 结果:
tensor([[-0.2345, 1.5678, -0.8901],
[ 0.4567, -0.7890, 0.1234]])
适用场景(核心区别)
| 场景 | 推荐函数 | 原因 |
|---|---|---|
| 模型权重初始化 | torch.randn() |
正态分布更符合深度学习权重初始化的需求(如线性层/卷积层,避免梯度消失/爆炸) |
| 生成随机掩码/采样 | torch.rand() |
均匀分布的0~1值适合做概率判断(如 rand()>0.5 生成50%概率的掩码) |
| 数据增强(添加噪声) | torch.randn() |
高斯噪声更贴近真实场景,且可通过缩放控制噪声幅度 |
| 简单随机数据生成 | torch.rand() |
0~1的范围直观,无需额外调整即可用于比例/概率类场景 |
| 自定义区间随机数 | torch.rand() |
从 [0,1) 扩展到 [a,b) 更简单(a + (b-a)*rand()) |
场景示例1:权重初始化(randn 首选)
import torch.nn as nn
# 线性层权重初始化:randn 缩放后更合理
weight = nn.Parameter(torch.randn(3, 5) * 0.01) # 缩放避免数值过大
print("权重均值:", weight.mean().item()) # ≈0,适合反向传播
场景示例2:随机掩码(rand 首选)
# 生成50%概率的0/1掩码
batch_size, seq_len = 4, 10
mask = (torch.rand(batch_size, seq_len) > 0.5).float()
print("随机掩码:\n", mask) # 0和1均匀分布
总结
- 核心差异:
torch.rand()是 [0,1) 均匀分布,torch.randn()是 μ=0、σ²=1 的标准正态分布,数值范围和统计特征完全不同。 - 用法差异:参数和调用方式完全一致,仅数值分布不同。
- 场景选择:权重初始化/高斯噪声用
randn(),掩码/概率采样/简单随机数用rand()。