Потеря GRU уменьшилась до 0,9, но не дальше, PyTorch

#python #deep-learning #pytorch #lstm #recurrent-neural-network

#python #глубокое обучение #pytorch #lstm #рекуррентная нейронная сеть

Вопрос:

код, который я использую для экспериментов с GRU.

 import torch
import torch.nn as nn
import torch.nn.functional as F 

from collections import *


class N(nn.Module):
    def __init__(self):
        super().__init__()


        self.embed = nn.Embedding(5,2)

        self.layers = 4
        self.gru = nn.GRU(2, 512, self.layers, batch_first=True)
        self.bat = nn.BatchNorm1d(4)
        self.bat1 = nn.BatchNorm1d(4)
        self.bat2 = nn.BatchNorm1d(4)
        self.fc = nn.Linear(512,100)
        self.fc1 = nn.Linear(100,100)
        self.fc2 = nn.Linear(100,5)
        self.s = nn.Softmax(dim=-1)
    
    def forward(self,x):
        h0 = torch.zeros(self.layers, x.size(0), 512).requires_grad_()

        x = self.embed(x)

        x,hn = self.gru(x,h0)
        x  = self.bat(x)
        x = self.fc(x)
        x = nn.functional.relu(x)

        x = self.bat1(x)
        x = self.fc1(x)
        x = nn.functional.relu(x)

        x = self.bat2(x)
        x  = self.fc2(x)
        softmaxed = self.s(x)
        return  softmaxed


inp = torch.tensor([[4,3,2,1],[2,3,4,1],[4,1,2,3],[1,2,3,4]])
out = torch.tensor([[3,2,1,4],[3,2,4,1],[1,2,3,4],[2,3,4,1]])
k = 0
n = N()
opt = torch.optim.Adam(n.parameters(),lr=0.0001)

while k<10000:
    print(inp.shape)
    o = n(inp)

    o = o.view(-1, o.size(-1))
    out = out.view(-1)
    loss = nn.functional.cross_entropy(o.view(-1,o.size(-1)),out.view(-1)-1)

    acc = ((torch.argmax(o, dim=1) == (out -1)).sum().item() / out.size(0))
    if k==10000:
        print(torch.argmax(o, dim=1))
        print(out-1)
        exit()

    print(loss,acc)
    loss.backward()
    opt.step()
    opt.zero_grad()
    k =1
print(o[0])
  

Уменьшенный вывод:

 torch.Size([4, 4])
tensor(0.9593, grad_fn=<NllLossBackward>) 0.9375
torch.Size([4, 4])
tensor(0.9593, grad_fn=<NllLossBackward>) 0.9375
tensor([4.8500e-01, 9.7813e-06, 5.1498e-01, 6.2428e-06, 7.5929e-06],
       grad_fn=<SelectBackward>)
  

Потеря составляет 0,9593, а точность достигла 0,9375. Для этих простых входных данных потеря GRU такая большая. В чем причина? Что-то не так в этом коде? Я использовал cross_entropy в качестве функции потерь и Adam в качестве оптимизатора. Скорость обучения составляет 0,001. Я пробовал несколько скоростей обучения, но все они давали одинаковый конечный результат. Я добавил пакетную нормализацию, это ускорило обучение, но те же потери и точность. Почему потери не уменьшаются до 0,2 или что-то в этом роде.

Ответ №1:

Я думаю, это потому, что вы используете функцию потери перекрестной энтропии, которая в PyTorch сочетает в себе логарифмическую мягкость и отрицательную логарифмическую вероятность. Поскольку ваша модель уже выполняет softmax перед возвратом выходных данных, вы фактически в конечном итоге вычисляете вероятность отрицательного логарифма для softmax softmax . Попробуйте удалить окончательный softmax из вашей модели.

Документация PyTorch для потери перекрестной энтропии: https://pytorch.org/docs/stable/nn.functional.html#cross-entropy