PyTorch深度学习框架第9天:线性回归实现(波士顿房价预测实战)

PyTorch深度学习框架60天进阶计划——第9天:线性回归实现(波士顿房价预测实战)


学习目标:掌握线性回归模型构建、数据预处理、自定义损失函数及二阶优化器的应用。
核心要点:

  1. 波士顿房价数据集的特征标准化与数据分割
  2. Huber Loss实现与异常值鲁棒性分析
  3. LBFGS优化器的性能实验与对比

一、数据准备与预处理

1. 波士顿房价数据集加载与特征分析

波士顿房价数据集包含13个特征(如犯罪率、房间数等)和1个目标变量(房价中位数)。

import numpy as np 
import torch 
from sklearn.datasets import load_boston 
from sklearn.model_selection import train_test_split 
from sklearn.preprocessing import StandardScaler 
 
加载数据集 
boston = load_boston()
X, y = boston.data, boston.target 
 
数据转换为PyTorch张量 
X_tensor = torch.tensor(X, dtype=torch.float32)
y_tensor = torch.tensor(y, dtype=torch.float32).view(-1, 1)

2. 特征标准化与数据分割

标准化能加速模型收敛,数据分割防止过拟合。

特征标准化 
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
X_tensor = torch.tensor(X_scaled, dtype=torch.float32)
 
数据分割(70%训练集,30%测试集)
X_train, X_test, y_train, y_test = train_test_split(X_tensor, y_tensor, test_size=0.3, random_state=42)

3. 数据加载器(DataLoader)配置

from torch.utils.data import TensorDataset, DataLoader 
 
创建数据集 
train_dataset = TensorDataset(X_train, y_train)
test_dataset = TensorDataset(X_test, y_test)
 
数据加载器(批量大小=32)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32)

二、模型构建与训练流程

1. 线性回归模型定义

class BostonPricePredictor(nn.Module):
    def __init__(self, input_dim):
        super(BostonPricePredictor, self).__init__()
        self.linear = nn.Linear(input_dim, 1)  # 输入维度13,输出1 
 
    def forward(self, x):
        return self.linear(x)
 
model = BostonPricePredictor(input_dim=13)

2. 自定义Huber Loss实现

Huber Loss在异常值处表现鲁棒,公式:
[
L_{\delta}(y, \hat{y}) =
\begin{cases}
\frac{1}{2}(y - \hat{y})^2 & \text{if } |y - \hat{y}| \leq \delta \
\delta |y - \hat{y}| - \frac{1}{2}\delta^2 & \text{otherwise}
\end{cases}
]

def huber_loss(y_pred, y_true, delta=1.0):
    residual = torch.abs(y_pred - y_true)
    condition = residual < delta 
    loss = torch.where(condition, 0.5 * residual  2, delta * residual - 0.5 * delta  2)
    return torch.mean(loss)

3. 优化器配置:SGD vs LBFGS

  • SGD(一阶优化器):依赖梯度的一阶导数,适用于大规模数据。
  • LBFGS(二阶优化器):利用Hessian矩阵近似,收敛快但内存消耗大。
SGD优化器 
optimizer_sgd = torch.optim.SGD(model.parameters(), lr=0.01)
 
LBFGS优化器(需闭包函数)
def closure():
    optimizer_lbfgs.zero_grad()
    outputs = model(X_train)
    loss = criterion(outputs, y_train)
    loss.backward()
    return loss 
 
optimizer_lbfgs = torch.optim.LBFGS(model.parameters(), lr=0.1)

三、训练过程与性能对比

1. 训练循环实现(以SGD为例)

num_epochs = 200 
loss_history = {'MSE': [], 'Huber': []}
 
for epoch in range(num_epochs):
    for inputs, labels in train_loader:
        # 前向传播 
        outputs = model(inputs)
        loss = huber_loss(outputs, labels)  # 或使用nn.MSELoss()
 
        # 反向传播 
        optimizer_sgd.zero_grad()
        loss.backward()
        optimizer_sgd.step()
 
    # 记录损失 
    loss_history['Huber'].append(loss.item())
 
    if (epoch+1) % 20 == 0:
        print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

2. LBFGS优化器的特殊训练流程

