首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FastAi LSTM正向方法问题

FastAi LSTM正向方法问题
EN

Stack Overflow用户
提问于 2019-11-24 06:49:50
回答 1查看 135关注 0票数 0

试图创建一个简单的LSTM模型并使用FastAI框架,但失败了。

代码语言:javascript
复制
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模块初始化它时,它失败了。

它抱怨数据的形状是错误的。这里是完整的代码

代码语言:javascript
复制
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,)参数?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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]时,你会发现

代码语言:javascript
复制
TabularLine d -0.4334; e 1.3458; a 0.4151; c 0.2837; b -0.6355;

data.train_ds.x[0].data产量:

代码语言:javascript
复制
[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)形状的张量,这也是非常有用的。

例如,添加:

代码语言:javascript
复制
custom_collate_fn = lambda b: data_collate([(x.data[1], y) for (x, y) in b])

并且在数据库创建中传递collate_fn=custom_collate_fn将有效。但是,您稍后会得到一个错误,因为您有200项,并且您的模型只有在批处理大小为64的情况下才能工作。如果你在那件事上需要帮助,请告诉我。

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

https://stackoverflow.com/questions/59015337

复制
相关文章

相似问题

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