python - PyToch Skorch 传递 3 维输入
问题描述
我试图在使用 skorch 时在 PyTorch 中拟合模型。我的问题是,我的模型使用 LSTM 层,它需要 3d 输入,但我不知道如何正确传递输入。
将 2d 数组传递给fit()
我从 PyTorch 收到预期 3d 输入的错误。如果传递一个 3d 数组,我会从fit()
长度不一致的方法中得到错误(这对我来说都很有意义)。
下面的示例代码:
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)
:
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)
:
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.
解决方案
正如您自己所说,传递 2D 数组是行不通的,因为那时您没有时间维度,因此在这种情况下错误消息是正确的(LSTM 需要 3 个维度)。
令人困惑的部分是传递 3D 数组时的错误消息。正在发生的事情是您将数据格式化为(sequence, batch, feature)
,即“第二批”。有一种替代格式称为“batch first”,其中数据被格式化为(batch, sequence, feature)
sklearn 中的默认格式(因此在 skorch 中)。如果您以这种方式重新格式化数据并将 LSTM 配置为使用这种格式(通过batch_first=True
),错误应该会消失:
self.rnn = nn.LSTM(
input_size,
hidden_size,
num_layers,
batch_first=True,
)
# ...
inputArr3d = np.random.rand(batch, seq, features)
请注意,您的模块还需要将 RNN 的返回值转换为后续层可以处理的内容(即展平时间维度),否则线性层将不知道如何处理额外的时间维度。
推荐阅读
- php - 使用 AWS PHP SDK 获取 403 禁止执行 API Gateway getConnection 或 postToConnection(在 Postman 中工作)
- python - 如何使用 HTML 显示熊猫图表
- python - AWS 上的 jupyter 笔记本
- docker - 通过 docker 运行 Hashicorp vault ui 时无法访问
- r - R:如果记录在特定列上匹配,但在另一列中不同,则删除不同值为 NA 的行
- r - 如何在 R 中添加基于用户 ID 和会话 ID 的平均列?
- r - 对 data.table 使用 i 中变量的字符串表示
- python - 通过 uwsgi 启动 Flask 时没有加载应用程序
- java - Spring Data JPA删除多对多关系问题
- python - 如何使用 Python 将 msdata xml 转换为 ms excel 电子表格