使用大型过滤器的tensorflow conv2d的内存使用情况

时间:2017-08-30 21:04:14

标签: memory tensorflow convolution

我有一个张量流模型,带有一些相对较大的135 x 135 x 1 x 3卷积滤镜。我发现tf.nn.conv2d对于如此大的过滤器变得无法使用 - 它试图使用超过60GB的内存,此时我需要杀死它。以下是重现我的错误的最小脚本:

import tensorflow as tf
import numpy as np

frames, height, width, channels = 200, 321, 481, 1
filter_h, filter_w, filter_out = 5, 5, 3  # With this, output has shape (200, 317, 477, 3)
# filter_h, filter_w, filter_out = 7, 7, 3  # With this, output has shape (200, 315, 475, 3)
# filter_h, filter_w, filter_out = 135, 135, 3  # With this, output will be smaller than the above with shape (200, 187, 347, 3), but memory usage explodes

images = np.random.randn(frames, height, width, channels).astype(np.float32)

filters = tf.Variable(np.random.randn(filter_h, filter_w, channels, filter_out).astype(np.float32))
images_input = tf.placeholder(tf.float32)
conv = tf.nn.conv2d(images_input, filters, strides=[1, 1, 1, 1], padding="VALID")

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    result = sess.run(conv, feed_dict={images_input: images})

print result.shape

首先,任何人都可以解释这种行为吗?为什么内存使用会因过滤器大小而爆炸? (注意:我也尝试更改我的尺寸以使用单个conv3d而不是一批conv2d s,但这有同样的问题)

第二,任何人都可以提出一个解决方案,比如将操作分解为200个独立的单图像卷积吗?

修改:重新阅读tf.nn.conv2d()上的docs后,我在解释它如何运作时注意到了这一点:

  
      
  1. 将滤镜展平为形状为[filter_height * filter_width * in_channels, output_channels]的二维矩阵。
  2.   
  3. 从输入张量中提取图像色块以形成形状为[batch, out_height, out_width, filter_height * filter_width * in_channels]的虚拟张量。
  4.   
  5. 对于每个补丁,右对乘滤波器矩阵和图像补丁矢量。
  6.   

我最初只把它当作过程的描述,但是如果tensorflow实际上是提取和存储单独的过滤器大小的补丁'从引擎盖下的图像开始,然后一个背后的计算结果显示,在我的情况下涉及的中间计算需要大约130GB,远远超过我可以测试的限制..这个可能回答我的第一个问题,但是如果有的话,任何人都可以解释为什么当我仍然只在CPU上调试时TF会这样做?

1 个答案:

答案 0 :(得分:3)

  

我最初只是将此作为对过程的描述,   但是如果tensorflow实际上是提取和存储分开的   从引擎盖下的图像过滤大小的'补丁',然后a   背面计算显示中间   在我的情况下涉及的计算需要大约130GB,远远超过极限   我可以测试一下。

正如你自己想的那样,这就是大量内存消耗的原因。 Tensorflow这样做是因为滤波器通常很小,计算矩阵乘法比计算卷积要快很多。

  

任何人都可以解释为什么当我还在调试时TF会这样做   在CPU上?

您也可以在没有GPU的情况下使用tensorflow,因此CPU实现不仅仅用于调试。它们还针对速度进行了优化,矩阵乘法在CPU和GPU上都更快。

要使用大型过滤器进行卷积,您必须在C ++中实现大型过滤器的卷积,并将其添加为张量流的新操作。