news 2026/4/16 17:07:29

如何使用pytorch模拟Pearson loss训练模型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何使用pytorch模拟Pearson loss训练模型

Pearson相关系数通常用于衡量两个变量之间的线性相关性。

之前介绍了如何用python模拟Pearson相关系数损失。

https://blog.csdn.net/liliang199/article/details/155751622

pytorch是最流行的模型训练工具,这里尝试用pytorch实现Pearson loss训练模型的过程。

所用代码和示例参考和修改自网络资料。

1 模型定义

这里参考pytorch开发模型的力促,先通过torch的nn.Module定义模型,然后定义Pearson损失。

1.1 模型定义

这里使用torch的Linear模块直接模拟weights和bias。

input_dim为输入维度,需要与输入X的维度一致,输出为1。

代码示例如下所示。

# 创建简单的线性模型 class LinearModel(nn.Module): def __init__(self, input_dim): super(LinearModel, self).__init__() self.linear = nn.Linear(input_dim, 1) def forward(self, x): return self.linear(x).squeeze()

1.2 损失定义

参考pytorch损失函数的定义流程,定义Pearson损失函数。

Pearson相关系数有两种常用的损失函数形式:1 - |r| 或 1 - r^2。

基于绝对值的损失:1 - |r|,取值范围 [0, 1]

基于平方的损失:1 - r^2,取值范围 [0, 1],对弱相关更敏感。

这里为简化分析采用第一种

# 使用PyTorch实现Pearson损失函数的版本 class PearsonLossTorch(nn.Module): def __init__(self): super(PearsonLossTorch, self).__init__() def forward(self, y_pred, y_true): # 计算Pearson相关系数 v_pred = y_pred - torch.mean(y_pred) v_true = y_true - torch.mean(y_true) numerator = torch.sum(v_pred * v_true) denominator = torch.sqrt(torch.sum(v_pred ** 2)) * torch.sqrt(torch.sum(v_true ** 2)) # 防止除以零 if denominator == 0: denominator = 1e-10 pearson_r = numerator / denominator # 返回1 - r作为损失 return 1 - pearson_r

1.3 梯度定义

Pearson损失相对weight和bias的梯度定义如下所示

具体过程参考

https://blog.csdn.net/liliang199/article/details/155751622

由于torch版本实现可以自动根据loss函数计算梯度,所以这里不需要单独计算梯度。

具体过程参考模型训练过程,示例如下

loss.backward()

2 模型训练

这里分别准备训练数据和使用pytorch训练模型。

2.1 训练数据

对于输入X,目标值y的生成核心逻辑如下

X是一个三维向量,true_weights是权重,true_bias是固定偏移,为保证随机性加随机偏移。

y = np.dot(X, true_weights) + true_bias + np.random.randn(n_samples) * noise

训练数据生成代码如下所示,具体过程参考

https://blog.csdn.net/liliang199/article/details/155751622

import numpy as np import matplotlib.pyplot as plt from sklearn.datasets import make_regression from sklearn.preprocessing import StandardScaler # 创建模拟数据 def generate_synthetic_data(n_samples=200, noise=10.0, seed=42): """生成合成数据""" np.random.seed(seed) # 生成特征 dim_size = 3 X = np.random.randn(n_samples, dim_size) # 生成真实权重 true_weights = np.array([2.5, -1.5, 0.8, 1.8, 3.2, 6.9, 7.8][:dim_size]) true_bias = 1.0 # 生成目标值 y = np.dot(X, true_weights) + true_bias + np.random.randn(n_samples) * noise # 标准化特征(有助于训练) scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # 标准化目标值 y_mean, y_std = y.mean(), y.std() y_scaled = (y - y_mean) / y_std return X_scaled, y_scaled, y_mean, y_std

2.2 模型训练

参考pytorch训练模型流程,在每次迭代过程中:

1)先计算预测值predictions

2)然后根据预测值predictions和实际值y_tensor,计算Pearson损失loss

3)再然后通过loss.backward() optimizer.step()计算梯度,更新模型

torch版Pearson损失训练模型的伪码如下所示。

X_tensor = torch.FloatTensor(X_np)
y_tensor = torch.FloatTensor(y_np)

model = LinearModel(X_np.shape[1])
criterion = PearsonLossTorch()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 训练
losses = []
for epoch in range(1000):
optimizer.zero_grad()
predictions = model(X_tensor)
loss = criterion(predictions, y_tensor)
loss.backward()
optimizer.step()
losses.append(loss.item())

以下是torch版本的Pearson损失训练模型的代码。

def pytorch_version(): """ 使用PyTorch实现Pearson损失函数的版本 需要安装: pip install torch """ try: import torch import torch.nn as nn import torch.optim as optim class PearsonLossTorch(nn.Module): def __init__(self): super(PearsonLossTorch, self).__init__() def forward(self, y_pred, y_true): # 计算Pearson相关系数 v_pred = y_pred - torch.mean(y_pred) v_true = y_true - torch.mean(y_true) numerator = torch.sum(v_pred * v_true) denominator = torch.sqrt(torch.sum(v_pred ** 2)) * torch.sqrt(torch.sum(v_true ** 2)) # 防止除以零 if denominator == 0: denominator = 1e-10 pearson_r = numerator / denominator # 返回1 - r作为损失 return 1 - pearson_r # 创建简单的线性模型 class LinearModel(nn.Module): def __init__(self, input_dim): super(LinearModel, self).__init__() self.linear = nn.Linear(input_dim, 1) def forward(self, x): return self.linear(x).squeeze() # 示例用法 print("\nPyTorch版本:") X_np, y_np, _, _ = generate_synthetic_data() X_tensor = torch.FloatTensor(X_np) y_tensor = torch.FloatTensor(y_np) model = LinearModel(X_np.shape[1]) criterion = PearsonLossTorch() optimizer = optim.SGD(model.parameters(), lr=0.01) # 训练 losses = [] for epoch in range(1000): optimizer.zero_grad() predictions = model(X_tensor) loss = criterion(predictions, y_tensor) loss.backward() optimizer.step() losses.append(loss.item()) if epoch % 200 == 0: print(f"Epoch {epoch}: Loss = {loss.item():.4f}") print("PyTorch训练完成!") except ImportError: print("PyTorch未安装,跳过PyTorch示例。") print("安装命令: pip install torch") pytorch_version()

训练输出如下,可见随着训练进行,模型越来越收敛,说明Pearson loss生效了。

PyTorch版本:
Epoch 0: Loss = 0.8733
Epoch 200: Loss = 0.7504
Epoch 400: Loss = 0.7321
Epoch 600: Loss = 0.7300
Epoch 800: Loss = 0.7298
PyTorch训练完成!

reference

---

如何使用python模拟Pearson loss训练模型

https://blog.csdn.net/liliang199/article/details/155751622

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!