几乎与现有的 conv2d() 相同,但我想为其添加一个特殊功能。
假设我们有一个形状为 5x5 的过滤器和一个形状为 100x100 的输入。
以我的理解,conv2d() 在内部做:
- 从整个输入中选择一个 5x5 输入区域。
- 计算 5x5 输入区域和过滤器之间的卷积。
- 以给定的步幅移动到下一个输入区域。
相比之下,customized_conv2d()内部想做的事情:
- 从整个输入中选择一个 5x5 输入区域。 (同)
- 从 5x5 输入区域中的每个值中减去 f(5x5 输入区域)的标量值。 (补充)
- 计算 5x5 输入区域的相减值与过滤器之间的卷积。 (同)
- 以给定的步幅移动到下一个输入区域。 (同)
其中 f(x) 是 (max(x) + min(x))/2
- 做起来容易吗?
- 定制代码能否在 GPU 上运行?
浏览了nn_ops.py、gen_nn_ops.py、nn_ops.cc的相关源码,来求助。
提前致谢!
附加:
到目前为止我学到了什么:
1) 在 CPU 上运行的最简单方法可能是制作定制的 TensorFlow。尽可能少地调整,tensorflow/core/kernels/conv_ops.cc和 tensorflow/core/kernels/deep_conv2d.cc .有了这个特殊的 TensorFlow,conv2d() 的行为方式符合预期,而不是原来的方式。在这种情况下,通过复制相关行并将所有函数/方法从 python 包装器重命名为 c++ 代码来添加一个新的操作,例如 customized_conv2d() 可能是过度的努力。
2) 通过CUDA在GPU上运行没有希望。似乎 TensorFlow 的 conv2d() 最终调用了 cudnnConvolutionForward()在 NVIDIA CUDA 深度神经网络库 (cuDNN) 中。 conv2d() 的主要部分在此库中完成。 Software License Agreement (SLA) for NVIDIA cuDNN不允许逆向工程或修改。没有提供库的源代码。
3) 不过,通过 OpenCL 在 GPU 上运行可能还有另一种希望。
最佳答案
由于卷积本身是线性的,因此插入任何线性运算都可以通过先通过 tf.nn.conv2d
进行卷积,然后进行该运算来完成。
(max(x) + min(x))/2
在每个 5x5
补丁上可以通过 (tf.nn.max_pool(x ) - tf.nn.max_pool(-x)) * 0.5
。要在 conv 之后减去它,您还需要将结果乘以相应的卷积核之和。之后,您可以应用非线性激活函数。
但是,一般来说,我不知道如何有效地添加非线性操作,例如在卷积乘法之前获取每个 5x5
补丁的 z 分数。也许其他答案可以提供一些见解。
关于python - 如何制作自定义的 TensorFlow tf.nn.conv2d()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47968757/