如何使用tf.keras在RNN中应用图层归一化?

时间:2019-03-29 15:15:26

标签: python tf.keras tensorflow2.0

我想将layer normalization应用于使用tf.keras的递归神经网络。在TensorFlow 2.0中,LayerNormalization中有一个tf.layers.experimental类,但是尚不清楚如何在每个时间步的{em> 这样的循环层中使用它们(<{因为它是为使用而设计的)。我应该创建一个自定义单元格,还是有一种更简单的方法?

例如,在创建LSTM层时,在每个时间步骤应用dropout就像设置recurrent_dropout参数一样容易,但是没有LSTM参数。

2 个答案:

答案 0 :(得分:3)

在tensorflow插件中,有一个现成的LayerNormLSTMCell内置框。

有关更多详细信息,请参见this doc。您可能必须先安装tensorflow-addons,然后才能导入此单元格。

pip install tensorflow-addons

答案 1 :(得分:1)

您可以通过继承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单元,人们通常在门上应用层规范(在输入和状态的线性组合之后,在S型激活之前),因此实现起来有些棘手。另外,您可以通过在应用activationrecurrent_activation之前先应用层范数来获得良好的结果,这将更易于实现。