我基本上是在尝试复制AlphaZero的功能。它在一些小游戏上已经成功了,但我试图将其扩展到更复杂的游戏。然而,现在我的网络在训练了2到1000万步之后就会充满NaN。不幸的是,由于它不是确定性的,而且故障点发生在如此广泛的范围内,使用调试器并没有很有效。当我让tfdbg检查”has_inf_or_nan”时,训练12000步大约需要5分钟。所以调试器对我来说毫无用处,因为要花很长时间才能遇到错误。
在这篇文章的最后,我将描述模型的外观。
以下是我使用的一些常见NaN来源的方法:
损失函数(单一网络有两个输出:策略(选择某步的概率)和价值(当前玩家棋盘位置的质量)):
注意:move_result_placeholder会被填充一批蒙特卡洛树搜索的输出步。由于大多数步位置都是无效的,通常它充满了0,只有5到10个浮点数代表选择该步的概率。我有一个断言来验证它们总和为1。在运行训练时,我也有一些断言来验证没有输入是NaN。我在填充批次时,从过去100万个(棋盘状态,步,奖励)的集合中随机均匀选择。然后我将棋盘状态、步和奖励输入到训练步骤中。
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")
批量归一化(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)。这捕捉了4×8棋盘的状态,以及自从玩家得分以来已经进行了多少步,以及在那个特定游戏中该棋盘状态被看到过多少次。这喂入一个卷积层,核大小为3×3,步长为1。然后我应用批量归一化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个残差块。在残差块之后,它分成两部分。第一部分是策略网络输出,它通过另一个卷积层,核大小为1×1,步长为1,以及一个批量归一化和一个ReLU。此时它是4x8x2,然后被展平并通过一个全连接层,然后通过一个softmax输出256个输出,代表它选择任何给定步的概率。256个输出映射到4×8棋盘上,具有棋子移动方向的平面。所以第一个4×8会告诉你选择一个棋子并将其向西北移动的概率。第二个会告诉你选择一个棋子并将其向东北移动的概率,等等。
分裂的另一边是价值输出。在那一边,它通过一个卷积层,然后被展平并通过一个全连接层,最后通过一个TanH输出一个单一值,告诉我们那个棋盘状态的质量。
所有层的权重都使用L2正则化(1e-4)。
损失函数是策略端的交叉熵和价值端的均方误差,我使用的是Adam优化器。
回答:
问题实际上是显卡坏了。如果你遇到了类似的问题,并且在没有成功的情况下调查了常见来源,请记得考虑你的显卡内存的问题。