是否有任何理由将NHWC的张量转换为NCHW?

时间:2018-01-25 08:57:08

标签: tensorflow

我经常在张量流代码中看到转置实现。我想知道为什么要将NHWC张量转换为NCHW。请给我一个很好的例子和背后的原因。

2 个答案:

答案 0 :(得分:2)

而不是引用文档。您应该了解CUDA的工作原理并思考如何实施大多数操作。

NCHW通常比NHWC更快的原因是CUDA内核的编写方式。在CUDA中,您需要指定每个线程正在执行的操作

-config:yourconfiguationfile.xml

这里有3个指数const int threads = 32; dim3 block(threads, threads); dim3 grid(up2(W / 2, threads), up2(H, threads), B); kernel<Dtype> <<< grid, block>>> (args ...) 。这些线程以warp(硬件设计)组织。

并且您希望拥有合并内存事务,这意味着线程以这样的方式排序,以便GPU可以快速地运行。

总结一下: 你想让“threadId.x”成为最内循环,你应该组织数据布局,使它以合并的方式读取它们。

可以访问理想的数据结构
threadId.z, threadId.y, threadId.x

其中低位字母表示索引,大写字母表示形状(例如,0 <= w

在卷积运算(最常用层的一部分)中,您实际上正在做的是在每个通道中裁剪一个区域,计算另一个通道中的区域(来自另一个张量)的点生成。所以需要快速运行的索引是height-idx和width-idx。最后,您将沿通道轴添加(如卷积公式建议)。这也解释了为什么考虑NWHC,NCWH没有区别。

这会对您订购数据的方式产生影响。这就是你想要我上面描述的内存布局的原因。

最糟糕的布局是:

b * C * H * W + c * H * W + h * W + w

最佳布局是:

H, C, B, in threadId.z, threadId.y, threadId.x

同样(大多数情况下)对于GEMM也是如此(这里一个矩阵应该是转置的)。没有可用的CuDNN来源。但您可能有兴趣研究cutlass

答案 1 :(得分:1)

来自Tensorflow的performance guide

  

NHWC是TensorFlow的默认值,NCHW是最佳使用格式   使用cuDNN在NVIDIA GPU上进行培训时。 [...]这两种格式的简要历史是TensorFlow使用NHWC开始,因为它在CPU上的速度要快一些。从长远来看,我们正在研究自动重写图形的工具,以便在格式之间进行透明切换,并利用微优化,其中使用NHWC的GPU Op可能比通常最有效的NCHW更快。

基本上,cuDNN针对NCHW进行了优化,而仅限CPU的张量流针对NHWC进行了优化。从一个切换到另一个只是性能最大化和/或特定数据格式中某些操作不可用的问题。