提高TensorFlow、Keras的交叉验证吞吐量

提高TensorFlow、Keras的交叉验证吞吐量,tensorflow,keras,profiling,cross-validation,Tensorflow,Keras,Profiling,Cross Validation,我正在研究CNN模型,该模型旨在根据蛋白质的氨基酸序列预测蛋白质的结构。我正在Keras实施我的CNN。KerasAPI是与TensorFlow 1.4.0捆绑在一起的,因此TensorFlow显然是我的后端。我已经安装了TensorFlow的GPU版本,并且我已经验证了GPU是否正在使用。我的GPU有点老,是NVidia GTX 760 当我执行3倍交叉验证以帮助选择架构和超参数时,我的训练折叠中有50K个示例,验证折叠中有25K个示例。这些是相当大的数据集,但是与我的计算机(16GB)或GP

我正在研究CNN模型,该模型旨在根据蛋白质的氨基酸序列预测蛋白质的结构。我正在Keras实施我的CNN。KerasAPI是与TensorFlow 1.4.0捆绑在一起的,因此TensorFlow显然是我的后端。我已经安装了TensorFlow的GPU版本,并且我已经验证了GPU是否正在使用。我的GPU有点老,是NVidia GTX 760

当我执行3倍交叉验证以帮助选择架构和超参数时,我的训练折叠中有50K个示例,验证折叠中有25K个示例。这些是相当大的数据集,但是与我的计算机(16GB)或GPU(2GB)上可用的RAM相比,它们很小。完全解包并表示为float32值,由于滑动窗口引入了冗余,所有折叠(输入加目标值)占316 MB。我已经预先计算了我的折叠,并将每个折叠的文件保存到磁盘。当我尝试使用架构和超参数时,每次试验都使用相同的折叠

我从包含一个隐藏层的网络开始,看看我能实现什么,然后切换到两个隐藏层。我在早期的所有实验中都使用了64的固定批量。训练进行得很快,我不在乎速度。对给定体系结构执行3倍交叉验证通常需要12分钟

但在我用双层网络做的最后一个实验中,我决定开始研究批量大小的影响。我了解到,在某种程度上,较小的批量给了我更好的结果。批量大小为8的是我可以指望不会崩溃的最小批量。“我的损失”值偶尔会在批大小为4的情况下转换为NaN,并且它们经常会在批大小为1或2的情况下转换为NaN。发生这种情况后,网络将无法训练。我知道梯度不稳定的可能性。我想我得到了一些

那么,为什么不使用8的批量大小并继续使用呢?问题是速度。使用两个隐藏层,一批八个花了我大约35分钟进行交叉验证。正如我上面提到的,64批的处理需要三分之一的时间。我用三个隐藏层进行的第一次试验每次试验耗时45到65分钟。我想利用更深层次的网络研究数百种潜在的体系结构和超参数。对于小批量,我可以看到Keras中逐批进度条的进度更慢。当一个时代结束时,我可以看到更长的停顿

是的,我可以将我的GPU升级到10系列。我想这最多只能使我的吞吐量翻倍?是的,我可以在云端租GPU时间。最终我可能会这么做。但是,如果我的软件效率低下,我绝对不想在云端随意使用它来烧钱

我的理解是(如果我错了,请纠正我),当GPU在正常TF/Keras工作流程中使用时,每个单独批次都从GPU单独发送到CPU。如果我在一个3倍交叉验证方案中训练50个网络,这意味着我要将相同的数据发送到我的GPU 150次。正如我前面提到的,我的所有数据最多占用316MB,大约占GPU上可用RAM的15%。我是否可以设计一个工作流,将这316 MB发送到GPU一次,如果是这样,会对我的吞吐量产生有用的影响?从直觉上看,这是应该的

我还应该考虑其他瓶颈吗?是否有方法描述TF或Keras操作


谢谢你的建议

好的。我知道您更关心Keras和您的硬件的吞吐量,但有几件事我想在这里提及:

  • 较小的批量给了我更好的结果
  • 考虑到您的情况,如果您没有这么大的数据,假设您正在为固定数量的历元(比如5个历元)运行培训,那么使用较小批量的培训自然会给您带来稍好的结果,因为与较大批量的培训相比,这意味着总体上有更多的后支撑步骤。如果你在训练固定数量的训练步骤,我不知道为什么会发生这种情况

  • 损失值偶尔会在批量大小为4时变为NaN
  • 同样,我假设您在这里使用批处理规范化,使用CNN。在使用BN时,实际上从未建议使用较小的批量,如2或4(甚至8)。也许,你面对小批量NaN的一个原因是,如果你在当前批量中的方差很低,如果你把ε值取得太小,你可能会有非常小的值,这会导致数值不稳定。但更一般地说,这可能是你提到的梯度不稳定的情况。考虑使用渐变剪辑来查看它是否有帮助。
  • GPU工作流
  • 在这里,我假设您只有1个GPU。不幸的是,您无法使用单个GPU进行并行化。澄清一下,您不应该担心GPU RAM的数据大小。在大多数单个GPU的情况下,当前批处理保留在CPU上,GPU只会占用这些操作。相反,您应该关心GPU将要计算的参数的大小。因为对于1层实验和3层实验,你们的操作有很大的不同,我认为这是不可能的,因为你们不能在同一台设备上同时放置多个操作。对于您来说,这里的最佳情况是使用更大的批量(不要太大,因为这将减少固定历元训练时的后支撑步骤的数量),这样您就可以在一次尝试中覆盖更多数据

    只是一个超级参数调整的提示,你可以考虑使用。这些源于LSTM的选通机制,您可以在其中指定大量隐藏层和网络f