如何让 TensorFlow RNN 训练更稳健?

How can I make TensorFlow RNN training more robust?

我正在用时间序列训练 RNN。我将 RNNCell 子类化并在 dynamic_rnn 中使用它。 RNNCell的拓扑结构如下:

  1. 输入(形状[15, 100, 3]
  2. 1x3 卷积(5 个内核),ReLu(形状[15, 98, 5]
  3. 1x(剩余)卷积(20 个内核),ReLu(形状 [15, 1, 20]
  4. 连接上一个输出(形状 [15, 1, 21]
  5. 挤压和 1x1 卷积(1 个内核),ReLu(形状 [15, 1]
  6. 挤压和 softmax(形状 [15]

dynamic_rnn 的批量大小约为 100(与上面描述的 100 不同,那是 window 数据中的时间段数)。时代由大约 200 个批次组成。 我想尝试超参数和正则化,但我尝试的往往完全停止学习,我不明白为什么。这些是发生的一些奇怪的事情:

为什么这个模型如此脆弱?是RNNCell的拓扑吗?

编辑: 这是 RNNCell:

的代码
class RNNCell(tf.nn.rnn_cell.RNNCell):
    def __init__(self):
        super(RNNCell, self).__init__()
        self._output_size = 15
        self._state_size = 15

    def __call__(self, X, prev_state):

        network = X
        # ------ 2 convolutional layers ------
        network = tflearn.layers.conv_2d(network, 5, [1, 3], activation='relu', weights_init=tflearn.initializations.variance_scaling(), padding="valid", regularizer=None)
        width = network.get_shape()[2]
        network = tflearn.layers.conv_2d(network, 20, [1, width], [1, 1], activation='relu', weights_init=tflearn.initializations.variance_scaling(), padding="valid", regularizer=None)

        # ------ concatenate the previous state ------
        _, height, width, features = network.get_shape()
        network = tf.reshape(network, [-1, int(height), 1, int(width * features)])
        network = tf.concat([network, prev_state[..., None, None]], axis=3)

        # ------ last convolution and softmax ------
        network = tflearn.layers.conv_2d(network, 1, [1, 1], activation='relu', weights_init=tflearn.initializations.variance_scaling(), padding="valid", regularizer=None)
        network = network[:, :, 0, 0]
        predictions = tflearn.layers.core.activation(network, activation="softmax")

        return predictions, predictions

    @property
    def output_size(self):
        return self._output_size
    @property
    def state_size(self):
        return self._state_size

很可能你正面临梯度消失的问题。

不稳定的原因可能是将 ReLU 与少量要调整的参数结合使用。据我从描述中了解到,例如,第一层中只有 1x3x5 = 15 个可训练参数。如果假设初始化大约为零,那么平均 50% 的参数的梯度将始终保持为零。一般来说,ReLU 在小型网络上是一种邪恶,尤其是在 RNNs 的情况下。

  1. 尝试使用 Leaky ReLU(但你可能会面临梯度爆炸)
  2. 尝试使用 tanh,但检查参数的初始值,它们确实在零附近,否则你的梯度也会很快消失。
  3. 检索未经训练但刚刚在第 0 步初始化的网络的结果。通过正确的初始化和 NN 构造,您应该获得大约 .5 的正态分布值。是错的。所有值都严格为 .5 也是不好的。
  4. 考虑更稳健的方法,例如 LSTM