均方误差期间Tensorflow GPU内存耗尽

均方误差期间Tensorflow GPU内存耗尽,tensorflow,gpu,recurrent-neural-network,Tensorflow,Gpu,Recurrent Neural Network,我有一个Tensorflow模型,它是一个使用长-短期记忆的递归神经网络。状态大小为3000,输入的每个时间步有300个输入,大约有500个时间步,每个时间步有1个输出。我正在训练一个序列到序列的模型 对于小于500个时间步的输入,它运行正常,但在大约500个时间步的某个地方,它会崩溃,并出现以下内存不足错误: ResourceExhaustedError (see above for traceback): OOM when allocating tensor with shape[20375

我有一个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到2GB),但它太慢了,从来没有达到500个时间步。我正在做一些修改,让它跳到500个时间步,看看它不在GPU上运行时使用了多少内存

我的问题是:Tensorflow可能想在哪里分配一个[2037520375]形状的张量?它似乎与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)
如果您需要所有的代码,可以找到它。相关函数是buildtower()和buildgraph()。在使用GPU的计算机上运行时,将常量NUM_gpu和BATCH_SIZE设置为适当的值

更新:我更换了线路

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

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


更新:在做了一些研究之后,我发现,当使用大量时间步长训练RNN时,通常会使用截断反向传播。这让我相信,通过大量时间步的反向传播固有地需要大量内存,我的问题不是我构造的图形错误,而是我对梯度计算的资源需求有一个根本性的误解。为此,我正在修改代码以使用截断反向传播。我将报告结果。

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

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

为了解决这个问题,我使用了,其中每个批次被分成若干固定数量的时间步长的块。这并不完美,因为这意味着错误最多只能传播回这么多时间步。然而,根据我在网上的发现,它似乎工作得很好,并且没有太多其他方法可以解决内存使用问题

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

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