【问题标题】:Loss doesn't decrease in training the pytorch RNN训练 pytorch RNN 的损失没有减少
【发布时间】:2018-04-01 18:25:44
【问题描述】:

这是我为情感设计的 RNN 网络。

class rnn(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super().__init__()
        self.hidden_size = hidden_size
        self.i2h = nn.Linear(input_size, hidden_size)
        self.h2o = nn.Linear(hidden_size, output_size)
        self.h2h = nn.Linear(hidden_size , hidden_size)
        self.relu = nn.Tanh()
        self.sigmoid = nn.LogSigmoid()

    def forward(self, input, hidden):
        hidden_new = self.relu(self.i2h(input)+self.h2h(hidden))
        output = self.h2o(hidden)
        output = self.sigmoid(output)
        return output, hidden_new

    def init_hidden(self):
        return Variable(torch.zeros(1, self.hidden_size))

然后,我创建并训练网络:

RNN = rnn(50, 50, 1)
learning_rate = 0.0005
criteria = nn.MSELoss()
optimizer = optim.Adam(RNN.parameters(), lr=learning_rate)
hidden = RNN.init_hidden()
epochs = 2
for epoch in range(epochs):
    for i in range(len(train['Phrase'])):
        input = convert_to_vectors(train['Phrase'][i])
        for j in range(len(input)):
            temp_input = Variable(torch.FloatTensor(input[j]))
            output, hidden = RNN(temp_input, hidden)
        temp_output = torch.FloatTensor([np.float64(train['Sentiment'][i])/4])
        loss = criteria( output, Variable(temp_output))
        loss.backward(retain_graph = True)
        if (i%20 == 0):
            print('Current loss is ', loss)

问题是网络的损失并没有减少。它增加,然后减少等等。它根本不稳定。我尝试使用较小的学习率,但似乎没有帮助。

为什么会发生这种情况,我该如何纠正?

【问题讨论】:

  • 请问您为什么不简单地使用 torch.nn.RNN ?
  • @ZEWEICHU 我想实现 RNN 表单从头开始。此错误背后的任何原因?
  • 你有LogSigmoidMSELoss,对吗?你能分享更多关于你的数据集的信息吗?提供一个训练示例,以便我们理解。

标签: python machine-learning pytorch rnn


【解决方案1】:

您只需在拨打loss.backward() 后拨打optimizer.step()

顺便说一句,这说明了一个常见的误解:反向传播不是一种学习算法,它只是计算损失 w.r.t 梯度的一种很酷的方法。你的参数。然后,您使用梯度下降的一些变体(例如,普通 SGD、AdaGrad 等,在您的情况下为 Adam)在给定梯度的情况下更新权重。

【讨论】:

    【解决方案2】:

    我认为有些事情可能会给你一些帮助。 首先,在rnn类模块中,最好用"super(rnn,self).__init__()"代替"super().__init__()"

    第二,变量名要和函数一致,最好用"self.tanh = nn.Tanh()"代替"self.relu = nn.Tanh()"。而在rnn中,sigmoid函数应该是1/(1+exp(-x)),而不是logsigmoid函数。您应该使用"self.sigmoid = nn.Sigmoid()" 替换"self.sigmoid = nn.LogSigmoid()"。 第三,如果使用 rnn 进行分类,输出应该由 softmax 函数激活。所以你应该添加两个语句,"self.softmax = nn.Softmax()""output = self.softmax(output)"

    【讨论】:

    • 为什么你更喜欢super(rnn,self).__init__() 而不是super().__init__()
    • 因为我习惯了python2。而super().__init__()在python3中也可以。
    猜你喜欢
    • 2019-08-18
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    • 2018-08-05
    • 2020-02-28
    相关资源
    最近更新 更多