【发布时间】:2021-10-05 21:53:33
【问题描述】:
我需要做一个执行 2D 卷积的函数,为此我需要将几个 3d 数组传递给它。但是,有人告诉我,我的方法不是执行此操作的理想方法。
首先,我声明变量:
typedef struct {
float img[224][224][3];
} input_224_t;
typedef struct {
float img[112][112][32];
} input_112_t;
typedef struct {
float img[3][3][32];
} weightsL1_t;
然后,卷积看起来像这样:
void convolution(input_224_t* N, weightsL1_t* M, input_112_t* P, int size, int ksize, int channels, int filters, int stride)
{
// Effectively pads the image before convolution. Technically also works for pointwise, but it's inefficient.
// find center position of kernel (half of kernel size)
int kcenter = ksize / 2;
// Declare output indexes
int a = 0;
int b = -1;
for (int k = 0; k < filters; ++k) // filters
{
for (int i = 0; i < size; i = i + stride) // rows
{
for (int j = 0; j < size; j = j + stride) // columns
{
b++;
if (b == ksize) {b=0;a++;} // Increment output index
for (int m = 0; m < ksize; ++m) // kernel rows
{
for (int n = 0; n < ksize; ++n) // kernel columns
{
// Index of input signal, used for checking boundary
int ii = i + (m - kcenter);
int jj = j + (n - kcenter);
// Ignore input samples which are out of bound
if (ii >= 0 && ii < size && jj >= 0 && jj < size) {
for (int p = 0; p < channels; ++p) // channels
{
P.img[a][b][k] += N.img[ii][jj][p] * M.img[m][n][k]; // convolve
}
}
}
}
}
}
}
}
(这会在“convolve”行返回“field 'img' could not be resolved”)
然后我将值导入到正确的结构中(这是我之前的一个问题,已经回答:Write values to a 3D array inside a struct in C),然后我这样调用函数:
convolution(test_image, test_filter, test_result, 6, 3, 1, 1, 2);
我在上一个问题中被告知,这不是处理 3D 数组的理想方式,而且它可能使用比我预期更多的内存。这是一个非常消耗内存的过程,并且会在嵌入式系统中运行,因此优化内存分配至关重要。
如果可能的话,我的目标是在任何时间点只分配这些 3D 数组中的一个,以便不使用不必要的内存,并以这种空间可以稍后释放。
提前谢谢你。
【问题讨论】:
-
内核应该是 4 维的,
float[3][3][3][32]。每个输出通道都应该使用单独的内核? -
不要使用
_t作为 typedef 后缀。 gnu.org/software/libc/manual/html_node/Reserved-Names.html -
@tstanisl 没错,2D 卷积有 4-dim 内核。我查看了我生成的权重并假设相反,但你是对的。
-
@WilliamPursell 真的吗?我被告知这是一个很好的做法,显然情况恰恰相反。谢谢你告诉我。
标签: c multidimensional-array convolution