如何使用 Eigen::Tensor::convolve with Multiple Kernel?
How to use Eigen::Tensor::convolve with multiple kernels?
将形状为(3, 20, 30)
(通道优先表示法)的输入张量与形状(3, 5, 7)
的8
过滤器进行卷积应该会产生形状为(8, 24, 16)
的张量。我正在尝试使用Eigen::Tensor::convolve
来实现这一点,但生成的形状是(1, 24, 16)
.因此,似乎只应用了一个过滤器,而不是所有过滤器8
。
下面是一个最小示例:
#include <cassert>
#include <iostream>
#include <eigen3/unsupported/Eigen/CXX11/Tensor>
int main() {
int input_height = 20;
int input_width = 30;
int input_channels = 3;
int kernels_height = 5;
int kernels_width = 7;
int kernels_channels = 3;
int kernel_count = 8;
assert(kernels_channels == input_channels);
int expected_output_height = input_height + 1 - kernels_height;
int expected_output_width = input_width + 1 - kernels_width;
int expected_output_channels = kernel_count;
Eigen::Tensor<float, 3> input(input_channels, input_width, input_height);
Eigen::Tensor<float, 4> filters(kernels_channels, kernels_width, kernels_height, kernel_count);
Eigen::array<ptrdiff_t, 3> dims({0, 1, 2});
Eigen::Tensor<float, 3> output = input.convolve(filters, dims);
const Eigen::Tensor<float, 3>::Dimensions& d = output.dimensions();
std::cout << "Expected output shape: (" << expected_output_channels << ", " << expected_output_width << ", " << expected_output_height << ")" << std::endl;
std::cout << "Actual shape: (" << d[0] << ", " << d[1] << ", " << d[2] << ")" << std::endl;
}
及其输出:
Expected output shape: (8, 24, 16)
Actual shape: (1, 24, 16)
当然,可以逐个迭代过滤器,并为每个过滤器调用.convolve
,但是这个
- 将导致通道不是第一维的张量
- 可能不如在一次调用中完成所有操作那样优化性能
- 需要更多自定义代码
所以我想我在使用特征库时做错了什么。如何正确完成?
它不支持一次使用多个内核的卷积(文档):
作为一部分的输出张量的维度大小 的卷积将通过公式减少:output_dim_size = input_dim_size - kernel_dim_size + 1 (要求: input_dim_size>= kernel_dim_size)。非维度的尺寸尺寸 卷积的一部分将保持不变。
根据上述expected_output_channels
应等于1 = 3 - 3 + 1
。
我认为不应该按照你的意愿去做,因为卷积运算是一个数学运算并且定义得很好,所以如果它不遵循数学定义会很奇怪。
未经测试的解决方案
我没有检查,但我相信下一个代码会如您所愿地生成输出:
Eigen::Tensor<float, 3> input(input_channels, input_width, input_height);
Eigen::Tensor<float, 4> filters(kernels_channels, kernels_width, kernels_height, kernel_count);
Eigen::Tensor<float, 3> output(kernel_count, expected_output_width, expected_output_height);
Eigen::array<ptrdiff_t, 3> dims({0, 1, 2});
for (int i = 0; i < kernel_count; ++i){
output.chip(i, 0) = input.convolve(filters.chip(i, 3), dims).chip(0, 0);
}
如您所见,第一个和第三个问题不是什么大问题。希望你会很幸运,这部分代码不会成为你的瓶颈:)
相关文章:
- C++ 链接到单独的.cpp文件说"multiple definitions"
- "multiple overloads"使用具有重复类型的模板化类
- 使用"multiple"命名空间单行
- 仅在使用 gradle 在 Travis CI 上编译时才"multiple definition" googletest 符号
- Qt5 C++中出现意外"Multiple definition"错误
- 尝试在类中编译内核,出现错误"__init__() got an unexpected keyword argument 'kernel'"
- 为什么只有一个库的链接器错误'multiple definitions'?在 Android Studio 中使用 CMake (3.4.1)
- 如何使用 Eigen::Tensor::convolve with Multiple Kernel?
- 为什么会给出"multiple test case"错误?
- "multiple definition of"链接错误
- 内核.cpp在制作 kernel.o 时显示错误和 Makefile 错误
- 编译mbed操作系统程序时"multiple definition of `main'"错误
- cyttsp4 (linux kernel) Makefile 中的错误
- C++ 使用生成文件捕获框架'multiple definition'链接器错误
- 为什么会出现"Multiple Definitions"错误
- 'Multiple Definition'错误
- 无缘无故地"Multiple definition"
- CUDA C++:文件中 kernel.cu 应有一个表达式
- 使用 Qt 创建器时出错:"multiple definition" "first defined here"
- C++:" multiple definition of 'mainCRTStartup' "错误等