Как вы применяете нормализацию слоя в RNN, используя tf.keras? - PullRequest
4 голосов
/ 29 марта 2019

Я хотел бы применить нормализацию слоя к рекуррентной нейронной сети, используя tf.keras.В TensorFlow 2.0 есть класс LayerNormalization в tf.layers.experimental, но неясно, как использовать его в рекуррентном слое, таком как LSTM, на каждом временном шаге (как он был разработан для использования).Должен ли я создать пользовательскую ячейку, или есть более простой способ?

Например, применение отсева на каждом временном шаге так же просто, как установка аргумента recurrent_dropout при создании слоя LSTM, но естьнет recurrent_layer_normalization аргумент.

1 Ответ

1 голос
/ 09 апреля 2019

Вы можете создать собственную ячейку, унаследовав от класса SimpleRNNCell, например:

import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.activations import get as get_activation
from tensorflow.keras.layers import SimpleRNNCell, RNN, Layer
from tensorflow.keras.layers.experimental import LayerNormalization

class SimpleRNNCellWithLayerNorm(SimpleRNNCell):
    def __init__(self, units, **kwargs):
        self.activation = get_activation(kwargs.get("activation", "tanh"))
        kwargs["activation"] = None
        super().__init__(units, **kwargs)
        self.layer_norm = LayerNormalization()
    def call(self, inputs, states):
        outputs, new_states = super().call(inputs, states)
        norm_out = self.activation(self.layer_norm(outputs))
        return norm_out, [norm_out]

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

model = Sequential([
    RNN(SimpleRNNCellWithLayerNorm(20), return_sequences=True,
        input_shape=[None, 20]),
    RNN(SimpleRNNCellWithLayerNorm(5)),
])

model.compile(loss="mse", optimizer="sgd")
X_train = np.random.randn(100, 50, 20)
Y_train = np.random.randn(100, 5)
history = model.fit(X_train, Y_train, epochs=2)

Для ячеек GRU и LSTM люди обычно применяют норму слоя на затворах (после линейной комбинации входов и состояний и перед активацией сигмоида), так что это немного сложнее реализовать. В качестве альтернативы вы, вероятно, можете получить хорошие результаты, просто применив норму слоя перед применением activation и recurrent_activation, что было бы проще реализовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...