首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将输入模糊从fit方法传递给skorch包装器?

如何将输入模糊从fit方法传递给skorch包装器?
EN

Stack Overflow用户
提问于 2020-01-31 14:22:00
回答 1查看 599关注 0票数 4

我正在尝试将PyTorch功能集成到scikit-learn环境中(特别是管道和GridSearchCV),因此一直在研究skorch。用于神经网络的标准文档示例如下

代码语言:javascript
复制
import torch.nn.functional as F
from torch import nn
from skorch import NeuralNetClassifier

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

        self.dense0 = nn.Linear(20, num_units)
        self.nonlin = nonlin
        self.dropout = nn.Dropout(0.5)
        ...
        ...
        self.output = nn.Linear(10, 2)
    ...
    ...

其中,通过将输入和输出维度硬编码到构造函数中,显式地传递它们。但是,这实际上不是scikit-learn接口的工作方式,fit方法导出输入和输出维度,而不是显式地传递给构造函数。作为一个实例,请考虑

代码语言:javascript
复制
# copied from the documentation
net = NeuralNetClassifier(
    MyModule,
    max_epochs=10,
    lr=0.1,
    # Shuffle training data on each epoch
    iterator_train__shuffle=True,
)

# any general Pipeline interface
pipeline = Pipeline([
        ('transformation', AnyTransformer()),
        ('net', net)
        ])

gs = GridSearchCV(net, params, refit=False, cv=3, scoring='accuracy')
gs.fit(X, y)

除了变压器中没有任何地方必须指定输入和输出维数之外,在模型建立之前应用的变压器可能会改变训练集的维数(考虑降维和相似),因此神经网络构造函数中的硬编码输入和输出是行不通的。

我是否误解了这是如何工作的,或者什么是建议的解决方案(我正在考虑将构造函数指定到forward方法中,在这里您已经可以使用X了,但我不确定这是一个好的实践)?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-11 13:31:42

这是一个非常好的问题,恐怕有最佳实践的答案,因为PyTorch通常是以初始化和执行为独立步骤的方式编写的,这正是您在本例中不想要的。

有几种方法都朝着相同的方向前进,即对输入数据进行内省,在拟合前重新初始化网络。我能想到的最简单的方法是编写一个回调,在训练开始时设置相应的参数:

代码语言:javascript
复制
class InputShapeSetter(skorch.callbacks.Callback):
    def on_train_begin(self, net, X, y):
        net.set_params(module__input_dim=X.shape[-1])

这将在培训开始期间设置一个模块参数,该参数将使用所述参数重新初始化PyTorch模块。这个特定的回调要求第一个层的参数称为input_dim,但是如果需要,可以更改这个参数。

一个完整的例子:

代码语言:javascript
复制
import torch
import skorch
from sklearn.datasets import make_classification
from sklearn.pipeline import Pipeline
from sklearn.decomposition import PCA

X, y = make_classification()
X = X.astype('float32')

class ClassifierModule(torch.nn.Module):
    def __init__(self, input_dim=80):
        super().__init__()
        self.l0 = torch.nn.Linear(input_dim, 10)
        self.l1 = torch.nn.Linear(10, 2)

    def forward(self, X):
        y = self.l0(X)
        y = self.l1(y)
        return torch.softmax(y, dim=-1)


class InputShapeSetter(skorch.callbacks.Callback):
    def on_train_begin(self, net, X, y):
        net.set_params(module__input_dim=X.shape[-1])


net = skorch.NeuralNetClassifier(
    ClassifierModule,
    callbacks=[InputShapeSetter()],
)

pipe = Pipeline([
    ('pca', PCA(n_components=10)),
    ('net', net),
])

pipe.fit(X, y)
print(pipe.predict(X))
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60005715

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档