python - 如何使 TensorFlow RNN 训练更加稳健?

标签 python tensorflow machine-learning recurrent-neural-network

我正在时间序列上训练 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 不同,它是数据窗口中的时间段数)。 Epoch 由大约 200 个批处理组成。 我想尝试超参数和正则化,但我尝试的很多时候会完全停止学习,我不明白为什么。这些是发生的一些奇怪的事情:

  • Adagrad 可以工作,但如果我使用 Adam 或 Nadam,梯度全部为零。

  • 我被迫设置一个巨大的学习率(~1.0)来观察从一个时代到另一个时代的学习。

  • 如果我尝试在任何卷积后添加 dropout,即使我将 keep_prob 设置为 1.0,它也会停止学习。

  • 如果我调整卷积中的内核数量,对于某些看起来同样好的选择(例如 5、25、1 与 5、20、1),网络将再次完全停止学习。

为什么这个模型如此脆弱?是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 是一种邪恶,特别是在 RNN 的情况下。

  1. 尝试使用 Leaky ReLU(但您可能会面临梯度爆炸)
  2. 尝试使用 tanh,但检查参数的初始值,确保它们确实在零附近,否则你的梯度也会很快消失。
  3. 检索未经训练但刚刚在第 0 步初始化的网络的结果。通过正确的初始化和神经网络构造,您应该得到 0.5 左右的正态分布值。如果您严格使用 1、0 或它们的混合,则您的神经网络架构是错误的。所有值严格限制为 0.5 也很糟糕。
  4. 考虑更稳健的方法,例如 LSTM

关于python - 如何使 TensorFlow RNN 训练更加稳健?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48484664/

相关文章:

python - fastapi.Response() 不返回自定义响应

python - Django 项目上的 SSL(django-sslserver) 问题

machine-learning - 使用 RNN/LSTM 根据过去事件预测 future 事件

matlab - 成本函数,sum(x)和ones(1,length(x)) *x有什么区别?

algorithm - LibSVM 和 LibLinear 有什么区别

python - "node ' 0 ' has no position - problems with allocating node positions to ' networkX/Python 中的节点类型

python - 通过创建处理程序类来避免重复代码

python - 必须完全定义新变量的形状,而不是 (?, 128)

python - 尝试使用 gpu 导入 tensorflow 时导入错误

python - 如何解读 H2ORF 对回归任务的预测?