2

我已经扩展nn.Module以实现我的网络,其转发功能是这样的......

def forward(self, X, **kwargs):

    batch_size, seq_len = X.size()

    length = kwargs['length']
    embedded = self.embedding(X) # [batch_size, seq_len, embedding_dim]
    if self.use_padding:
        if length is None:
            raise AttributeError("Length must be a tensor when using padding")
        embedded = nn.utils.rnn.pack_padded_sequence(embedded, length, batch_first=True)
        #print("Size of Embedded packed", embedded[0].size())


    hidden, cell = self.init_hidden(batch_size)
    if self.rnn_unit == 'rnn':
        out, _ = self.rnn(embedded, hidden)
    elif self.rnn_unit == 'lstm':
        out, (hidden, cell) = self.rnn(embedded, (hidden, cell))


    # unpack if padding was used
    if self.use_padding:
        out, _ = nn.utils.rnn.pad_packed_sequence(out, batch_first = True)

我像这样初始化了一个skorch NeuralNetClassifier

net = NeuralNetClassifier(
    model,
    criterion=nn.CrossEntropyLoss,
    optimizer=Adam, 
    max_epochs=8, 
    lr=0.01, 
    batch_size=32
)

现在,如果我调用net.fit(X, y, length=X_len)它会引发错误

TypeError: __call__() got an unexpected keyword argument 'length'

根据文档 fit 函数需要一个fit_params字典,

**fit_params : dict
   Additional parameters passed to the ``forward`` method of
   the module and to the ``self.train_split`` call.

并且源代码总是将我的参数发送到train_split显然我的关键字参数不会被识别的地方。

有没有办法将参数传递给我的转发函数?

4

1 回答 1

1

fit_params参数旨在传递与数据拆分和模型类似的信息,例如拆分组。

在您的情况下,您将额外的数据传递给模块,fit_params这不是它的用途。事实上,如果你在训练数据加载器上启用批量改组,那么你很容易在这样做时遇到麻烦,因为那时你的长度和数据没有对齐。

执行此操作的最佳方法已在问题跟踪器上对您的问题的回答中进行了描述:

X_dict = {'X': X, 'length': X_len}
net.fit(X_dict, y)

由于 skorch 支持dicts 您可以简单地将长度添加到您的输入 dict 并将其都传递给模块,很好地批处理并通过相同的数据加载器。在您的模块中,您可以通过以下参数访问它forward

def forward(self, X, length):
     return ...

可以在 docs中找到有关此行为的更多文档。

于 2019-03-27T10:26:49.297 回答