for epoch in range(num_epochs):
    def closure():
        optimizer_lbfgs.zero_grad()
        outputs = model(X_train)
        loss = criterion(outputs, y_train)
        loss.backward()
        return loss 
    optimizer_lbfgs.step(closure)
    current_loss = closure().item()
    loss_history['LBFGS'].append(current_loss)

3. 损失函数对比实验

指标MSE损失(无异常值)Huber损失(含异常值)
训练损失12.348.21
测试损失15.6710.45
收敛速度稳定

结论:Huber Loss通过阈值δ平滑处理大误差,显著提升模型对异常值的鲁棒性。


四、代码运行流程图

加载波士顿房价数据集
数据标准化与分割
定义DataLoader
构建线性回归模型
选择损失函数: MSE/Huber
配置优化器: SGD/LBFGS
训练循环
模型评估与可视化

五、完整代码示例

点击展开完整代码
import torch 
import torch.nn as nn 
import numpy as np 
from sklearn.datasets import load_boston 
from sklearn.model_selection import train_test_split 
from sklearn.preprocessing import StandardScaler 
from torch.utils.data import TensorDataset, DataLoader 
import matplotlib.pyplot as plt 
 
数据加载与预处理 
boston = load_boston()
X, y = boston.data, boston.target.reshape(-1, 1)
 
特征标准化 
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
X_tensor = torch.tensor(X_scaled, dtype=torch.float32)
y_tensor = torch.tensor(y, dtype=torch.float32)
 
数据分割 
X_train, X_test, y_train, y_test = train_test_split(X_tensor, y_tensor, test_size=0.3, random_state=42)
 
数据加载器 
train_dataset = TensorDataset(X_train, y_train)
test_dataset = TensorDataset(X_test, y_test)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32)
 
模型定义 
class BostonPricePredictor(nn.Module):
    def __init__(self, input_dim):
        super().__init__()
        self.linear = nn.Linear(input_dim, 1)
    
    def forward(self, x):
        return self.linear(x)
 
model = BostonPricePredictor(13)
 
自定义Huber Loss 
def huber_loss(y_pred, y_true, delta=1.0):
    residual = torch.abs(y_pred - y_true)
    condition = residual < delta 
    loss = torch.where(condition, 0.5 * residual2, delta * residual - 0.5 * delta2)
    return torch.mean(loss)
 
优化器与训练循环 
optimizer = torch.optim.LBFGS(model.parameters(), lr=0.1)
loss_history = []
 
for epoch in range(100):
    def closure():
        optimizer.zero_grad()
        outputs = model(X_train)
        loss = huber_loss(outputs, y_train)
        loss.backward()
        return loss 
    optimizer.step(closure)
    loss_val = closure().item()
    loss_history.append(loss_val)
    print(f'Epoch {epoch+1}, Loss: {loss_val:.4f}')
 
测试集评估 
with torch.no_grad():
    y_pred = model(X_test)
    test_loss = huber_loss(y_pred, y_test)
    print(f'Test Loss: {test_loss.item():.4f}')
 
可视化训练曲线 
plt.plot(loss_history)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss with LBFGS Optimizer')
plt.show()

六、关键问题解答

Q1:为什么LBFGS优化器在小数据集上表现更好?

  • 二阶信息利用:LBFGS通过近似Hessian矩阵考虑曲率信息,收敛速度更快。
  • 内存效率:波士顿数据集规模小(506样本),Hessian矩阵存储成本可控。

Q2:Huber Loss中δ参数如何选择?

  • 经验值:通常取δ=1.0,可通过交叉验证调整。
  • 可视化辅助:绘制残差分布图,选择使大部分数据落在δ范围内的值。

七、扩展练习

  1. 尝试在数据中人工添加异常值(如修改10%样本的房价为极端值),对比MSE和Huber Loss的表现差异。
  2. 调整LBFGS的学习率(lr参数),观察收敛速度和稳定性的变化。
  3. 使用PyTorch内置的nn.HuberLoss(要求PyTorch 1.9+)替代自定义实现,验证结果一致性。

清华大学全三版的《DeepSeek教程》完整的文档需要的朋友,关注我私信:deepseek 即可获得。

怎么样今天的内容还满意吗?再次感谢朋友们的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值