#python #deep-learning #pytorch #lstm #softmax
#python #глубокое обучение #pytorch #lstm #softmax
Вопрос:
Я пытался самостоятельно освоить основы RNN с помощью личного проекта на PyTorch. Я хочу создать простую сеть, которая способна предсказывать следующий символ в последовательности (идея в основном из этой статьиhttp://karpathy.github.io/2015/05/21/rnn-effectiveness / но я хотел сделать большую часть материала сам).
Моя идея заключается в следующем: я беру пакет из B входных последовательностей размером n (np массив из n целых чисел), одним горячим способом кодирую их и пропускаю через свою сеть, состоящую из нескольких слоев LSTM, одного полностью подключенного слоя и одного модуля softmax. Затем я сравниваю вывод с целевыми последовательностями, которые являются входными последовательностями, сдвинутыми на шаг вперед.
Моя проблема в том, что когда я включаю слой softmax, вывод одинаков в каждую отдельную эпоху для каждого отдельного пакета. Когда я его не включаю, сеть, похоже, обучается соответствующим образом. Я не могу понять, что не так.
Моя реализация заключается в следующем :
class Model(nn.Module):
def __init__(self, one_hot_length, dropout_prob, num_units, num_layers):
super().__init__()
self.LSTM = nn.LSTM(one_hot_length, num_units, num_layers, batch_first = True, dropout = dropout_prob)
self.dropout = nn.Dropout(dropout_prob)
self.fully_connected = nn.Linear(num_units, one_hot_length)
self.softmax = nn.Softmax(dim = 1)
# dim = 1 as the tensor is of shape (batch_size*seq_length, one_hot_length) when entering the softmax unit
def forward_pass(self, input_seq, hc_states):
output, hc_states = self.LSTM (input_seq, hc_states)
output = output.view(-1, self.num_units)
output = self.fully_connected(output)
# I simply comment out the next line when I run the network without the softmax layer
output = self.softmax(output)
return output, hc_states
one_hot_length — это размер моего словаря символов (~ 200, также размер одного вектора с горячим кодированием)
num_units — это количество скрытых блоков в ячейке LSTM, num_layers — количество уровней LSTM в сети.
Внутренняя часть цикла обучения (упрощенная) выглядит следующим образом :
input, target = next_batches(data, batch_pointer)
input = nn.functional.one_hot(input_seq, num_classes = one_hot_length).float().
for state in hc_states:
state.detach_()
optimizer.zero_grad()
output, states = net.forward_pass(input, hc_states)
loss = nn.CrossEntropyLoss(output, target)
loss.backward()
nn.utils.clip_grad_norm_(net.parameters(), MaxGradNorm)
optimizer.step()
С hc_states кортежем с тензором скрытых состояний и тензором состояний ячеек, входным является тензор размера (B,n,one_hot_length), целевой является (B,n).
Я тренируюсь на действительно небольшом наборе данных (предложения в формате .txt размером ~ 400 КБ), просто чтобы настроить свой код, и выполнил 4 разных запуска с разными параметрами, и каждый раз результат был одинаковым: сеть вообще не обучается, когда у нее есть слой softmax, и тренируется несколько адекватно без него. Я не думаю, что это проблема с тензорными формами, поскольку я почти уверен, что я все проверил.
Мое понимание моей проблемы заключается в том, что я пытаюсь выполнить классификацию, и что обычно нужно поместить единицу softmax в конец, чтобы получить «вероятности» появления каждого символа, но, очевидно, это неправильно.
Есть идеи, которые могут мне помочь? Я также довольно новичок в Pytorch и RNN, поэтому заранее приношу извинения, если моя архитектура / реализация покажется знающему человеку каким-то чудовищем. Не стесняйтесь поправлять меня и заранее благодарите.
Комментарии:
1.
nn.CrossEntropyLoss
Сначала меня тоже смутил. Одновременно выполняется logSoftmax и потеря вероятности отрицательного логарифма, поэтому softmax является избыточным. pytorch.org/docs/stable/generated /…2. О, хорошо, спасибо, я думаю, я должен был более тщательно прочитать документацию. Я думаю, мне это не нужно для моего прямого прохождения. Однако я все еще не до конца понимаю это, потому что, когда я печатаю вывод моего прямого прохода (поэтому, прежде чем вычислять потери) Я ясно вижу, что вывод тот же. Есть ли у вас какие-либо идеи, почему добавление слоя softmax после слоя FC может вызвать такую проблему? Большое вам спасибо в любом случае