torch.randn()是 PyTorch 中用于生成服从标准正态分布(均值为 0,标准差为 1)的随机张量的核心函数
生成不同形状张量的示例
生成标量(0维张量)
>>> torch.randn(())
tensor(-0.6713) # 形状: torch.Size([])
生成向量(1维张量)
>>> torch.randn(5) # 长度为5的向量
tensor([-1.4123, 0.7111, 2.0729, 1.4402, -0.7117]) # 形状: torch.Size([5])
生成矩阵(2维张量)
>>> torch.randn(3, 4) # 3行4列的矩阵
tensor([[ 0.8147, -0.2505, -0.4497, 1.1226],
[ 2.1816, 1.6623, -0.5899, -0.5745],
[-0.6160, 0.5105, -0.6703, 0.5460]]) # 矩阵形状: torch.Size([3, 4])
生成3维张量(常用于图像数据的通道、高度、宽度)
>>> torch.randn(3, 224, 224) # 3通道,高224,宽224
# torch.Size([3, 224, 224])
生成4维张量(常用于批量图像数据:[batch, channel, height, width])
>>> torch.randn(2, 3, 224, 224) # 批量大小为2,通道3,高224,宽224
4维张量形状: torch.Size([2, 3, 224, 224])
调整分布参数
若需非标准正态分布(均值 μ,标准差 σ),通过线性变换实现
mean, std = 5, 2
x = torch.randn(2, 2) * std + mean # 生成 N(5, 4) 分布
可重复性与随机性的控制(随机种子Seed)
torch.manual_seed(42) # 设置种子
x = torch.randn(2, 2)
典型应用场景
1、神经网络权重初始化:
conv_weight = torch.randn(16, 3, 3, 3) # 16个3x3卷积核,输入通道3
神经网络权重需打破对称性,避免全零初始化导致的梯度消失。torch.randn()生成的小随机数可确保初始权重接近零但具有差异性,促进梯度有效传播。
进阶的初始化方法
- Xavier/Glorot 初始化:适用于 sigmoid/tanh激活函数,调整标准差为 nin+nout2。
- He 初始化:常用于使用 ReLU 激活函数的神经网络层(如卷积层),目的是通过合理初始化权重,缓解训练过程中的梯度消失或爆炸问题。
举个栗子:
He 初始化(He initialization) 的具体实现
# 创建卷积层
conv_layer = nn.Conv2d(3, 16, kernel_size=3)
# He 初始化(使用 PyTorch 内置函数)
nn.init.kaiming_normal_(conv_layer.weight, mode='fan_in', nonlinearity='relu')
先定义了一个 2D 卷积层 conv_layer:
- 输入通道数为3(如 RGB 图像);
- 输出通道数为16(16 个卷积核);
- kernel_size=3,即卷积核大小为 3×3。
此时,卷积层的权重 conv_layer.weight 已被 PyTorch 随机初始化,但可能不符合 He 初始化的分布。
PyTorch 内置的 He 初始化函数,作用是将卷积层的权重 conv_layer.weight 重新初始化为符合 He 分布的随机数:
- kaiming_normal_:He 提出的正态分布初始化方法(“_” 表示原地修改权重);如何理解原地修改权重
- mode=‘fan_in’:表示以 输入特征数 为基准计算标准差(He 初始化推荐用于 ReLU 时使用 fan_in);如何理解 fan_in与 fan_out
- 对于卷积层,fan_in 的计算方式为:输入通道数 × 卷积核高 × 卷积核宽(这里是 3×3×3=27);
- nonlinearity=‘relu’:指定激活函数为 ReLU(He 初始化会根据激活函数调整分布参数)。
等价手动实现:
# 计算 fan_in:输入通道数 × 卷积核高 × 卷积核宽
fan_in = 3 * 3 * 3 # 27
# 生成符合 He 初始化的权重(正态分布 N(0, σ²),其中 σ = √(2/fan_in))
conv_layer.weight = torch.randn(16, 3, 3, 3) * (2 / fan_in) **0.5
这行代码展示了 He 初始化的数学本质:
torch.randn(16, 3, 3, 3):生成形状为 [输出通道数,输入通道数,核高,核宽] 的随机数,服从 标准正态分布 N (0, 1);- (2 / fan_in) **0.5:He 初始化的标准差(σ)计算公式。
核心原理:He 初始化针对 ReLU 激活函数设计,其核心是让权重的初始化分布满足:权重~N (0, σ²),其中 σ² = 2 /fan_in
2、 随机噪声生成与数据增强
模拟输入数据(如图像批量):
input_batch = torch.randn(32, 3, 64, 64) # 批量32,RGB图像64x64
噪声生成(GANs),作为生成器的随机噪声输入:
noise = torch.randn(16, 100) # 16个噪声向量,维度100
数据增强:向图像/音频添加高斯噪声,提升模型鲁棒性。例如,在图像数据中注入噪声模拟低光照条件:
#生成原始图像(干净图像)
clean_images = torch.rand(32, 3, 224, 224)
#生成噪声
noise = torch.randn_like(clean_images) * 0.1 # 噪声强度 0.1
#生成带噪声的图像
noisy_images = clean_images + noise
clean_images是一个包含 32 张 3 通道、224×224 分辨率的 “干净图像” 张量(像素值在 0~1 之间,模拟正常图像)。torch.randn_like(clean_images):生成与clean_images形状完全相同(32, 3, 224, 224)的张量,其值服从标准正态分布 N (0, 1)(均值为 0,标准差为 1)。* 0.1:将噪声的标准差缩放为 0.1(此时噪声服从N (0, 0.1²)分布)。这一步控制 “噪声强度”:这里的缩放系数(如 0.1)越小,噪声强度越弱,噪声越不明显;系数越大,噪声强度越强,噪声越明显。- 因此,
noise是一个与原始图像同形状的噪声张量,用于模拟真实场景中的随机噪声(如传感器噪声、传输噪声等)。 - 将原始图像与噪声按像素位置相加,得到被噪声污染的图像
noisy_images。 - 由于原始图像像素值在
[0, 1)之间,噪声值主要分布在[-0.3, 0.3]附近(正态分布约 99.7% 的值落在均值 ±3 倍标准差范围内),因此叠加后像素值可能略微超出[0, 1],实际使用中可能需要额外截断(如noisy_images.clamp(0, 1))
生成对抗网络(GAN):生成器输入为潜空间噪声向量
# 定义潜在空间维度
latent_dim = 100
# 从潜在空间采样随机向量
z = torch.randn(64, latent_dim) # 生成 64 个噪声向量
# 用生成器将向量映射为虚假图像
fake_images = generator(z)
- 潜在空间是一个低维或高维的抽象向量空间,生成模型的核心能力就是将这个空间中的随机向量 “映射” 为真实世界的数据(如图像)。
- 这些随机向量
z通常被称为 “噪声向量”,但它们并非无意义的噪声,而是生成模型的 “输入密码”—— 通过不同的z,生成模型会输出不同的虚假数据。 generator是生成模型(如 GAN 中的生成器网络),它是一个神经网络,接收潜在空间的随机向量z(64, 100)(64 是批量大小,100 是潜在维度)作为输入,通过一系列非线性变换(如卷积、反卷积、激活函数等),最终输出 “看起来像真实图像” 的虚假图像(64, 3, 224, 224)。- 假设
generator设计用于生成 RGB 图像(3 通道),且输出尺寸为224×224,则 fake_images 的形状可能是(64, 3, 224, 224),即 64 张 3 通道、224×224 分辨率的虚假图像。
测试数据生成与验证
- 单元测试:快速生成张量验证模型组件逻辑:
test_input = torch.randn(10, 3) # 测试全连接层
output = linear_layer(test_input)
- 性能压测:生成大规模数据测试系统吞吐量:
large_tensor = torch.randn(10000, 1000).to('cuda') # GPU 压力测试
- 工具替代方案:
- Faker:生成结构化测试数据(如姓名、地址)。
- Mockaroo:在线生成 CSV 测试数据集。
其他的随机函数
torch.rand()函数
生成在 [0, 1) 范围内均匀分布的随机数
>>> torch.rand(3, 2) # 生成3x2的张量
tensor([[0.1064, 0.5662],
[0.0658, 0.1150],
[0.0338, 0.4362]]) # 形状: torch.Size([3, 2])
torch.randint()
生成由3个0到9之间的整数填充的一维张量
>>> torch.randint(low=0, high=10, size=(3,))
tensor([7, 6, 8])
生成由0到9之间的整数填充的二维张量
>>> torch.randint(low=0, high=10, size=(3,2))
tensor([[2, 4],
[7, 3],
[0, 5]])
torch.normal()
生成指定均值和标准差的正态分布随机数
>>> torch.normal(mean=torch.tensor([0.0, 0.0]), std=torch.tensor([1.0, 2.0]))
tensor([0.2706, 1.0389])
第一个数服从N(0, 1),第二个数服从N(0, 2)
1566

被折叠的 条评论
为什么被折叠?



