培训因资源错误而中断



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

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

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

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

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

  5. 代码 他 rnn 模型

当我在这个模型上工作时,我收到以下错误。我以为我的批次太大了。因此,我试图将批量大小从 20 减少到 10,但它不起作用。

资源耗尽错误(有关回溯,请参见上文):分配时的 OOM 带形状的张量[24760,100] [[节点: 字符/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)]] [[Node: 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/bw/bw/stack", tensor_type=DT_INT32, _device="/作业:本地主机/副本:0/任务:0/设备:CPU:0"]]

带 shape[24760,100] 的张量表示 2476000*32/8*1024*1024 = 9.44519043 MB 内存。我正在泰坦X(11 GB)GPU上运行代码。可能出现什么问题?为什么会发生这种类型的错误?

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

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

这些天我一直在调整很多来解决这个问题。

最后,我还没有解开问题中描述的内存大小之谜。我想在计算梯度张流时会积累大量额外的内存来计算梯度。我需要检查张量流的来源,这在此时似乎非常麻烦。您可以通过以下命令从终端检查您的模型使用了多少内存,

nvidia-smi

从此命令来看,您可以猜测可以使用多少额外内存。

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

就我而言,将批次的大小减少到 3 个作品。这可能会有所不同 模型到模型。

但是,如果您使用的模型的嵌入矩阵要大得多,以至于无法将它们加载到内存中,该怎么办?

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

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

接下来你将面临一个新问题,

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

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

*注意*:错误发生在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])就可以解决我的问题。

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

我在训练 conv-autoencoder 模型时也遇到了同样的问题。通过减小批量大小解决了这个问题。我之前的批量大小是 64。为了解决此错误,我将其减少到 32 并且它起作用了!!

最新更新