You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SKORCH结合PyCaret处理回归问题时目标y维度报错如何解决

PyCaret集成Skorch实现回归任务维度报错修复

问题描述

参考PyCaret+Skorch构建PyTorch神经网络的分类任务示例,将方案迁移到回归场景时触发维度不匹配错误。

复现代码

import pycaret
import numpy as np
import torch.nn as nn
import torch.nn.functional as F
from skorch import NeuralNetRegressor
from sklearn.pipeline import Pipeline
from skorch.helper import DataFrameTransformer
from pycaret.regression import *
from pycaret.datasets import get_data

data = get_data('boston')
target = "medv"

reg1 = setup(data = data, 
            target = target,
            train_size = 0.8,
            fold = 5,
            session_id = 123,
            silent = True)

class RegressorModule(nn.Module):
    def __init__(
            self,
            num_units=100,
            nonlin=F.relu,
    ):
        super(RegressorModule, self).__init__()
        self.num_units = num_units
        self.nonlin = nonlin

        self.dense0 = nn.Linear(14, num_units)
        self.nonlin = nonlin
        self.dense1 = nn.Linear(num_units, 10)
        self.output = nn.Linear(10, 1)

    def forward(self, X, **kwargs):
        X = self.nonlin(self.dense0(X))
        X = F.relu(self.dense1(X))
        X = self.output(X)
        return X

net_regr = NeuralNetRegressor(
    RegressorModule,
    max_epochs=20,
    lr=0.1,
    device='cuda'
)

nn_pipe = Pipeline(
    [
        ("transform", DataFrameTransformer()),
        ("net", net_regr),
    ]
)

skorch_model = create_model(nn_pipe)

报错信息

ValueError: 目标数据不能为1维结构,需为2维格式,第二维度大小需与回归目标数量一致(通常为1),请将目标数据reshape为2维格式(例如y = y.reshape(-1, 1))。

手动验证结果

手动完成数据归一化、目标维度调整预处理后,直接传入Skorch训练可正常运行,对应代码如下:

X = data.copy().to_numpy().astype(np.float32)
mean = X.mean(axis=0)
X -= mean
std = X.std(axis=0)
X /= std

y = data[target].to_numpy().astype(np.float32)
y = y.reshape(-1, 1)
net_regr.fit(X, y)

运行效果截图:
运行成功截图

问题根因

PyCaret内部基于DataFrame格式存储训练数据,传入Skorch转换为PyTorch可用张量时,目标值y始终保持1维结构。该结构适配分类任务的输入要求,但Skorch的NeuralNetRegressor强制要求y为2维格式,因此触发报错。

解决方案

不需要修改PyCaret内部处理逻辑,通过子类化原生Skorch回归器增加维度自动适配逻辑即可解决问题,同时修正原代码中输入层维度的错误(波士顿房价数据集特征数为13,原代码误写为14)。

修复后完整可运行代码

import numpy as np
import torch.nn as nn
import torch.nn.functional as F
from skorch import NeuralNetRegressor
from sklearn.pipeline import Pipeline
from skorch.helper import DataFrameTransformer
from pycaret.regression import *
from pycaret.datasets import get_data

# 适配PyCaret输入格式的Skorch回归器补丁类
class SkorchRegressorAdaptor(NeuralNetRegressor):
    def fit(self, X, y, **fit_params):
        # 将PyCaret传入的1维y转为2维float32格式,满足Skorch输入要求
        y = y.to_numpy().astype(np.float32).reshape(-1, 1)
        return super().fit(X, y, **fit_params)
    
    def predict(self, X):
        # 将模型输出的2维预测结果转为1维,适配PyCaret评估逻辑
        y_pred = super().predict(X)
        return y_pred.flatten()

data = get_data('boston')
target = "medv"

reg1 = setup(data = data, 
            target = target,
            train_size = 0.8,
            fold = 5,
            session_id = 123,
            silent = True)

class RegressorModule(nn.Module):
    def __init__(
            self,
            num_units=100,
            nonlin=F.relu,
    ):
        super(RegressorModule, self).__init__()
        self.num_units = num_units
        self.nonlin = nonlin
        # 修正输入维度:数据集共13个数值特征
        self.dense0 = nn.Linear(13, num_units)
        self.dense1 = nn.Linear(num_units, 10)
        self.output = nn.Linear(10, 1)

    def forward(self, X, **kwargs):
        X = self.nonlin(self.dense0(X))
        X = F.relu(self.dense1(X))
        X = self.output(X)
        return X

net_regr = SkorchRegressorAdaptor(
    RegressorModule,
    max_epochs=20,
    lr=0.1,
    device='cuda',
    # 关闭Skorch自带的训练集拆分,完全使用PyCaret的交叉验证逻辑
    train_split=None
)

nn_pipe = Pipeline(
    [
        ("transform", DataFrameTransformer()),
        ("net", net_regr),
    ]
)

skorch_model = create_model(nn_pipe)

关键修复点说明

  • 自定义SkorchRegressorAdaptor继承原生NeuralNetRegressor:重写fit方法自动完成目标y的维度转换,重写predict方法将输出转换回PyCaret兼容的1维格式,全程不需要侵入修改PyCaret内部流程
  • 修正神经网络第一层输入维度为13,匹配波士顿房价数据集的实际特征数量,避免矩阵乘法维度不匹配错误
  • 增加train_split=None参数,禁用Skorch自带的内部验证集拆分,完全使用PyCaret的交叉验证拆分规则,避免数据泄露

内容的提问来源于stack exchange,提问作者user1910714

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 11:33:15