ОК, так что, кажется, единственный способ достичь этого - определить стек экземпляров GRU Layer. Вот что я придумал (обратите внимание, что мне нужны только слои GRU с сохранением состояния, которые возвращают последовательности, и не нужно состояние возврата последнего слоя):
class RNN(tf.keras.layers.Layer):
def __init__(self, dim, num_layers=1):
super(RNN, self).__init__()
self.dim = dim
self.num_layers = num_layers
def layer():
return tf.keras.layers.GRU(
self.dim,
return_sequences=True,
return_state=True,
stateful=True)
self._layer_names = ['layer_' + str(i) for i in range(self.num_layers)]
for name in self._layer_names:
self.__setattr__(name, layer())
def call(self, inputs):
seqs = inputs
state = None
for name in self._layer_names:
rnn = self.__getattribute__(name)
(seqs, state) = rnn(seqs, state)
return seqs
Необходимо вручную добавить внутренние слои rnn на родительский слой, используя __setattr__
. Кажется, что добавление rnns в список и установка , что в качестве атрибута слоя, не позволит отслеживать внутренние слои родительским слоем (см. this ответ this проблема).
Я надеялся, что это ускорит мою сеть. Тесты на Colab пока не показали никакой разницы, во всяком случае, на самом деле это немного медленнее , чем при использовании прямой RNN, инициализированной списком ячеек GRU. Я думал, что увеличение размера пакета с 10 до 64 может иметь значение, но нет, похоже, что они по-прежнему работают примерно с той же скоростью.
ОБНОВЛЕНИЕ : На самом деле там действительно ли кажется заметным ускорением, но только если я не украшаю свою функцию шага тренировки с tf.function
(у меня есть специальное обучение l oop, я не использую Model.fit
). Небольшое увеличение скорости - возможно, примерно на 33% быстрее при размере партии 96. Гораздо меньший размер партии (от 10 до 20) дает еще большую скорость, около 70%.