我扩展了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,在那里我的关键字参数显然无法被识别。

有什么办法可以将参数传递给我的转发函数吗?

最佳答案

fit_params参数用于传递与数据拆分和模型(例如拆分组)相关的信息。

在您的情况下,您正在通过fit_params将其他数据传递给该模块,而这并非本来打算的。实际上,例如,如果在火车数据加载器上启用批改组,那么这样做很容易会遇到麻烦,因为那样会导致长度和数据未对齐。

最佳方法已在answer to your question on the issue tracker中进行了描述:

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


由于skorch支持dict,因此您可以简单地将长度添加到输入字典中,然后将其都传递到模块中,进行批量处理并通过同一数据加载器传递。然后,您可以在模块中通过forward中的参数进行访问:

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


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

08-25 05:04