Понимание softmax выходного слоя RNN - PullRequest
0 голосов
/ 26 ноября 2018

Вот простая модель LSTM в Keras:

input = Input(shape=(max_len,))
model = Embedding(input_dim=input_dim, output_dim=embed_dim, input_length=max_len)(input)
model = Dropout(0.1)(model)
model = Bidirectional(LSTM(units=blstm_dim, return_sequences=True, recurrent_dropout=0.1))(model)
out =Dense(label_dim, activation="softmax")(model)

Вот моя попытка перевести ее на модель Pytorch:

class RNN(nn.Module):
    def __init__(self, input_dim, embed_dim, blstm_dim, label_dim):
        super(RNN, self).__init__()
        self.embed = nn.Embedding(input_dim, embed_dim)
        self.blstm = nn.LSTM(embed_dim, blstm_dim,  bidirectional=True, batch_first=True)
        self.fc = nn.Linear(2*blstm_dim, label_dim)


    def forward(self, x):
        h0 = torch.zeros(2, x.size(0), blstm_dim).to(device) 
        c0 = torch.zeros(2, x.size(0), blstm_dim).to(device)
        x = self.embed(x)
        x = F.dropout(x, p=0.1, training=self.training)
        x,_ = self.blstm(x, (h0, c0))
        x = self.fc(x)
        return F.softmax(x, dim=1)
#        return x

Теперь запуск модели Keras дает следующее:

Epoch 5/5
38846/38846 [==============================] - 87s 2ms/step - loss: 0.0374 - acc: 0.9889 - val_loss: 0.0473 - val_acc: 0.9859

Но использование модели PyTorch дает следующее:

Train Epoch: 10/10 [6400/34532 (19%)]   Loss: 2.788933
Train Epoch: 10/10 [12800/34532 (37%)]  Loss: 2.788880
Train Epoch: 10/10 [19200/34532 (56%)]  Loss: 2.785547
Train Epoch: 10/10 [25600/34532 (74%)]  Loss: 2.796180
Train Epoch: 10/10 [32000/34532 (93%)]  Loss: 2.790446
Validation: Average loss: 0.0437, Accuracy: 308281/431600 (71%)

Я убедился, что потери и оптимизатор одинаковы (кросс-энтропия и RMSprop).Теперь интересно, если я удаляю softmax из модели PyTorch (т.е. использую хешированный вывод в коде, я получаю то, что кажется правильным:

Train Epoch: 10/10 [32000/34532 (93%)]  Loss: 0.022118
Validation: Average loss: 0.0009, Accuracy: 424974/431600 (98%)

Итак, вот мои вопросы:

1) Являются ли две модели, которые я напечатал выше, эквивалентными (давайте проигнорируем recurrent_dropout, так как я не выяснил, как это сделать в PyTorch)?

2) Что я делаю неправильно с выходным слоем softmaxв PyTorch?

Спасибо большое!

1 Ответ

0 голосов
/ 26 ноября 2018
  1. Являются ли две модели, которые я напечатал выше, эквивалентными (давайте проигнорируем recurrent_dropout, так как я не понимаю, как это сделать в PyTorch)?

Кроме отсева, я не вижу никакой разницы.Таким образом, они должны быть полностью эквивалентны с точки зрения структуры.

Одно примечание: вам не нужно инициализировать состояния, если вы используете их таким образом (если вы не используете их повторно).Вы можете просто переслать LSTM с помощью x,_ = self.blstm(x) - он автоматически инициализирует состояния с нулями.

Что я делаю не так с выходным слоем softmax в PyTorch?

PyTorch torch.nn.CrossEntropyLoss уже включает softmax:

Этот критерий объединяет nn.LogSoftmax() и nn.NLLLoss() в одном классе.

Таким образом, это фактически CE с логитами.Я думаю, это делает его более эффективным.Таким образом, вы можете просто пропустить активацию softmax в конце.

...