如何使用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

相关推荐
做cv的小昊2 小时前
VLM相关论文阅读:【LoRA】Low-rank Adaptation of Large Language Models
论文阅读·人工智能·深度学习·计算机视觉·语言模型·自然语言处理·transformer
VertGrow AI销冠2 小时前
AI获客软件VertGrow AI销冠的自动化功能测评
人工智能
TextIn智能文档云平台2 小时前
抽取出的JSON结构混乱,如何设计后处理规则来标准化输出?
人工智能·json
百罹鸟2 小时前
在langchain Next 项目中使用 shadcn/ui 的记录
前端·css·人工智能
MediaTea2 小时前
Python 的设计哲学P08:可读性与人类语言
开发语言·python
qq_251533592 小时前
如何使用 Python 正则表达式去除空格/制表符/换行符?
开发语言·python·正则表达式
python_1362 小时前
2026年AI论文修改降重工具推荐喵喵降
人工智能
Akamai中国2 小时前
无服务器计算架构的优势
人工智能·云计算·云服务
Mintopia2 小时前
🌐 开源社区在 WebAIGC 技术迭代中的推动作用与争议
前端·人工智能·aigc