试图创建一个简单的LSTM模型并使用FastAI框架,但失败了。
class SimpleLSTM(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim, bs):
super().__init__()
self.input_dim = input_dim
self.hidden_dim = hidden_dim
self.output_dim = output_dim
self.bs = bs
self.lstm = nn.LSTM(self.input_dim, self.hidden_dim)
self.linear = nn.Linear(self.hidden_dim, self.output_dim)
def forward(self, *inputs):
print(f'in[0]: {inputs[0].shape}')
out, self.h = self.lstm(inputs[0].view(1, self.bs, self.input_dim))
y_pred = self.linear(out)
return y_pred[-1]当我将原始数据提供给模型时,这个模块可以工作,但是当我用Learner模块初始化它时,它失败了。
它抱怨数据的形状是错误的。这里是完整的代码
import torch
import torch.nn as nn
import pandas as pd
import fastai
from fastai.tabular import *
size = 200
bs = 20
X = torch.randn(size, 5)
y = (X.T[0] * 1.2 + X.T[1] * 4.2 + X.T[2] * 0.56 + X.T[3] * 0.12 + X.T[4] * 7.2 + torch.randn(size)).view(size, 1)
valid_ratio = 0.2
valid_samples = int(valid_ratio * size)
print(f'X.shape: {X.shape}')
print(f'y.shape: {y.shape}')
df = pd.concat([pd.DataFrame(X.data.numpy()), pd.DataFrame(y.data.numpy())], axis=1)
df.columns = ['a', 'b', 'c', 'd', 'e', 'y']
class SimpleLSTM(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim, bs):
super().__init__()
self.input_dim = input_dim
self.hidden_dim = hidden_dim
self.output_dim = output_dim
self.bs = bs
self.lstm = nn.LSTM(self.input_dim, self.hidden_dim)
self.linear = nn.Linear(self.hidden_dim, self.output_dim)
def forward(self, *inputs):
print(f'in[0]: {inputs[0].shape}')
out, self.h = self.lstm(inputs[0].view(1, self.bs, self.input_dim))
y_pred = self.linear(out)
return y_pred[-1]
model = SimpleLSTM(input_dim=5, hidden_dim=100, output_dim=1, bs=bs)
model
out = model(X[:bs])
print(f'out shape: {out.shape}')
out = model(X[:bs])
print(f'out shape: {out.shape}')
procs = [Normalize]
valid_idx = range(len(df)-valid_samples, len(df))
dep_var = 'y'
data = TabularDataBunch.from_df('.', df, dep_var, valid_idx=valid_idx, procs=procs, bs=bs)
learner = Learner(data, model)
learner.fit_one_cycle(1)我的观察是,FastAI将提供两个参数,一个是形状(Bs ),另一个是形状(bs,input_dim)。为什么它传递(bs,)参数?
发布于 2019-11-26 13:31:22
您的观察是正确的,并且在数据库的collate_function中发生了什么。基本上,当迭代数据器时,所发生的情况是x是data.collate_fn([data.train_ds.x[i] for i in list_indices),其中list_indices是您为这个批处理使用的样本的标记列表。当你看到data.train_ds.x[0]时,你会发现
TabularLine d -0.4334; e 1.3458; a 0.4151; c 0.2837; b -0.6355;data.train_ds.x[0].data产量:
[tensor(0), tensor([-0.4334, 1.3458, 0.4151, 0.2837, -0.6355])]产生这一结果的原因是,fastai中的表格数据处理的是分类变量和连续变量,这是通过使用tabular_learner创建一个特殊的学习者来处理的。
这里有两种解决方案:
data.train_ds.x[i].data成为形状为5的张量。collate_fn以使其返回(bs,input_dim)形状的张量,这也是非常有用的。例如,添加:
custom_collate_fn = lambda b: data_collate([(x.data[1], y) for (x, y) in b])并且在数据库创建中传递collate_fn=custom_collate_fn将有效。但是,您稍后会得到一个错误,因为您有200项,并且您的模型只有在批处理大小为64的情况下才能工作。如果你在那件事上需要帮助,请告诉我。
https://stackoverflow.com/questions/59015337
复制相似问题