训练中断了ResourceExausted错误

时间:2017-12-28 13:00:48

标签: python tensorflow batch-processing

我是tensorflow和机器学习的新手。最近我正在研究一个模型。我的模型如下,

  1. 字符级嵌入向量 - >嵌入查找 - > LSTM1

  2. 单词级嵌入向量 - >嵌入查找 - > LSTM2

  3. [LSTM1 + LSTM2] - >单层MLP-> softmax图层

  4. [LSTM1 + LSTM2] - >单层MLP-> WGAN鉴别器

  5. 他的模特代码

  6. 当我正在使用此模型时,我收到以下错误。我以为我的批次太大了。因此,我尝试将批量大小从20减少到10,但它不起作用。

      

    ResourceExhaustedError(参见上面的回溯):分配时的OOM   张量形状[24760,100] [节点:   chars / bidirectional_rnn / bw / bw / while / bw / lstm_cell / split =   拆分[T = DT_FLOAT,num_split = 4,   _device = “/作业:本地主机/复制:0 /任务:0 /设备:GPU:0”](gradients_2 / ADD_3 / Y,   chars / bidirectional_rnn / bw / bw / while / bw / lstm_cell / BiasAdd)]] [[节点:   bi-lstm / bidirectional_rnn / bw / bw / stack / _167 =   _Recvclient_terminated = false,recv_device =“/ job:localhost / replica:0 / task:0 / device:CPU:0”,   send_device = “/作业:本地主机/复制:0 /任务:0 /设备:GPU:0”,   send_device_incarnation = 1,   tensor_name = “edge_636_bi-LSTM / bidirectional_rnn /体重/体重/栈”,   tensor_type = DT_INT32,   _device = “/作业:本地主机/复制:0 /任务:0 /装置:CPU:0”]]

    形状的张量[24760,100] 表示2476000 * 32/8 * 1024 * 1024 = 9.44519043 MB内存。我在Titan X(11 GB)GPU上运行代码。怎么可能出错?为什么会出现这种类型的错误?

    *额外信息* :LSTM1的大小为100.对于双向LSTM,它变为200。 LSTM2的大小为300.对于双向LSTM,它变为600。

    *注意* :错误发生在32个纪元之后。我的问题是为什么在32个时代之后出现了错误。为什么不在最初的时代。

2 个答案:

答案 0 :(得分:7)

这些天我一直在调整以解决这个问题。

最后,我还没有解开问题中描述的内存大小的谜团。我想在计算梯度时,tensoflow会为计算梯度积累大量额外的内存。我需要检查张量流的来源,这在目前看来非常麻烦。您可以通过以下命令

检查模型在终端上使用的内存量
nvidia-smi

根据此命令判断,您可以猜出可以使用多少额外内存。

但这些问题的解决方案在于减少批量大小,

  

对于我的情况,将批量的大小减少到3个。这可能会有所不同   模型到模型。

但是如果你使用的模型中嵌入矩阵要大得多,你就无法将它们加载到内存中呢?

解决方案是写一些痛苦的代码。

您必须在嵌入矩阵上查找,然后将嵌入加载到模型中。简而言之,对于每个批次,您必须将查找矩阵提供给模型(通过sess.run()中的feed_dict参数提供它们。)

接下来,您将遇到一个新问题,

您无法以这种方式进行嵌入trainable。解决方案是在placeholder中使用嵌入并将其分配给Variable(例如A)。在每批训练之后,学习算法更新变量A。然后通过tensorflow计算A向量的输出,并将它们分配给模型外部的嵌入矩阵。 (我说这个过程很痛苦)

现在你的下一个问题应该是,如果你不能将嵌入查找提供给模型,那会怎么样,因为它太大了。这是一个你无法避免的根本问题。这就是NVIDIA GTX 1080,1080ti和NVIDA TITAN Xp具有如此价格差异的原因,尽管NVIDIA 1080ti和1080具有更高的运行执行频率。

答案 1 :(得分:3)

  

*注*:错误发生在32个纪元之后。我的问题是为什么在32个时代之后出现了错误。为什么不在最初的时代。

这是图表在执行期间不是静态的主要线索。我的意思是,你可能会sess.run(tf.something)代替

my_something = tf.something
with tf.Session() as sess: 
    sess.run(my_something)

我遇到了试图实现有状态RNN的同样问题。我偶尔会重置状态,所以我正在做sess.run([reset if some_condition else tf.no_op()])。只需将nothing = tf.no_op()添加到我的图表并使用sess.run([reset if some_condition else nothing])解决了我的问题。

如果你可以发布训练循环,那么就更容易判断这是不是出了什么问题。