Memory 带有大型过滤器的tensorflow conv2d的内存使用

Memory 带有大型过滤器的tensorflow conv2d的内存使用,memory,tensorflow,convolution,Memory,Tensorflow,Convolution,我有一个tensorflow模型,带有一些相对较大的135x135x1x3卷积滤波器。我发现tf.nn.conv2d对于如此大的过滤器变得不可用-它试图使用超过60GB的内存,此时我需要杀死它。以下是复制我的错误的最低脚本: 将tensorflow导入为tf 将numpy作为np导入 帧,高度,宽度,通道=200321481,1 filter_h,filter_w,filter_out=5,5,3#这样,输出具有形状(200317477,3) #filter_h,filter_w,filter_

我有一个tensorflow模型,带有一些相对较大的
135x135x1x3
卷积滤波器。我发现
tf.nn.conv2d
对于如此大的过滤器变得不可用-它试图使用超过60GB的内存,此时我需要杀死它。以下是复制我的错误的最低脚本:

将tensorflow导入为tf
将numpy作为np导入
帧,高度,宽度,通道=200321481,1
filter_h,filter_w,filter_out=5,5,3#这样,输出具有形状(200317477,3)
#filter_h,filter_w,filter_out=7,7,3#这样,输出具有形状(200315475,3)
#filter_h,filter_w,filter_out=135,135,3#这样,输出将小于上面的形状(200187347,3),但内存使用量会激增
images=np.random.randn(帧、高度、宽度、通道).astype(np.float32)
filters=tf.Variable(np.random.randn(filter\u h,filter\u w,channels,filter\u out).astype(np.float32))
图像输入=tf.placeholder(tf.float32)
conv=tf.nn.conv2d(图像输入、过滤器、步幅=[1,1,1,1],padding=“VALID”)
使用tf.Session()作为sess:
sess.run(tf.global\u variables\u initializer())
result=sess.run(conv,feed\u dict={images\u input:images})
打印结果.shape
首先,有人能解释这种行为吗?为什么内存使用会随着过滤器大小而膨胀?(注意:我还尝试改变我的尺寸,用一个
conv3d
代替一批
conv2d
s,但这也有同样的问题)

第二,除了将操作分解为200个单独的单图像卷积,还有谁能提出解决方案吗

编辑:在重新阅读了关于
tf.nn.conv2d()
的内容后,我在解释其工作原理时注意到了这一点:

  • 将过滤器展平为二维矩阵,形状
    [过滤器高度*过滤器宽度*输入通道,输出通道]
  • 从输入张量中提取图像面片,以形成形状的虚拟张量
    [批处理、输出高度、输出宽度、过滤器高度*过滤器宽度*输入通道]
  • 对于每个面片,右乘滤波器矩阵和图像面片向量
  • 我最初只是简单地将其作为过程的描述,但如果tensorflow实际上是从引擎盖下的图像中提取并存储单独的过滤器大小的“补丁”,那么信封背面的计算表明,在我的情况下,所涉及的中间计算需要约130GB,远远超过了我可以测试的限制。。这可能回答了我的第一个问题,但如果是这样的话,有人能解释为什么TF会在我仍然只在CPU上调试时这么做吗

    我最初只是把它当作对过程的描述, 但如果tensorflow实际上是提取和存储分离的 从引擎盖下的图像过滤大小的“补丁”,然后 信封背面的计算表明,中间 在我的例子中,所涉及的计算需要约130GB,远远超出了限制 我可以测试一下

    正如您自己所了解的,这就是大量内存消耗的原因。Tensorflow这样做是因为过滤器通常很小,计算矩阵乘法比计算卷积快得多

    有人能解释为什么TF会在我还在调试的时候这么做吗 在CPU上

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


    为了使大的滤波器卷积,你必须对C++中的大的滤波器实现卷积,并将它作为一个新的OP添加到TysFooSo../P>它实际上是在CPU上调试时这样做的,它是这样做的,因为它把卷积变成矩阵乘法,因此,您可以使用线性代数库来实现它。在GPU上运行它实际上可能需要更少的内存。