PyTorch拟合对数正态分布报错:Normal对象无fit属性求助
对数正态分布拟合代码修正
原问题与错误
尝试将数据拟合成对数正态分布时,出现以下错误:
AttributeError: 'Normal' object has no attribute 'fit'
原代码如下:
import torch import torch.distributions as dist print(torch.cuda.is_available()) # Sample data data = torch.randn(1000) # Fit the data to a log-normal distribution mu, std = dist.Normal(0, 1).fit(torch.log(data)) # Create a log-normal distribution with the fitted parameters lognormal = dist.LogNormal(mu, std) # Get the probability density function (PDF) of the log-normal distribution pdf = lognormal.log_prob(torch.log(data)).exp() # Plot the data and the PDF import matplotlib.pyplot as plt plt.hist(data, bins=30, density=True) plt.plot(data, pdf, 'r') plt.show()
错误原因
PyTorch的torch.distributions模块中的分布类没有内置fit方法,无法直接通过该方法拟合数据。此外原代码还有两处问题:
torch.randn生成的数据包含负数,对负数取对数会报错,而对数正态分布的样本必须为正数。- 绘图时未对数据排序,导致PDF曲线混乱无序。
修正方案
对数正态分布的核心特性是:若随机变量X服从对数正态分布,则ln(X)服从正态分布。因此只需对正数数据取对数后,计算其均值和标准差,即可得到对数正态分布的参数。
修正后的完整代码:
import torch import torch.distributions as dist import matplotlib.pyplot as plt print(torch.cuda.is_available()) # 生成符合对数正态分布的正数样本(避免负数取log报错) data = dist.LogNormal(0, 1).sample((1000,)) # 对数据取对数,转换为正态分布的样本 log_data = torch.log(data) # 计算正态分布的均值和标准差,即对数正态分布的参数mu和std mu = log_data.mean() std = log_data.std() # 创建拟合后的对数正态分布 lognormal = dist.LogNormal(mu, std) # 计算PDF:对原数据取log后传入log_prob,再exp得到概率密度 # 排序数据和对应的PDF,确保绘图曲线平滑 sorted_data, indices = torch.sort(data) pdf = lognormal.log_prob(torch.log(sorted_data)).exp() # 绘制直方图和拟合曲线 plt.hist(data, bins=30, density=True, alpha=0.6, label='Sample Data') plt.plot(sorted_data, pdf, 'r-', label='Fitted Log-Normal PDF') plt.xlabel('Value') plt.ylabel('Density') plt.legend() plt.show()
关键修正点
- 替换样本生成方式:用
dist.LogNormal生成正数样本,确保取对数时无错误。 - 手动计算参数:通过
torch.mean和torch.std直接计算对数数据的均值和标准差,作为对数正态分布的参数。 - 排序数据:对样本和对应的PDF值排序,保证拟合曲线的连续性。
内容的提问来源于stack exchange,提问作者DataWrangler1980
相关产品推荐
相关产品推荐

