PyTorch 中 Tensor 统计学函数及相关概念
文章目录
- PyTorch 中 Tensor 统计学函数及相关概念
- 一、引言
- 二、基础统计学函数
- (一)torch.mean()——均值计算
- (二)torch.sum()——总和计算
- (三)torch.prod()——元素积计算
- (四)torch.max() & torch.min()——最值及索引
- (五)torch.argmax() & torch.argmin()——最值索引
- 三、离散程度与分布相关函数
- (一)torch.std()——标准差
- (二)torch.var()——方差
- (三)torch.median()——中位数
- (四)torch.mode()——众数
- (五)torch.histc()——直方图计算
- (六)torch.bincount()——元素频数
- 四、分布函数与随机抽样
- (一)常见分布生成函数
- 1. torch.normal()——正态分布抽样
- 2. torch.randn()——标准正态分布快捷函数
- 3. torch.rand()——均匀分布抽样
- 4. torch.randint()——整数均匀分布抽样
- (二)分布相关的其他函数
- 1. torch.bernoulli()——伯努利分布抽样
- 2. torch.multinomial()——多项式分布抽样
- 五、协方差与相关性分析
- (一)torch.cov()——协方差计算
- (二)torch.corrcoef()——相关系数计算
- 六、总结与实践建议
PyTorch 中 Tensor 统计学函数及相关概念
一、引言
PyTorch 中 Tensor(张量)是数据操作的核心载体。统计学函数能助力我们剖析张量数据的特征,不管是基础的均值、方差,还是分布相关操作,都极为关键。本文将深入讲解 PyTorch 中 Tensor 统计学函数,搭配详细概念解析与代码示例,带你吃透这些工具 。
二、基础统计学函数
(一)torch.mean()——均值计算
概念:均值是一组数据的平均值,反映数据的集中趋势,计算方式为所有元素总和除以元素个数 。
函数原型:torch.mean(input, dim=None, keepdim=False, dtype=None) → Tensor
input
:输入的张量,数据操作的对象。dim
:可选参数,指定在哪些维度上计算均值,若为None
,计算所有元素的均值;比如张量是(2,3)
形状,dim=0
计算列均值,dim=1
计算行均值 。keepdim
:布尔值,设为True
时,输出张量保留输入的维度结构,方便后续维度匹配操作 。dtype
:可选,输出张量的数据类型。
代码示例:
import torch# 创建张量
tensor = torch.tensor([[1., 2.], [3., 4.]])
# 计算所有元素均值
mean_all = torch.mean(tensor)
# 按行(dim=1)计算均值,保留维度
mean_row = torch.mean(tensor, dim=1, keepdim=True)
print("所有元素均值:", mean_all)
print("按行均值(保留维度):", mean_row)
运行结果:
所有元素均值: tensor(2.5000)
按行均值(保留维度): tensor([[1.5000],[3.5000]])
结果分析:所有元素均值是 (1 + 2 + 3 + 4) / 4 = 2.5
;按行计算时,第一行 (1 + 2)/2 = 1.5
,第二行 (3 + 4)/2 = 3.5
,因 keepdim=True
,输出维度为 (2,1)
。
(二)torch.sum()——总和计算
概念:将张量中元素累加,得到总和,用于了解数据总量情况 。
函数原型:torch.sum(input, dim=None, keepdim=False, dtype=None) → Tensor
参数含义和 torch.mean
类似,input
是输入张量,dim
指定求和维度,keepdim
控制维度保留,dtype
设输出类型 。
代码示例:
tensor = torch.tensor([[1, 2], [3, 4]])
# 所有元素求和
sum_all = torch.sum(tensor)
# 按列(dim=0)求和
sum_col = torch.sum(tensor, dim=0)
print("所有元素总和:", sum_all)
print("按列求和结果:", sum_col)
运行结果:
所有元素总和: tensor(10)
按列求和结果: tensor([4, 6])
结果分析:所有元素总和是 1 + 2 + 3 + 4 = 10
;按列求和,第一列 1 + 3 = 4
,第二列 2 + 4 = 6
。
(三)torch.prod()——元素积计算
概念:计算张量所有元素的乘积,反映元素连乘的结果,在一些概率连乘等场景有用 。
函数原型:torch.prod(input, dim=None, keepdim=False, dtype=None) → Tensor
参数逻辑同前面函数,对输入张量元素做乘积运算 。
代码示例:
tensor = torch.tensor([[2, 3], [4, 5]])
# 所有元素乘积
prod_all = torch.prod(tensor)
# 按行(dim=1)乘积
prod_row = torch.prod(tensor, dim=1)
print("所有元素乘积:", prod_all)
print("按行乘积结果:", prod_row)
运行结果:
所有元素乘积: tensor(120)
按行乘积结果: tensor([ 6, 20])
结果分析:所有元素乘积是 2×3×4×5 = 120
;按行乘积,第一行 2×3 = 6
,第二行 4×5 = 20
。
(四)torch.max() & torch.min()——最值及索引
概念:torch.max
找张量中最大值,torch.min
找最小值,还能结合 argmax
、argmin
找对应索引,用于定位极值位置 。
torch.max
函数原型:torch.max(input, dim, keepdim=False, out=None) → (Tensor, LongTensor)
(当指定 dim
时,返回最值和索引;不指定 dim
只返回最值)
input
:输入张量。dim
:指定在哪个维度找最值。keepdim
:是否保留维度。
torch.min
类似,只是找最小值 。
代码示例:
tensor = torch.tensor([[1, 5], [3, 2]])
# 找全局最大值
max_val = torch.max(tensor)
# 按列(dim=0)找最大值及索引
max_col, max_col_idx = torch.max(tensor, dim=0)
# 找全局最小值
min_val = torch.min(tensor)
print("全局最大值:", max_val)
print("按列最大值:", max_col)
print("按列最大值索引:", max_col_idx)
print("全局最小值:", min_val)
运行结果:
全局最大值: tensor(5)
按列最大值: tensor([3, 5])
按列最大值索引: tensor([1, 0])
全局最小值: tensor(1)
结果分析:全局最大值是 5
,全局最小值是 1
;按列看,第一列 1
和 3
最大值是 3
(索引 1
,对应第二行),第二列 5
和 2
最大值是 5
(索引 0
,对应第一行 )。
(五)torch.argmax() & torch.argmin()——最值索引
概念:专门用于找张量中最大值、最小值的索引,常和 max
、min
配合,精准定位极值位置 。
函数原型:torch.argmax(input, dim=None, keepdim=False) → LongTensor
,torch.argmin
同理 。
参数中 dim
指定在哪个维度找索引,keepdim
控制维度保留 。
代码示例:
tensor = torch.tensor([[1, 5], [3, 2]])
# 全局最大值索引
argmax_all = torch.argmax(tensor)
# 按行(dim=1)找最大值索引
argmax_row = torch.argmax(tensor, dim=1)
print("全局最大值索引:", argmax_all)
print("按行最大值索引:", argmax_row)
运行结果:
全局最大值索引: tensor(1)
按行最大值索引: tensor([1, 0])
结果分析:张量展平后元素索引从 0
开始,5
在展平后索引是 1
,所以全局最大值索引是 1
;按行看,第一行最大值 5
索引是 1
,第二行最大值 3
索引是 0
。
三、离散程度与分布相关函数
(一)torch.std()——标准差
概念:标准差衡量数据的离散程度,反映数据相对于均值的波动情况,公式为方差的平方根,方差是各数据与均值差的平方的平均数 。
函数原型:torch.std(input, dim=None, keepdim=False, unbiased=True, dtype=None) → Tensor
unbiased
:布尔值,设为True
时,计算样本标准差(除以n - 1
,n
是元素个数 );False
时计算总体标准差(除以n
) 。
代码示例:
tensor = torch.tensor([1., 3., 5., 7.])
# 总体标准差(unbiased=False)
std_pop = torch.std(tensor, unbiased=False)
# 样本标准差(unbiased=True)
std_sample = torch.std(tensor, unbiased=True)
print("总体标准差:", std_pop)
print("样本标准差:", std_sample)
运行结果:
总体标准差: tensor(2.2361)
样本标准差: tensor(2.5820)
结果分析:均值是 (1 + 3 + 5 + 7)/4 = 4
。总体标准差计算:先算每个数与均值差的平方和 ( (1-4)^2 + (3-4)^2 + (5-4)^2 + (7-4)^2 ) = 20
,除以 4
得方差 5
,开平方约 2.2361
。样本标准差除以 3
(n - 1 = 3
),方差约 6.6667
,开平方约 2.5820
。
(二)torch.var()——方差
概念:方差是标准差的平方,同样体现数据离散程度,是各数据与均值差的平方的平均数(或样本情况下除以 n - 1
) 。
函数原型:torch.var(input, dim=None, keepdim=False, unbiased=True, dtype=None) → Tensor
参数 unbiased
作用和 torch.std
一致,控制计算样本方差还是总体方差 。
代码示例:
tensor = torch.tensor([1., 3., 5., 7.])
# 总体方差(unbiased=False)
var_pop = torch.var(tensor, unbiased=False)
# 样本方差(unbiased=True)
var_sample = torch.var(tensor, unbiased=True)
print("总体方差:", var_pop)
print("样本方差:", var_sample)
运行结果:
总体方差: tensor(5.)
样本方差: tensor(6.6667)
结果分析:依据前面标准差计算的中间步骤,总体方差是 5
,样本方差约 6.6667
,和理论计算相符。
(三)torch.median()——中位数
概念:中位数是将数据排序后,位于中间位置的数值(数据个数奇数时是中间数;偶数时是中间两个数的平均值 ),能避免极端值影响,反映数据中间水平 。
函数原型:torch.median(input, dim=None, keepdim=False, out=None) → (Tensor, LongTensor)
(指定 dim
时返回中位数和索引;不指定返回全局中位数 )
代码示例:
tensor = torch.tensor([1, 3, 5, 7, 9])
# 全局中位数
median_all = torch.median(tensor)
# 若 tensor 是 torch.tensor([1, 3, 5, 8])
tensor_even = torch.tensor([1, 3, 5, 8])
median_even = torch.median(tensor_even)
print("奇数个元素中位数:", median_all)
print("偶数个元素中位数:", median_even)
运行结果:
奇数个元素中位数: tensor(5)
偶数个元素中位数: tensor(4.)
结果分析:奇数个元素时,排序后中间数是 5
;偶数个元素时,中间两个数 3
和 5
,平均值 (3 + 5)/2 = 4
。
(四)torch.mode()——众数
概念:众数是数据中出现次数最多的数值,用于了解数据中最常出现的特征 。
函数原型:torch.mode(input, dim=None) → (Tensor, LongTensor)
返回众数和其出现的索引(指定 dim
时按维度找众数 )。
代码示例:
tensor = torch.tensor([1, 2, 2, 3, 3, 3])
# 全局众数
mode_all = torch.mode(tensor)
# 按自定义维度(这里假设二维 tensor 演示,实际一维也可拓展)
tensor_2d = torch.tensor([[1, 2, 2], [3, 3, 3]])
mode_2d, mode_2d_idx = torch.mode(tensor_2d, dim=1)
print("全局众数:", mode_all)
print("二维张量按行众数:", mode_2d)
print("二维张量按行众数索引:", mode_2d_idx)
运行结果:
全局众数: (tensor(3), tensor(5))
二维张量按行众数: tensor([2, 3])
二维张量按行众数索引: tensor([1, 1])
结果分析:全局中 3
出现次数最多(3 次),索引 5
;二维张量按行,第一行 2
出现次数多,索引 1
;第二行 3
出现次数多,索引 1
。
(五)torch.histc()——直方图计算
概念:直方图用于统计数据在不同区间的分布情况,把数据划分到若干区间(bins),统计每个区间内元素个数 。
函数原型:torch.histc(input, bins=100, min=0, max=1) → Tensor
bins
:区间个数。min
:数据最小值区间的下限。max
:数据最大值区间的上限,输入数据需在[min, max]
范围,否则会被过滤 。
代码示例:
tensor = torch.tensor([1., 2., 2., 3., 3., 3.])
# 划分 3 个区间,范围 [1, 3]
hist = torch.histc(tensor, bins=3, min=1, max=3)
print("直方图统计结果:", hist)
运行结果:
直方图统计结果: tensor([1., 2., 3.])
结果分析:区间 [1, 2)
(左闭右开 )有 1
个元素(数值 1
),[2, 2.5)
有 2
个元素(两个 2
),[2.5, 3]
有 3
个元素(三个 3
),所以统计结果对应这三个区间的元素个数 。
(六)torch.bincount()——元素频数
概念:统计非负整数张量中每个值出现的频数,常用于简单的计数场景 。
函数原型:torch.bincount(input, weights=None, minlength=0) → Tensor
weights
:可选,为每个元素加权,输出是加权后的频数和 。minlength
:指定输出张量的最小长度,若实际统计最大值小于它,会用0
填充 。
代码示例:
tensor = torch.tensor([0, 1, 1, 2, 2, 2])
# 基础频数统计
bincount = torch.bincount(tensor)
# 加权统计,权重 tensor([1, 1, 1, 1, 1, 1]) (这里简单用 1 演示,可自定义)
weights = torch.ones_like(tensor)
bincount_weighted = torch.bincount(tensor, weights=weights)
print("基础频数统计:", bincount)
print("加权频数统计:", bincount_weighted)
运行结果:
基础频数统计: tensor([1, 2, 3])
加权频数统计: tensor([1., 2., 3.])
结果分析:值 0
出现 1
次,1
出现 2
次,2
出现 3
次;加权时因权重都是 1
,结果和基础统计一样,若权重不同,比如 weights = torch.tensor([2, 1, 1, 1, 1, 1])
,值 0
加权频数就是 2
,可灵活调整 。
四、分布函数与随机抽样
(一)常见分布生成函数
PyTorch 可生成多种分布的随机数,比如正态分布、均匀分布等,用于模拟数据或初始化参数 。
1. torch.normal()——正态分布抽样
概念:从正态(高斯)分布中抽样,正态分布由均值(μ)和标准差(σ)刻画,概率密度函数呈钟形曲线,是自然界中最常见的分布之一。
函数原型:
torch.normal(mean, std, *, generator=None, out=None) → Tensor
参数说明:
mean
:张量,指定每个元素的均值,形状决定输出张量的形状。std
:张量,指定每个元素的标准差,需与mean
形状相同。generator
:可选的随机数生成器,用于控制随机种子,保证结果可复现。out
:可选的输出张量。
代码示例:
import torch# 生成均值为0、标准差为1的正态分布随机数(标准正态分布)
# 方法1:指定标量均值和标准差,生成形状为(2, 3)的张量
normal_tensor1 = torch.normal(mean=0.0, std=1.0, size=(2, 3))
# 方法2:通过均值张量和标准差张量指定每个元素的分布参数
mean = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
std = torch.tensor([[0.1, 0.2], [0.3, 0.4]])
normal_tensor2 = torch.normal(mean=mean, std=std)print("标准正态分布随机数:\n", normal_tensor1)
print("指定均值和标准差的正态分布随机数:\n", normal_tensor2)
运行结果(因随机性,每次结果不同):
标准正态分布随机数:tensor([[-0.5414, 0.1637, -1.0923],[ 0.3677, 0.8820, -0.3387]])
指定均值和标准差的正态分布随机数:tensor([[0.9876, 2.0123],[3.1024, 3.9876]])
结果分析:
- 标准正态分布(mean=0, std=1)的随机数大部分落在[-3, 3]区间内。
- 第二个示例中,每个元素的取值围绕对应位置的
mean
波动,波动幅度由std
决定(std
越大,数据越分散)。
2. torch.randn()——标准正态分布快捷函数
概念:是 torch.normal(mean=0, std=1)
的快捷方式,专门生成均值为0、标准差为1的标准正态分布随机数。
函数原型:
torch.randn(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor
参数说明:
size
:整数序列,指定输出张量的形状,如(2, 3)
表示2行3列。- 其他参数用于指定数据类型、设备等,通常默认即可。
代码示例:
# 生成形状为(3, 3)的标准正态分布随机数
randn_tensor = torch.randn(3, 3)
print("标准正态分布随机数(randn):\n", randn_tensor)
运行结果:
标准正态分布随机数(randn):tensor([[ 0.2824, -0.3715, 1.2038],[-0.5687, 0.7648, -0.1234],[ 1.5421, -0.8763, 0.4567]])
3. torch.rand()——均匀分布抽样
概念:从区间 [0, 1)
上的均匀分布中抽样,即每个数值在该区间内出现的概率相等。
函数原型:
torch.rand(*size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor
参数说明:
size
:指定输出张量的形状,与torch.randn
一致。
代码示例:
# 生成形状为(2, 2)的[0,1)均匀分布随机数
rand_tensor = torch.rand(2, 2)
print("均匀分布随机数([0,1)):\n", rand_tensor)
运行结果:
均匀分布随机数([0,1)):tensor([[0.3456, 0.8721],[0.1234, 0.6543]])
结果分析:所有元素值均在 [0, 1)
范围内,且分布较为均匀,适合需要“公平”随机数的场景(如随机初始化掩码)。
4. torch.randint()——整数均匀分布抽样
概念:从区间 [low, high)
上的整数均匀分布中抽样,生成指定范围内的随机整数。
函数原型:
torch.randint(low=0, high, size, *, generator=None, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor
参数说明:
low
:整数,区间下限(包含),默认值为0。high
:整数,区间上限(不包含)。size
:指定输出张量的形状。
代码示例:
# 生成形状为(3, 2)、范围在[1, 10)的随机整数
randint_tensor = torch.randint(low=1, high=10, size=(3, 2))
print("整数均匀分布随机数([1,10)):\n", randint_tensor)
运行结果:
整数均匀分布随机数([1,10)):tensor([[5, 3],[8, 2],[7, 9]])
(二)分布相关的其他函数
1. torch.bernoulli()——伯努利分布抽样
概念:伯努利分布是单个二元随机变量的分布,输出为0或1,其中1的概率为 p
,0的概率为 1-p
,常用于模拟二分类随机事件(如抛硬币)。
函数原型:
torch.bernoulli(input, *, generator=None, out=None) → Tensor
参数说明:
input
:张量,元素值p
需在[0, 1]
范围内,表示每个位置输出1的概率。
代码示例:
# 生成概率为0.5的伯努利分布(模拟抛硬币,正面概率50%)
prob = torch.tensor([0.5])
bernoulli_tensor = torch.bernoulli(prob.repeat(5)) # 重复5次,生成5个样本
print("伯努利分布抽样结果(0=反面,1=正面):", bernoulli_tensor)
运行结果(随机):
伯努利分布抽样结果(0=反面,1=正面): tensor([1., 0., 1., 1., 0.])
2. torch.multinomial()——多项式分布抽样
概念:多项式分布是二项分布的扩展,用于从多个类别中抽样,每个类别有对应的概率,且抽样结果为类别索引。
函数原型:
torch.multinomial(input, num_samples, replacement=False, *, generator=None, out=None) → LongTensor
参数说明:
input
:张量,每行表示一个概率分布(元素非负且和为1)。num_samples
:整数,指定每个行抽样的次数。replacement
:布尔值,True
表示有放回抽样(同一类别可重复选中),False
表示无放回抽样(每个类别最多被选中一次)。
代码示例:
# 定义一个概率分布:3个类别的概率分别为0.2、0.3、0.5
probs = torch.tensor([0.2, 0.3, 0.5])
# 无放回抽样2次(每个类别最多选一次)
multinomial_no_replace = torch.multinomial(probs, num_samples=2, replacement=False)
# 有放回抽样5次(可重复选)
multinomial_replace = torch.multinomial(probs, num_samples=5, replacement=True)print("无放回抽样结果:", multinomial_no_replace)
print("有放回抽样结果:", multinomial_replace)
运行结果(随机):
无放回抽样结果: tensor([2, 1])
有放回抽样结果: tensor([2, 2, 1, 2, 0])
结果分析:概率最高的类别(索引2,概率0.5)在有放回抽样中出现次数最多,符合预期。
五、协方差与相关性分析
(一)torch.cov()——协方差计算
概念:协方差衡量两个变量的联合变化程度,若协方差为正,变量同向变化;为负则反向变化;接近0则线性相关性弱。对于张量 x
,协方差矩阵 C
的元素 C[i][j]
表示第 i
行与第 j
行的协方差。
函数原型:
torch.cov(input, correction=1) → Tensor
参数说明:
input
:二维张量,每行代表一个变量,每列代表一个观测值。correction
:修正项,correction=1
表示样本协方差(除以n-1
),correction=0
表示总体协方差(除以n
)。
代码示例:
# 定义两个变量:x 和 y(x增大时y也增大,预期协方差为正)
x = torch.tensor([[1., 2., 3., 4., 5.]]) # 第一行是变量x
y = torch.tensor([[2., 4., 6., 8., 10.]]) # 第二行是变量y(y=2x)
data = torch.cat((x, y), dim=0) # 合并为2行5列的张量# 计算协方差矩阵
cov_matrix = torch.cov(data)
print("协方差矩阵:\n", cov_matrix)
运行结果:
协方差矩阵:tensor([[ 2.5000, 5.0000],[ 5.0000, 10.0000]])
结果分析:
C[0][0]
是x
的方差(2.5),C[1][1]
是y
的方差(10.0)。C[0][1]
和C[1][0]
是x
与y
的协方差(5.0),为正值,说明两者正相关。
(二)torch.corrcoef()——相关系数计算
概念:相关系数(皮尔逊相关系数)是标准化的协方差,取值范围为 [-1, 1]
,消除了量纲影响,更直观地反映变量间的线性相关程度(1表示完全正相关,-1表示完全负相关,0表示无线性相关)。
函数原型:
torch.corrcoef(input, correction=1) → Tensor
参数说明:与 torch.cov
一致,input
为二维张量(每行一个变量)。
代码示例:
# 使用上面的x和y数据(y=2x,理论上相关系数为1)
corr_matrix = torch.corrcoef(data)
print("相关系数矩阵:\n", corr_matrix)
运行结果:
相关系数矩阵:tensor([[1.0000, 1.0000],[1.0000, 1.0000]])
结果分析:x
和 y
完全线性相关(y=2x
),因此相关系数为1,符合理论预期。
六、总结与实践建议
PyTorch 的 Tensor 统计学函数覆盖了从基础描述统计(均值、方差)到分布生成、相关性分析的全流程,是数据预处理、模型评估、实验仿真的重要工具。使用时需注意:
- 维度指定:多数函数通过
dim
参数控制计算维度,需明确张量形状与计算目标(如行/列统计)。 - 样本 vs 总体:方差、标准差等函数的
unbiased
参数需根据数据是否为样本(需除以n-1
)或总体(除以n
)选择。 - 随机可复现性:分布抽样函数可通过
generator
参数固定随机种子(如torch.Generator().manual_seed(42)
),保证实验结果一致。
)
print(“相关系数矩阵:\n”, corr_matrix)
**运行结果**:
相关系数矩阵:
tensor([[1.0000, 1.0000],
[1.0000, 1.0000]])
**结果分析**:`x` 和 `y` 完全线性相关(`y=2x`),因此相关系数为1,符合理论预期。## 六、总结与实践建议
PyTorch 的 Tensor 统计学函数覆盖了从基础描述统计(均值、方差)到分布生成、相关性分析的全流程,是数据预处理、模型评估、实验仿真的重要工具。使用时需注意:1. **维度指定**:多数函数通过 `dim` 参数控制计算维度,需明确张量形状与计算目标(如行/列统计)。
2. **样本 vs 总体**:方差、标准差等函数的 `unbiased` 参数需根据数据是否为样本(需除以 `n-1`)或总体(除以 `n`)选择。
3. **随机可复现性**:分布抽样函数可通过 `generator` 参数固定随机种子(如 `torch.Generator().manual_seed(42)`),保证实验结果一致。掌握这些函数,能帮助你更高效地分析数据特征、构建合理的模型初始化策略,为深度学习任务打下坚实基础。