使用Tensorflow进行预处理的3D卷积

3
我为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]

然后我使用自定义函数创建一个三维核,并定义三维卷积:

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') - GPhilo
1
错误意味着没有实现该特定输入类型组合的Conv3D操作。您的内核类型为int,但是根据错误消息,可用于浮点数和双精度数的内核至少是可用的。 - GPhilo
根据速度问题,看起来这些操作仅在CPU上实现(再次阅读错误消息)。尝试查看速度是否有所提高。另外一个问题:您是否正在使用Tensorflow的GPU版本?因为错误代码中的“Registered Devices:[CPU]”似乎意味着Tensorflow无法识别您的GPU... - GPhilo
1
好的,在内核和堆栈中都切换到“float32”确实起作用,谢谢。但是现在卷积比scikit图像实现要慢得多。我正在我的笔记本电脑上编写代码,但将在带有GPU的计算机上运行实际训练,不用担心 ;) - McMa
1个回答

4

我将在以下内容中帮助排列解决方案,以便其他人能更好地理解。

解析错误信息:

您的错误信息:

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操作,在您的机器上有2个可用实现。一个在CPU上运行,输入为float32张量(DT_FLOAT),而另一个也在CPU上运行,以float64张量(DT_DOUBLE)作为输入。
注意:Registered devices: [CPU]表明您的Tensorflow没有看到您的GPU(您是否安装了Tensorflow的仅CPU版本?)。
您的问题的答案:
“这个错误是什么意思,我如何实现三维卷积?”
我认为在前面的部分已经解释了错误。您不想自己实现Conv3D,而是更改输入类型为已经有实现的类型。将StackTF_kernel的类型都更改为float32float64(例如,使用kernel=np.ones((11,11,11,1,1),dtype='float32')定义kernel)。
“我假设在tensorflow中实现这一点(目前使用scikit-image实现)对执行速度有好处吗?”
很难说。由于这两个实现都仅限于CPU,我猜尝试并查看是否有改进是最好的选择(如果您能在此之后更新您的问题并让我们知道是否确实加速了,那就太好了)。
我还建议检查您是否使用了GPU Tensorflow版本,如果没有,请切换到该版本(这有更高的几率加速您的计算)。

感谢您的解释,有时候这种错误对我来说很难理解! 我目前正在我的笔记本电脑上编写和测试这些程序,没有GPU(因此在错误信息中缺少它)。一旦我在我们支持CUDA的计算机上测试过后,我会更新我的问题并分享实现结果。 - McMa
不用谢!我认为应对Tensorflow的一个重要部分是弄清楚所有这些代码的含义(幸运的是,它是一个相当冗长的框架),所以我希望这将有助于解决未来的其他错误。期待速度结果!;) - GPhilo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接