首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >传递三维输入的PyToch Skorch

传递三维输入的PyToch Skorch
EN

Stack Overflow用户
提问于 2018-06-21 20:38:23
回答 1查看 798关注 0票数 2

我正在尝试在使用skorch的同时在PyTorch中适应一个模型。我的问题是,我的模型使用了一个LSTM层,它需要3d输入,而我不知道如何正确地传递输入。

在向fit()传递2D数组时,对于预期的3d输入,我从PyTorch得到一个错误。如果传递一个3D数组,我会从fit()方法得到长度不一致的错误(这对我来说都很有意义)。

示例代码如下:

代码语言:javascript
复制
import numpy as np
import torch
from torch import nn
import skorch

class lstmNet(nn.Module):

    def __init__(self, input_size, hidden_size, num_layers):
        super(lstmNet, self).__init__()
        self.rnn = nn.LSTM(
            input_size,
            hidden_size,
            num_layers        )
        self.lin = nn.Linear(
            in_features=hidden_size,
            out_features=1
        )

    def forward(self, x):
        print(x.size())
        out, hn = self.rnn(x)
        out = self.lin(out)
        return out


input_feat = 5
hidden_size = 10
lstmLayers = 2

seq = 20
batch = 30
features = 5

net = skorch.NeuralNet(
    module=lstmNet(
        input_size=input_feat,
        hidden_size=hidden_size,
        num_layers=lstmLayers
    ),
    criterion=torch.nn.MSELoss,
    optimizer=torch.optim.SGD,
    lr=0.1,
    max_epochs=10
)

#inputArr2d = np.random.rand(seq * batch, features)
inputArr3d = np.random.rand(seq, batch, features)
print('input:\n {}\nshape: {}'.format(inputArr3d, inputArr3d.shape))
targetArr = np.random.rand((seq * batch))
#print('target:\n {}\nshape: {}'.format(targetArr, targetArr.shape))

net.fit(X=inputArr3d, y=targetArr)

这是调用net.fit(X=inputArr2d, y=targetArr)时的错误

代码语言:javascript
复制
Traceback (most recent call last):
File "C:\Spielplatz\Python\examples\playground.py", line 64, in <module>
net.fit(X=inputArr2d, y=targetArr)
File "C:\ProgramData\Anaconda3\lib\site-packages\skorch\net.py", line 686, in fit
self.partial_fit(X, y, **fit_params)
File "C:\ProgramData\Anaconda3\lib\site-packages\skorch\net.py", line 646, in partial_fit
self.fit_loop(X, y, **fit_params)
File "C:\ProgramData\Anaconda3\lib\site-packages\skorch\net.py", line 584, in fit_loop
step = self.train_step(Xi, yi, **fit_params)
File "C:\ProgramData\Anaconda3\lib\site-packages\skorch\net.py", line 507, in train_step
y_pred = self.infer(Xi, **fit_params)
File "C:\ProgramData\Anaconda3\lib\site-packages\skorch\net.py", line 810, in infer
return self.module_(x, **fit_params)
File "C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py", line 491, in __call__
result = self.forward(*input, **kwargs)
File "C:\Spielplatz\Python\examples\playground.py", line 33, in forward
out, hn = self.rnn(x)
File "C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\module.py", line 491, in __call__
result = self.forward(*input, **kwargs)
File "C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\rnn.py", line 178, in forward
self.check_forward_args(input, hx, batch_sizes)
File "C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\rnn.py", line 126, in check_forward_args
expected_input_dim, input.dim()))
RuntimeError: input must have 3 dimensions, got 2

这是调用net.fit(X=inputArr3d, y=targetArr)时的错误

代码语言:javascript
复制
Traceback (most recent call last):
File "C:\Spielplatz\Python\examples\playground.py", line 64, in <module>
net.fit(X=inputArr3d, y=targetArr)
File "C:\ProgramData\Anaconda3\lib\site-packages\skorch\net.py", line 686, in fit
self.partial_fit(X, y, **fit_params)
File "C:\ProgramData\Anaconda3\lib\site-packages\skorch\net.py", line 646, in partial_fit
self.fit_loop(X, y, **fit_params)
File "C:\ProgramData\Anaconda3\lib\site-packages\skorch\net.py", line 573, in fit_loop
X, y, **fit_params)
File "C:\ProgramData\Anaconda3\lib\site-packages\skorch\net.py", line 1004, in get_split_datasets
dataset = self.get_dataset(X, y)
File "C:\ProgramData\Anaconda3\lib\site-packages\skorch\net.py", line 961, in get_dataset
return dataset(X, y, **kwargs)
File "C:\ProgramData\Anaconda3\lib\site-packages\skorch\dataset.py", line 104, in __init__
raise ValueError("X and y have inconsistent lengths.")
ValueError: X and y have inconsistent lengths.
EN

回答 1

Stack Overflow用户

发布于 2018-06-29 17:20:56

正如您自己所说,传递2D数组是行不通的,因为您没有时间维度,所以在这种情况下错误消息是正确的(LSTM需要3维)。

配置部分是传递3D数组时的错误消息。正在发生的情况是,您正在将数据格式化为(sequence, batch, feature),即"batch second“。还有一种称为"batch first“的替代格式,它将数据格式化为(batch, sequence, feature),这在sklearn中是默认格式(因此在skorch中也是如此)。如果以这种方式重新格式化数据,并将LSTM配置为使用这种格式(传递batch_first=True),则错误应该会消失:

代码语言:javascript
复制
    self.rnn = nn.LSTM(
        input_size,
        hidden_size,
        num_layers,
        batch_first=True,   
    )
# ...
inputArr3d = np.random.rand(batch, seq, features)

请注意,您的模块还需要将RNN的返回值转换为后续层可以处理的内容(例如,展平时间维度),否则线性层将不知道如何处理额外的时间维度。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50968788

复制
相关文章

相似问题

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