Я пытаюсь сделать LSTM в tenorflow 2.1 с нуля, не используя тот, который уже поставляется с keras (tf.keras.layers.LSTM), только для того, чтобы что-то изучать и кодировать. Для этого я определил класс «Модель», который при вызове (например, с model(input)
) вычисляет умножения матриц LSTM. Я вставляю сюда часть своего кода, остальные части находятся на github ( ссылка )
class Model(object):
[...]
def __call__(self, inputs):
assert inputs.shape == (vocab_size, T_steps)
outputs = []
for time_step in range(T_steps):
x = inputs[:,time_step]
x = tf.expand_dims(x,axis=1)
z = tf.concat([self.h_prev,x],axis=0)
f = tf.matmul(self.W_f, z) + self.b_f
f = tf.sigmoid(f)
i = tf.matmul(self.W_i, z) + self.b_i
i = tf.sigmoid(i)
o = tf.matmul(self.W_o, z) + self.b_o
o = tf.sigmoid(o)
C_bar = tf.matmul(self.W_C, z) + self.b_C
C_bar = tf.tanh(C_bar)
C = (f * self.C_prev) + (i * C_bar)
h = o * tf.tanh(C)
v = tf.matmul(self.W_v, h) + self.b_v
v = tf.sigmoid(v)
y = tf.math.softmax(v, axis=0)
self.h_prev = h
self.C_prev = C
outputs.append(y)
outputs = tf.squeeze(tf.stack(outputs,axis=1))
return outputs
Но у этой нейронной сети есть три проблемы:
1) во время тренировок это очень медленно. Для сравнения, модель, использующая tf.keras.layers.LSTM (), обучается более чем в 10 раз быстрее. Почему это? Может быть, потому, что я не использовал обучение мини-пакет, а стохастический c один?
2) Кажется, NN вообще ничего не изучает. После всего лишь нескольких (очень немногих!) Обучающих примеров потеря, похоже, уляжется и больше не будет уменьшаться, а скорее колеблется вокруг достигнутого значения. После обучения я протестировал NN, заставляя его генерировать некоторый текст, но он просто выводит бессмысленные гиббери sh. Почему ничего не изучает?
3) функция потерь выдает очень высокие значения. Я закодировал категорическую функцию кросс-энтропийной потери, но с длиной последовательности 100 символов значение функции превышает 370 в каждом обучающем примере. Разве это не должно быть намного ниже, чем это?
Я написал функцию потерь следующим образом:
def compute_loss(predictions, desired_outputs):
l = 0
for i in range(T_steps):
l -= tf.math.log(predictions[desired_outputs[i], i])
return l
Я знаю, что это открытые вопросы, но, к сожалению, я не могу сделать оно работает. Таким образом, любой ответ, даже короткий, который поможет мне решить проблему, вполне подойдет:)