如何在PyTorch中执行求和池

时间:2018-06-13 13:46:52

标签: conv-neural-network pytorch max-pooling spatial-pooling

如何在PyTorch中执行求和池。具体来说,如果我们输入#include <stdio.h> /* printf */ #include <stdlib.h> /* malloc, free, realloc */ #include <string.h> /* strcat */ #include <ctype.h> /* isalnum */ #include <conio.h> /* getch */ int main(void) { char add[2]; char str2[200]; char c; int temp = -1; int num = 0; char *str3; /* I just think 'count' is an int, since you didn't put it in the code, * I also deduced that @count will be used as the length of @str3 */ int count; /* Here, count is not initialized, so you MUST initialize it in order * to call malloc with it! Since it seems you want to add character by * character using realloc, then we just malloc() 2 bytes - 1 for a * character and one for the NULL terminator. */ count = 2; str3 = malloc(count); /* You will be using @strcat to append strings to @str3, so you need * to put a NULL terminator in it, because strcat will look for that * NULL byte to find where it should append */ *str3 = 0x0; while((c = getch()) != '\r') { for (int i = 0;i < 200; i++) { if (str2[i] =='\0') { num = i; break; } } if ((temp == -32) || (temp == 0)) { /* empty */ } else { if(isalnum((char)c) == 0) { if((c == '\'') || (c == -118) || (c == -115) || (c == -107) || (c == -123) || (c == -105)|| (c == 32)) { /* this is not the optimal way of using realloc, because * you should first check for errors, but will do for * this example. * You must assign the returned value of realloc to str3. * * Also, since @count contains the length * of @str3, you need to increment it. */ str3 = realloc(str3, ++count); printf("true: %c\n",c); add[1] = '\0'; add[0] = c; strcat(str3,add); strcat(str2,add); printf("str2: %s\n",str2); printf("str3: %s\n",str3); } else if (c == 8) { printf("Deleting something...\n"); } } else { /* see notes above on realloc */ str3 = realloc(str3, ++count); printf("true: %c\n",c); add[1] = '\0'; add[0] = c; strcat(str3,add); strcat(str2,add); printf("str2: %s\n",str2); printf("str3: %s\n",str3); } } printf("ASCII Code: %d\n",c); temp = c; } return 0; } 并希望输出(N, C, W_in, H_in)使用特定(N, C, W_out, H_out)kernel_size,就像stride一样?

3 个答案:

答案 0 :(得分:2)

您可以使用torch.nn.AvgPool1d(或torch.nn.AvgPool2dtorch.nn.AvgPool3d)执行平均合并 - 与总和池成比例。如果你真的想要求和值,你可以将平均输出乘以池化表面。

答案 1 :(得分:1)

要在benjaminplanche's answer上进行扩展:
我也需要求和池,并且它似乎并不直接存在,但是它等效于运行具有由1组成的weights参数的conv2d。我认为运行AvgPool2d并乘以内核大小乘积会更快。事实并非如此。

最下面的底线:
使用torch.nn.functional.avg_pool2d及其相关函数并乘以内核大小。

我在Jupyter中进行测试:

(开销)

%%timeit
x = torch.rand([1,1,1000,1000])
>>> 3.49 ms ± 4.72 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit
_=F.avg_pool2d(torch.rand([1,1,1000,1000]), [10,10])*10*10
>>> 4.99 ms ± 74.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

(所以1.50 ms±79.0 µs)(我发现*10*10仅增加了大约20 µs的图形)

avePool = nn.AvgPool2d([10, 10], 1, 0)

%%timeit
_=avePool(torch.rand([1,1,1000,1000]))*10*10
>>> 80.9 ms ± 1.57 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

(所以77.4 ms±1.58 ms)

y = torch.ones([1,1,10,10])

%%timeit
_=F.conv2d(torch.rand([1,1,1000,1000]), y)
>>> 14.4 ms ± 421 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

(所以10.9 ms±426 µs)

sumPool = nn.Conv2d(1, 1, 10, 1, 0, 1, 1, False)
sumPool.weight = torch.nn.Parameter(y)
%%timeit
_=sumPool(torch.rand([1,1,1000,1000]))
>>> 7.24 ms ± 63.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

(所以3.75 ms±68.3 µs)

作为健全性检查。

abs_err = torch.max(torch.abs(avePool(x)*10*10 - sumPool(x)))
magnitude = torch.max(torch.max(avePool(x)*10*10, torch.max(sumPool(x))))
relative_err = abs_err/magnitude
abs_err.item(), magnitude.item(), relative_err.item()
>>> (3.814697265625e-06, 62.89910125732422, 6.064788493631568e-08)

这可能是一个合理的舍入相关错误。

我不知道为什么功能版本比制作专用内核要快,但是好像您要制作专用内核,更喜欢使用Conv2D版本,并且使用sumPool.weights.requires_grad = False或{ {1}}在创建内核参数期间。这些结果可能会随内核大小而变化,因此,如果需要加快这一部分的速度,请测试您自己的应用程序。让我知道我是否错过了某件事...

答案 2 :(得分:0)

https://pytorch.org/docs/stable/generated/torch.nn.AvgPool2d.html#torch.nn.AvgPool2d找到divisor_override。
设置divisor_override = 1
你会得到一个总池

{loading || loading === undefined ? (
    <Loader />
) : (
    <Row>
        <Col className="text-center" md={12}>
            <h1>
                {`${contributor.firstName} ${contributor.lastName} ${
                    contributor.otherName || ''
                }`}
            </h1>
        </Col>
    </Row>
)}

你会得到

import torch
input = torch.tensor([[[1,2,3],[3,2,1],[3,4,5]]])
sumpool = torch.nn.AvgPool2d(2, stride=1, divisor_override=1)
sumpool(input)