maxpool
void test_maxpool_api()
{
float input[] = { 0, 0, 0, 0.5,
0, 0.1, 0, 0,
0, 0.8, 0, 0,
0, 0, 0.6, 0 };
int b, i, j, k, m, n;
int batch = 1;
int pad = 1; // size-1
int size = 2;
int stride = 1;
int stride_y = stride;
int stride_x = stride;
int w_offset = -pad / 2;
int h_offset = -pad / 2;
int h_input = 4;
int w_input = 4;
// maxpool输出大小计算公式
int h_out = (h_input + pad - size) / stride + 1;
int w_out = (w_input + pad - size) / stride + 1;
float * output = (float*)malloc(h_out*w_out * sizeof(float));
//float output[] = {};
int c = 1;
for (b = 0; b < batch; ++b) {
for (k = 0; k < c; ++k) {
for (i = 0; i < h_out; ++i) {
for (j = 0; j < w_out; ++j) {
int out_index = j + w_out*(i + h_out*(k + c*b));
float max = -FLT_MAX;
int max_i = -1;
for (n = 0; n < size; ++n) {
for (m = 0; m < size; ++m) {
int cur_h = h_offset + i*stride_y + n;
int cur_w = w_offset + j*stride_x + m;
int index = cur_w + w_input*(cur_h + h_input*(k + b*c));
int valid = (cur_h >= 0 && cur_h < h_input &&
cur_w >= 0 && cur_w < w_input);
float val = (valid != 0) ? input[index] : -FLT_MAX;
max_i = (val > max) ? index : max_i;
max = (val > max) ? val : max;
}
}
output[out_index] = max;
//if (l.indexes) l.indexes[out_index] = max_i;
}
}
}
}
printf("maxpool before: ");
for (int i = 0; i < h_out*w_out; i++)
{
if (i % 4 == 0) printf("\n");
printf("%f ", input[i]);
}
printf("\nmaxpool after: ");
for (int i = 0; i < h_out*w_out; i++)
{
if (i % 4 == 0) printf("\n");
printf("%f ", output[i]);
}
}
int main()
{
test_maxpool_api();
system("pause");
return 0;
}
输出:
maxpool before:
0.000000 0.000000 0.000000 0.500000
0.000000 0.100000 0.000000 0.000000
0.000000 0.800000 0.000000 0.000000
0.000000 0.000000 0.600000 0.000000
maxpool after: size=2 stride=1
0.100000 0.100000 0.500000 0.500000
0.800000 0.800000 0.000000 0.000000
0.800000 0.800000 0.600000 0.000000
0.000000 0.600000 0.600000 0.000000
maxpool after: size=2 stride=2
0.100000 0.500000
0.800000 0.600000
Darknet maxpool 输出打印结果
总结:
通过输出可以看到,Darkenet最大池化层,先是将右边与下边分别补一行、一列0操作,然后再进行取最大值操作。Pytorch最大池化层,如果padding=1,则是在输入的每一条边补充0。
Upsample
void test_upsample_api()
{
float input[] = { 1, 2, 3,
4, 5, 6,
7, 8, 9,};
int stride = 2;
int w = 3;
int h = 3;
int c = 1;
int batch = 1;
float scale = 1;
float *out = (float*)malloc(stride*stride*w*h * sizeof(float));
int i, j, k, b;
for (b = 0; b < batch; ++b) {
for (k = 0; k < c; ++k) {
for (j = 0; j < h*stride; ++j) {
for (i = 0; i < w*stride; ++i) {
int in_index = b*w*h*c + k*w*h + (j / stride)*w + i / stride;
int out_index = b*w*h*c*stride*stride + k*w*h*stride*stride + j*w*stride + i;
if (true) out[out_index] = scale*input[in_index];
}
}
}
}
printf("upsample before: ");
for (int i = 0; i < h*w; i++)
{
if (i % 3 == 0) printf("\n");
printf("%f ", input[i]);
}
printf("\n upsample after: ");
for (int i = 0; i < stride*stride*h*w; i++)
{
if (i % (3*stride) == 0) printf("\n");
printf("%f ", out[i]);
}
}
int main()
{
test_upsample_api();
system("pause");
return 0;
}
输出:
upsample before:
1.000000 2.000000 3.000000
4.000000 5.000000 6.000000
7.000000 8.000000 9.000000
upsample after:
1.000000 1.000000 2.000000 2.000000 3.000000 3.000000
1.000000 1.000000 2.000000 2.000000 3.000000 3.000000
4.000000 4.000000 5.000000 5.000000 6.000000 6.000000
4.000000 4.000000 5.000000 5.000000 6.000000 6.000000
7.000000 7.000000 8.000000 8.000000 9.000000 9.000000
7.000000 7.000000 8.000000 8.000000 9.000000 9.000000
Darknet Upsample输出打印结果
总结:
通过输出可以看到,Upsampe层,采用了的最近邻取值法进行上采样,与pytorch中的"nearest"算法相同。
>>> input = torch.arange(1, 5, dtype=torch.float32).view(1, 1, 2, 2)
>>> input
tensor([[[[ 1., 2.],
[ 3., 4.]]]])
>>> m = nn.Upsample(scale_factor=2, mode='nearest')
>>> m(input)
tensor([[[[ 1., 1., 2., 2.],
[ 1., 1., 2., 2.],
[ 3., 3., 4., 4.],
[ 3., 3., 4., 4.]]]])
>>> m = nn.Upsample(scale_factor=2, mode='bilinear') # align_corners=False
>>> m(input)
tensor([[[[ 1.0000, 1.2500, 1.7500, 2.0000],
[ 1.5000, 1.7500, 2.2500, 2.5000],
[ 2.5000, 2.7500, 3.2500, 3.5000],
[ 3.0000, 3.2500, 3.7500, 4.0000]]]])
>>> m = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
>>> m(input)
tensor([[[[ 1.0000, 1.3333, 1.6667, 2.0000],
[ 1.6667, 2.0000, 2.3333, 2.6667],
[ 2.3333, 2.6667, 3.0000, 3.3333],
[ 3.0000, 3.3333, 3.6667, 4.0000]]]])
Pytorch Upsample输出打印结果