忘川彼岸|Zero进行神经网络训练,用PyTorch对Leela( 二 )


(x_conv+bias—mean)/sqrt(var—eps)=(x_conv—mean)/sqrt(var—eps)+betax_conv+bias—mean=x_conv—mean+beta*sqrt(var—eps)bias=beta*sqrt(var—eps)因此 , 如果我们在权值文件中将卷积偏差设置为beta*sqrt(var-eps) , 我们就会得到期望的输出 , 这就是LeelaZero所做的 。
那么 , 我们如何实现它呢?在Tensorflow中 , 你可以通过调用tf.layers.batch_normalization(scale=False)来告诉归一化层要忽略gamma项 , 然后使用它 。
遗憾的是 , 在PyTorch中 , 你不能将归一化层设置为只忽略gamma , 你只能通过将仿射参数设置为False:BatchNorm2d(out_channels,affine=False) , 来忽略gamma和beta 。 所以 , 我把归一化层设为两个都忽略 , 然后简单地在后面加上一个张量 , 它表示beta 。 然后 , 使用公式bias=beta*sqrt(var-eps)来计算权值文件的卷积偏差 。
训练管道在弄清了LeelaZeros的神经网络的细节之后 , 就到了处理训练管道的时候了 。 正如我提到的 , 我想练习使用两个工具:PyTorchLightning和Hydra , 来加快编写训练管道和有效管理实验配置 。 让我们来详细了解一下我是如何使用它们的 。
PyTorchLightning编写训练管道是我研究中最不喜欢的部分:它涉及大量重复的样板代码 , 而且很难调试 。 正因为如此 , PyTorchLightning对我来说就像一股清流 , 它是一个轻量级的库 , PyTorch没有很多辅助抽象 , 在编写训练管道时 , 它负责处理大部分样板代码 。 它允许你关注你的训练管道中更有趣的部分 , 比如模型架构 , 并使你的研究代码更加模块化和可调试 。 此外 , 它还支持多gpu和TPU的开箱即用训练!
为了使用PyTorchLightning作为我的训练管道 , 我需要做的最多的编码就是编写一个类 , 我称之为NetworkLightningModule , 它继承自LightningModule来指定训练管道的细节 , 并将其传递给训练器 。 有关如何编写自己的LightningModule的详细信息 , 可以参考PyTorchLightning的官方文档 。
Hydra我一直在研究的另一部分是实验管理 。 当你进行研究的时候 , 你不可避免地要运行大量不同的实验来测试你的假设 , 所以 , 以一种可扩展的方式跟踪它们是非常重要的 。 到目前为止 , 我一直依赖于配置文件来管理我的实验版本 , 但是使用平面配置文件很快就变得难以管理 。 使用模板是这个问题的一个解决方案 。 然而 , 我发现模板最终也会变得混乱 , 因为当你覆盖多个层的值文件来呈现你的配置文件时 , 很难跟踪哪个值来自哪个值文件 。
另一方面 , Hydra是一个基于组件的配置管理系统 。 与使用单独的模板和值文件来呈现最终配置不同 , 你可以组合多个较小的配置文件来组成最终配置 。 它不如基于模板的配置管理系统灵活 , 但我发现基于组件的系统在灵活性和可维护性之间取得了很好的平衡 。 Hydra就是这样一个专门为研究脚本量身定做的系统 。 它的调用有点笨拙 , 因为它要求你将它用作脚本的主要入口点 , 但实际上我认为有了这种设计 , 它很容易与你的训练脚本集成 。 此外 , 它允许你通过命令行手动覆盖配置 , 这在运行你的实验的不同版本时非常有用 。 我常常使用Hydra管理不同规模的网络架构和训练管道配置 。
评估为了评估我的训练网络 , 我使用GoMill()来举行围棋比赛 。 它是一个运行在GoTextProtocol(GTP)引擎上的比赛的库 , LeelaZero就是其中之一 。 你可以在这里(/blob/master/eval/bg-vs-sm.ctl)找到我使用的比赛配置 。
结论【忘川彼岸|Zero进行神经网络训练,用PyTorch对Leela】通过使用PyTorch-Lightning和Hydra , 能够极大地加快编写训练管道的速度 , 并有效地管理实验配置文件 。 我希望这个项目和博客文章也能对你的研究有所帮助 。 代码: