【问题标题】:Tensorflow Model fills up with NaNs during trainingTensorflow 模型在训练期间充满了 NaN
【发布时间】:2018-09-17 00:52:01
【问题描述】:

我基本上是在玩复制 AlphaZero。它适用于一些小型游戏,但我正在尝试将其扩大到适用于更复杂的游戏。但是,现在我的网络经过 2-1000 万次移动训练后将充满 NaN。不幸的是,由于它不是确定性的,并且故障点发生在如此广泛的范围内,因此使用调试器并不是很有效。当我让 tfdbg 检查“has_inf_or_nan”时,训练 12000 个动作大约需要 5 分钟。所以调试器没有为我做任何事情,因为它需要很长时间才能遇到错误。

在这篇文章的最底部,我将描述模型的外观。

以下是我如何使用某些常见的 NaN 来源:

损失函数(具有 2 个输出的单一网络:策略(选择移动的几率)和价值(活跃玩家的棋盘位置质量)):

注意:move_result_placeholder 填充了一批移动,这些移动是蒙特卡洛树搜索的输出。由于大多数移动位置都是无效的,它通常充满 0 和 5-10,它们是代表选择该移动的几率的浮点数。我有一个断言,验证它们的总和为 1。在运行训练时,我也有断言验证没有一个输入是 NaN。在填充批次时,我从最后 1,000,000 个(棋盘状态、移动、奖励)的集合中随机选择。然后我将棋盘状态、动作和奖励输入到训练步骤中。

self.loss_policy = tf.losses.softmax_cross_entropy(self.move_result_placeholder, out_dense)
self.loss_value = 
    tf.losses.mean_squared_error(self.value_result_placeholder, 
    tf.reshape(self.out_value_layer, shape=[-1,]))
self.total_loss = self.loss_policy + self.loss_value

优化器(学习率 1e-4):

self.train_step = tf.train.AdamOptimizer(learning_rate=self.learning_rate_placeholder).minimize(self.total_loss, name="optimizer")

Softmax:

self.out_policy_layer = tf.nn.softmax(out_dense, name="out_policy_layer")

Batch Normalization(is_training 是一个占位符,训练时为 1,玩游戏时为 0)batch_norm_decay 为 .999:

input_bn = tf.contrib.layers.batch_norm(input_conv, center=True, scale=True, is_training=self.is_training, decay=self._config.batch_norm_decay)

正则化(层中所有权重的 L2 为 1e-4):

initializer=tf.contrib.layers.xavier_initializer()
if use_regularizer:
        regularizer = tf.contrib.layers.l2_regularizer(scale=self._config.l2_regularizer_scale)

    weights = tf.get_variable(name, shape=shape, initializer=initializer, regularizer=regularizer)

型号说明:

该模型是在 tensorflow 中创建的,包含一个 4x8x3 的输入层(批量大小为 1024)。这捕获了 4x8 棋盘的状态,以及自从玩家得分以来已经进行了多少次移动,以及在特定游戏中该棋盘状态出现了多少次。这会输入内核大小为 3x3 且 strides=1 的 conv2d 层。然后我应用 BatchNormalization tf.contrib.layers.batch_norm(input_conv, center=True, scale=True, is_training=self.is_training, decay=self._config.batch_norm_decay) 和 relu。在输入 relu 的末尾,大小为 4x8x64。

之后有 5 个残差块。在残差块之后,它一分为二。第一个是策略网络输出,它通过另一个卷积层运行,内核大小为 1x1,步长为 1,并进行批量归一化和 ReLU。此时它是 4x8x2,它被展平并穿过一个密集层,然后到一个 softmax 以输出 256 个输出,这些输出代表它将选择任何给定动作的几率。 256 个输出映射到 4x8 板,平面用于棋子移动的方向。所以第一个 4x8 会告诉你选择一块并将其移动到西北的几率。第二个会告诉你选择一块并将其移动到东北等的几率。

分割的另一边是值输出。在那一侧,它穿过一个卷积层,然后它被展平并穿过一个密集层,最后穿过一个 TanH,因此它输出一个值,告诉我们该板状态的质量。

所有层的权重都使用 L2 正则化 (1e-4)。

损失是策略方面的交叉熵和价值方面的均方误差,我正在使用 Adam 优化器。

【问题讨论】:

    标签: python tensorflow machine-learning deep-learning


    【解决方案1】:

    如果我是你,我会研究用于 tensorboard 的 tensorflow 调试器插件。你会发现使用这个工具,很容易通过你的图表来追踪问题。

    您可以在图表中逐步执行计算,还可以跟踪弹出的 NaN 值的出现。

    https://github.com/tensorflow/tensorboard/tree/master/tensorboard/plugins/debugger

    【讨论】:

      【解决方案2】:

      嗯,这个问题太宽泛了,无法像这样解决。一般来说,您需要考虑什么可以产生NaNs 并通过模块化禁用来解决这个问题,即禁用或绕过模型中的东西,看看错误是否消失。一些可能出现问题的候选者:批量归一化,或某些边缘情况的 softmax(全为零输入),或者您可能有梯度爆炸(尝试限制学习率)。

      例如,关闭批量标准化并运行模型,看看是否发生错误。如果是,则将学习率降低几个数量级。以此类推。

      【讨论】:

      • 是的,我一直在尝试各种事情,但我一直无法弄清楚。这就是为什么我尽可能详细地发布一个帖子。盲目地希望有人会阅读它并指出我正在做的一些愚蠢的事情。我不知所措。我实际上还没有尝试禁用批处理规范,所以我会试一试。谢谢!
      【解决方案3】:

      问题实际上是一个即将死去的显卡。如果您遇到类似的问题,并且您调查了通常的来源但没有成功,请记住考虑您的视频卡中的内存问题。

      【讨论】:

      • 这不是真正的解决方案,只是您尝试过的事情的列表。请只标记普遍适用或具体解决问题的答案
      猜你喜欢
      • 2018-08-03
      • 2019-12-20
      • 2023-03-20
      • 1970-01-01
      • 2021-12-27
      • 1970-01-01
      • 2019-12-07
      • 2020-01-03
      • 1970-01-01
      相关资源
      最近更新 更多