【问题标题】:3D convolution for preprocessing with Tensorflow使用 Tensorflow 进行预处理的 3D 卷积
【发布时间】:2018-02-15 01:09:15
【问题描述】:

我构建了一个神经网络,用于对 3D 图像进行像素级分类。

分类任务非常简单,不需要卷积网络,而是计算一些特征(高斯、LoG、Sobel 等)并将这些与原始值一起输入经典 MLP。由于此功能的计算非常缓慢并且没有利用我的 GPU,我认为 Tensorflow 实现可能会有所帮助:

首先我读取一个二进制文件并创建一个带有 3D 数组和 1 个通道的批次:

data_dir="/Users/Me/Documents/Data/"
filenames = [os.path.join(data_dir,'File_%05d.bin' % i ) for i in range(100)]
filename_queue = tf.train.string_input_producer(filenames)
Stack= BinChunkReader(filename_queue) #custom reader

sess = tf.Session()
print(sess.run(tf.shape(Stack))) #outputs [1 100 100 100 1]

然后我使用自定义函数创建一个 3D 内核并定义 3D 卷积:

kernel=np.ones((11,11,11,1,1),dtype='int32')
kernel[:,:,:,0,0]=Get3DKernel("LoG", Radius=6,Param=5) #custom function to produce a kernel

kernel_init=tf.constant(kernel)
TF_kernel=tf.get_variable('LoG_filter', initializer= kernel_init)
LoG=tf.nn.conv3d(Stack,TF_kernel,[1,1,1,1,1],"SAME")

但试图运行它

sess = tf.Session()
sess.run(LoG)

产生以下错误:

InvalidArgumentError: No OpKernel was registered to support Op 'Conv3D' with these attrs.  Registered devices: [CPU], Registered kernels:
  device='CPU'; T in [DT_FLOAT]
  device='CPU'; T in [DT_DOUBLE]

     [[Node: Conv3D_1 = Conv3D[T=DT_INT32, padding="SAME", strides=[1, 1, 1, 1, 1]](Reshape, LoG_filter/read)]]

第一个问题:这个错误是什么意思,如何实现 3D 卷积?

第二个问题:我的假设是否正确,即在 tensorflow 中实现这个(目前用 scikit-image 实现)对执行速度有好处?

【问题讨论】:

  • 第一个问题:尝试定义kernel=np.ones((11,11,11,1,1),dtype='float32')
  • 该错误表示对于输入类型的特定组合没有实现 Conv3D 操作。您的内核是 int 类型,但内核可用于浮点数和双精度数(至少根据错误消息)
  • 根据速度问题,似乎这些操作仅在 CPU 上实现(再次读取错误消息)。试试看速度是否有所提高。附带问题:您使用的是 GPU 构建的 Tensorflow 吗?因为错误代码中的Registered Devices :[CPU] 似乎意味着Tensorflow 看不到你的GPU...
  • 好的,在 Kernel 和 Stack 中切换到 'float32' 工作,谢谢,但是卷积现在比 scikit 图像实现花费更长的时间。我正在我的笔记本电脑上编写代码,但将在带有 GPU 的计算机上运行实际训练,不用担心;)

标签: python multidimensional-array tensorflow convolution


【解决方案1】:

我正在以更有序的方式将解决方案放在 cmets 中,以防其他人偶然发现这个问题。

解读错误信息:

你的错误:

InvalidArgumentError: No OpKernel was registered to support Op 'Conv3D' with these attrs.  
Registered devices: [CPU], 
Registered kernels:
  device='CPU'; T in [DT_FLOAT]
  device='CPU'; T in [DT_DOUBLE]
[[Node: Conv3D_1 = Conv3D[T=DT_INT32, padding="SAME", strides=[1, 1, 1, 1, 1]](Reshape, LoG_filter/read)]]

No OpKernel was registered to support Op 'Conv3D' with these attrs 表示您传递给函数调用的属性与该函数的任何现有实现都不匹配。

Node: Conv3D_1 = Conv3D[T=DT_INT32, padding="SAME", strides=[1, 1, 1, 1, 1]](Reshape, LoG_filter/read)] 表示对于图中引发错误的Conv3D 节点,输入张量的类型为int32

Registered kernels:
  device='CPU'; T in [DT_FLOAT]
  device='CPU'; T in [DT_DOUBLE]

告诉Conv3D 操作在您的机器上有两个可用的实现。一个在您的 CPU 上运行,并以 float32 张量 (DT_FLOAT) 作为输入,而另一个也在您的 CPU 上运行,并将 float64 张量 (DT_DOUBLE) 作为输入。

注意:Registered devices: [CPU], 似乎指出您的 Tensorflow 看不到您的 GPU(您是否安装了仅 CPU 版本的 Tensorflow?)。

您的问题的答案:

这个错误是什么意思?如何实现 3D 卷积?

我认为在上一节中已经对错误进行了充分的解释。您不想自己实现 Conv3D,而是将输入类型更改为已经实现的东西。将StackTF_kernel 的类型更改为float32float64(例如,将kernel 定义为kernel=np.ones((11,11,11,1,1),dtype='float32'))。

我的假设是否正确,在 tensorflow 中实现(目前使用 scikit-image 实现)将对执行速度有利?

很难说。由于这两种实现都是纯 CPU 的,我想尝试看看情况是否有所改善是最好的选择(如果你能更新你的问题,让我们知道它是否确实加速了,那就太好了)。 我还建议检查您是否正在使用 GPU Tensorflow 构建,如果没有,请切换到那个(加快计算速度的机会更高)。

【讨论】:

  • 感谢您的解释,有时这种错误对我来说是相当神秘的!我目前正在没有 GPU 的笔记本电脑上编写和测试这些程序(因此错误消息中没有它)。一旦我在我们支持 CUDA 的计算机上测试它,我就会用这个实现的结果更新我的问题。
  • 不客气!我认为对抗 Tensorflow 的很大一部分是弄清楚所有这些代码的含义(幸运的是,这是一个相当冗长的框架),所以我希望这将有助于解决未来的其他错误。期待速度的结果! ;)
猜你喜欢
  • 2018-06-27
  • 2017-08-13
  • 2017-01-12
  • 1970-01-01
  • 2020-01-07
  • 2017-04-19
  • 1970-01-01
  • 2018-07-05
  • 1970-01-01
相关资源
最近更新 更多