Darknet与Pytorch— MaxPool/Upsample区别

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输出打印结果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值