【问题标题】:Tensorflow GPU Memory exhausted during mean squared errorTensorflow GPU 内存在均方误差期间耗尽
【发布时间】:2017-03-27 22:35:56
【问题描述】:

我有一个 Tensorflow 模型,它是一个使用长期短期记忆的循环神经网络。状态大小为 3000,输入的每个时间步有 300 个输入,大约有 500 个时间步,每个时间步有 1 个输出。我正在训练一个序列到序列的模型。

对于少于 500 个时间步长的输入,它运行良好,但在大约 500 个时间步长时,它会因以下内存不足错误而崩溃:

ResourceExhaustedError (see above for traceback): OOM when allocating tensor with shape[20375,20375]
     [[Node: gradients/mean_squared_error/Mul_grad/mul_1 = Mul[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/gpu:0"](mean_squared_error/Square, gradients/mean_squared_error/Sum_grad/Tile)]]
     [[Node: gradients/MatMul_grad/tuple/control_dependency_1/_225 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/cpu:0", send_device="/job:localhost/replica:0/task:0/gpu:0", send_device_incarnation=1, tensor_name="edge_5086_gradients/MatMul_grad/tuple/control_dependency_1", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/cpu:0"]()]]

这是在具有 12gb 内存的 GPU 上运行的。

我曾尝试在我的笔记本电脑 CPU 上运行它,它似乎使用的内存非常少(大约 1 到 2 GB),但它太慢了,以至于它从未达到 500 个时间步长。我正在做一些改变,让它跳到 500 个时间步,看看它在 GPU 上不运行时使用了多少内存。

我的问题是:Tensorflow 可能想要在哪里分配形状为 [20375, 20375] 的张量?它似乎与 tf.mean_squared_error 函数有关,但这似乎不是一个需要如此大量内存的操作。

我已经尝试减小批量大小,但这只会将故障点推高几个时间步,而且我需要多达几千个时间步,所以这似乎不是一个好的长期 -长期解决方案。我更愿意找到问题的根源。

这里是均方误差的相关代码:

initial_state_tuple = tf.contrib.rnn.LSTMStateTuple(initial_state, initial_hidden_state)


# Create the actual RNN
with tf.variable_scope(VARIABLE_SCOPE, reuse=None):
    cell = tf.contrib.rnn.BasicLSTMCell(STATE_SIZE)
    rnn_outputs, finalstate = tf.nn.dynamic_rnn(cell=cell, inputs=networkinput,
                                                initial_state=initial_state_tuple)

with tf.variable_scope(VARIABLE_SCOPE, reuse=True):
    weights = tf.get_variable(name=WEIGHTS_NAME, shape=[STATE_SIZE, 1], dtype=tf.float32)
    biases = tf.get_variable(name=BIASES_NAME, shape=[1], dtype=tf.float32)

# Build the output layers
rnn_outputs_reshaped = tf.reshape(rnn_outputs, [-1, STATE_SIZE])
network_outputs = tf.sigmoid(tf.matmul(rnn_outputs_reshaped, weights) + biases)
expected_outputs_reshaped = tf.reshape(expected_outputs, [-1, 1])

# Loss mask just cancels out the inputs that are padding characters, since not all inputs have the same number of time steps
loss_mask_reshaped = tf.reshape(loss_mask, shape=[-1])

expected_outputs_reshaped = loss_mask_reshaped * expected_outputs_reshaped
network_outputs = loss_mask_reshaped * network_outputs

loss = tf.losses.mean_squared_error(labels=expected_outputs_reshaped, predictions=network_outputs)

如果你想要所有的代码,可以找到here。相关函数是 buildtower() 和 buildgraph()。在带有 GPU 的机器上运行时,常量 NUM_GPUS 和 BATCH_SIZE 被设置为适当的值。

更新:我换了行

loss = tf.losses.mean_squared_error(labels=expected_outputs_reshaped, predictions=network_outputs)

error_squared = tf.pow(expected_outputs_reshaped - network_outputs, 2)
loss = tf.reduce_mean(error_squared)

同样的错误发生了。我将状态大小减少到 30,批量大小减少到 5,错误仍然发生,尽管它确实达到了大约 3000 个时间步长。

更新:经过一番研究,我发现,在训练具有大量时间步长的 RNN 时,经常使用截断反向传播。这让我相信通过大量时间步长的反向传播本质上会占用大量内存,而我的问题不是我构建的图表错误,而是我对梯度计算的资源需求存在根本性的误解。为此,我正在努力更改我的代码以使用截断的反向传播。我会报告结果。

【问题讨论】:

    标签: tensorflow gpu recurrent-neural-network


    【解决方案1】:

    这个项目是我对机器学习和 TensorFlow 的第一次体验,在做了一些研究之后,似乎我有一些基本的误解。

    我曾认为内存使用量会随着数据中的时间步数呈线性增长。因为我的模型的每个其他维度(批量大小、状态大小)都很小,所以我希望在内存不足之前我可以达到相当多的时间步长。然而,计算梯度的内存使用似乎随着时间步的数量呈指数增长,所以无论我将状态大小和批量大小设置得多么小,它最终都会因为大量的时间步而耗尽我的所有内存。

    为了解决这个问题,我使用了truncated backpropagation,其中每个批次都被分成一些固定数量的时间步长的块。这并不完美,因为这意味着错误最多只能传播回这么多时间步。但是,根据我在网上的发现,它似乎运行良好,并且没有太多其他方法可以解决内存使用问题。

    正如我之前所说,这是我第一次接触机器学习,所以如果这里有什么明显的错误,请告诉我。

    【讨论】:

      猜你喜欢
      • 2017-02-07
      • 1970-01-01
      • 2018-04-08
      • 2017-08-11
      • 2016-03-13
      • 2021-02-24
      • 2021-11-01
      • 2017-12-12
      • 1970-01-01
      相关资源
      最近更新 更多