Как изменить формат веса LSTMCell с tensorflow на tf.keras

У меня есть старый код из tensorflow, который я хочу использовать для tensorflow2 / tf.keras. Я хотел бы сохранить те же веса LSTM, но не могу понять, как преобразовать формат.

У меня есть старые веса, сохраненные в файле контрольной точки, а также они сохранены в файлах csv.

Мой старый код выглядит примерно так:

input_placeholder = tf.placeholder(tf.float32, [None, None, input_units])
lstm_layers = [tf.nn.rnn_cell.LSTMCell(layer_size), tf.nn.rnn_cell.LSTMCell(layer_size)]
stacked = tf.contrib.rnn.MultiRNNCell(lstm_layers)
features, state = tf.nn.dynamic_rnn(stacked, input_placeholder, dtype=tf.float32)

И мой новый код выглядит примерно так:

input_placeholder = tf.placeholder(tf.float32, [None, None, input_units])
lstm_layers = [tf.keras.layers.LSTMCell(layer_size),tf.keras.layers.LSTMCell(layer_size)]
stacked = tf.keras.layers.StackedRNNCells(lstm_layers)
features = stacked(input_placeholder)
... #later in the code
features.set_weights(previous_weights)

Старое предубеждение похоже соответствует новому предубеждению. Старое ядро, похоже, представляет собой соединение ядра и повторяющегося ядра. Я могу загрузить предыдущие_весы в модель (явно проверил, правильно ли загружены веса), однако тесты, которые у меня не были, дают такой же результат. Копаясь в исходном коде, кажется, что у ядер под капотом другой формат.

Можно ли рассчитать ядро ​​и recurrent_kernel (tf.keras), используя эти старые сохраненные веса ядра?

Ссылки, если они полезны:

https://github.com/tensorflow/tensorflow/blob/r1.13/tensorflow/python/ops/rnn_cell_impl.py

https://github.com/tensorflow/tensorflow/blob/r1.13/tensorflow/python/keras/layers/recurrent.py.


person 9mpT9g    schedule 11.06.2019    source источник


Ответы (1)


Вы можете разделить матрицу:

Если вы видите здесь , матрица ядра TF1 имеет вид (input_shape[-1], self.units).

Допустим, у вас есть 20 входов и 128 узлов на уровне LSTM.

input_units=20
layer_size = 128
input_placeholder = tf.placeholder(tf.float32, [None, None, input_units])
lstm_layers = [tf.nn.rnn_cell.LSTMCell(layer_size),     tf.nn.rnn_cell.LSTMCell(layer_size)]
stacked = tf.contrib.rnn.MultiRNNCell(lstm_layers)
output, state = tf.nn.dynamic_rnn(stacked, input_placeholder, dtype=tf.float32)

Ваши обучаемые параметры будут иметь следующие формы:

[<tf.Variable 'rnn/multi_rnn_cell/cell_0/lstm_cell/kernel:0' shape=(148, 512) dtype=float32_ref>,
 <tf.Variable 'rnn/multi_rnn_cell/cell_0/lstm_cell/bias:0' shape=(512,) dtype=float32_ref>,
 <tf.Variable 'rnn/multi_rnn_cell/cell_1/lstm_cell/kernel:0' shape=(256, 512) dtype=float32_ref>,
 <tf.Variable 'rnn/multi_rnn_cell/cell_1/lstm_cell/bias:0' shape=(512,) dtype=float32_ref>]

В TF 1.0 ядро ​​и рекуррентное ядро ​​TF 2.0 объединены (см. здесь)

def build(self, input_shape):
    self.kernel = self.add_weight(shape=(input_shape[-1], self.units),
                              initializer='uniform',
                              name='kernel')
   self.recurrent_kernel = self.add_weight(
    shape=(self.units, self.units),
    initializer='uniform',
    name='recurrent_kernel')
    self.built = True

В этой новой версии у вас есть две разные весовые матрицы.

input_placeholder = tf.placeholder(tf.float32, [None, None, input_units])
lstm_layers = [tf.keras.layers.LSTMCell(layer_size),tf.keras.layers.LSTMCell(layer_size)]
stacked = tf.keras.layers.StackedRNNCells(lstm_layers)
output = tf.keras.layers.RNN(stacked, return_sequences=True, return_state=True, dtype=tf.float32)

Таким образом, ваши обучаемые параметры:

<tf.Variable 'rnn_1/while/stacked_rnn_cells_1/kernel:0' shape=(20, 512) dtype=float32>,
<tf.Variable 'rnn_1/while/stacked_rnn_cells_1/recurrent_kernel:0' shape=(128, 512) dtype=float32>,
<tf.Variable 'rnn_1/while/stacked_rnn_cells_1/bias:0' shape=(512,) dtype=float32>,
<tf.Variable 'rnn_1/while/stacked_rnn_cells_1/kernel_1:0' shape=(128, 512) dtype=float32>,
<tf.Variable 'rnn_1/while/stacked_rnn_cells_1/recurrent_kernel_1:0' shape=(128, 512) dtype=float32>,
<tf.Variable 'rnn_1/while/stacked_rnn_cells_1/bias_1:0' shape=(512,) dtype=float32>]
person ARAT    schedule 11.06.2019
comment
Спасибо за ответ. Я знаю, что старое ядро ​​объединено, однако после отмены объединения я не получаю тех же результатов. - person 9mpT9g; 11.06.2019
comment
что вы имеете в виду, вы не можете получить такие же результаты? то же что? - person ARAT; 11.06.2019
comment
Преобразовываю старый код. Выход rnn отличается. - person 9mpT9g; 11.06.2019