【问题标题】:The same output value whatever is the input value for a Pytorch LSTM regression modelPytorch LSTM 回归模型的输入值是相同的输出值
【发布时间】:2021-12-26 02:25:46
【问题描述】:

我的数据集如下所示:

左边是我的输入,右边是输出。 输入被标记化并转换为索引列表,例如分子输入: 'CC1(C)Oc2ccc(cc2C@HN3CCCC3=O)C#N' 转换为:

[28, 28, 53, 69, 28, 70, 40, 2, 54, 2, 2, 2, 69, 2, 2, 54, 67, 28, 73, 33, 68, 69, 67, 28, 73, 73, 33, 68, 53, 40, 70, 39, 55, 28, 28, 28, 28, 55, 62, 40, 70, 28, 63, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

我使用以下字符列表作为从字符串到索引的映射

cs = ['a','b','c','d','e','f','g','h','i','j','k', 'l','m','n','o','p','q','r','s','t','u','v','w','x ','y','z','A','B','C','D','E','F','G','H','I','J', 'K','L','M','N','O','P','Q','R','S','T','U','V','W ','X','Y','Z', '0','1','2','3','4','5','6','7','8','9', '=','#',':','+','-','[',']','(',')','/','\'
, '@','.','%']

因此,对于输入字符串中的每个字符,都有一个索引,如果输入字符串的长度小于所有输入的最大长度 100,我用零补足。 (如上图所示)

我的模型如下所示:

class LSTM_regr(torch.nn.Module) :
    def __init__(self, vocab_size, embedding_dim, hidden_dim) :
        super().__init__()
        self.embeddings = nn.Embedding(vocab_size, embedding_dim, padding_idx=0)
        self.lstm = nn.LSTM(embedding_dim, hidden_dim, batch_first=True)
        self.linear = nn.Linear(hidden_dim, 1)
        self.dropout = nn.Dropout(0.2)  
        
    def forward(self, x, l):
        x = self.embeddings(x)
        x = self.dropout(x)
        lstm_out, (ht, ct) = self.lstm(x)
        return self.linear(ht[-1])
vocab_size = 76
model =  LSTM_regr(vocab_size, 20, 256)

我的问题是,在训练之后,我给模型进行测试的每个输入都给了我相同的输出(即 3.3318)。这是为什么呢?

我的训练循环:

def train_model_regr(model, epochs=10, lr=0.001):
    parameters = filter(lambda p: p.requires_grad, model.parameters())
    optimizer = torch.optim.Adam(parameters, lr=lr)
    for i in range(epochs):
        model.train()
        sum_loss = 0.0
        total = 0
        for x, y, l in train_dl:
            x = x.long()
            y = y.float()
            y_pred = model(x, l)
            optimizer.zero_grad()
            loss = F.mse_loss(y_pred, y.unsqueeze(-1))
            loss.backward()
            optimizer.step()
            sum_loss += loss.item()*y.shape[0]
            total += y.shape[0]

编辑:

我想通了,我将学习率从 0.01 降低到 0.0005,并将批量大小从 100 降低到 10,效果很好。

我认为这是有道理的,模型是在大批量上训练的,因此它一直在学习输出平均值,因为这就是损失函数的作用。

【问题讨论】:

    标签: pytorch regression lstm recurrent-neural-network


    【解决方案1】:

    您的LSTM_regr 返回最后一个隐藏状态无论真实序列长度如何。也就是说,如果你的真实序列长度为 3,x 的长度为 100,输出为处理 97 个填充元素后的最后一个隐藏状态。

    您应该计算与每个序列的真实长度相匹配的预测损失。

    【讨论】:

      【解决方案2】:

      我想通了,我将学习率从 0.01 降低到 0.0005,并将批量大小从 100 降低到 10,效果很好。

      我认为这是有道理的,模型在大批量上进行训练,因此它一直在学习输出平均值,因为这就是损失函数的作用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-09
        • 2021-04-25
        • 2018-03-25
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        • 2017-09-21
        • 2019-08-19
        相关资源
        最近更新 更多