PyTorch中的池化

        池化常在卷积神经网络中使用,可以调节数据维数,抑制噪声、降低信息冗余、降低模型计算量、防止过拟合等作用。池化没有可学习的参数,与激活函数较为相似,池化在一维或多维张量上的操作与卷积层也有相似之处。

        池化最初作用是降低数据量,使模型更容易训练,称为下采样(down-sampling)或下池化。后来池化也可以增加数据大小,此时为上采样(up-smapling)或上池化。

        根据被池化的张量维数的不同,可分为一维池化、二维池化与三维池化。池化有固定的窗口,可以称为池化窗口,类似与卷积中的卷积核。需要池化窗口kernel size、步长stride、填充padding、dilation这几个参数。池化窗口表示选取的数据范围,步长表示池化窗口每次沿某个方向的长度,padding表示对input池化前是否在周围补充0,dilation为膨胀率。  

最大池化

        每次选取移动框内数的最大值,分为一维、二维和三维张量数据的池化。

        如TextCNN中卷积后的一维最大池化,每个卷积核的输出大小根据句长,步长,padding等计算获得,一维最大池化的 kernel_size 即为该值。

import torch
from torch import nn
input=torch.randint(0, 2, size=(2,2,5),dtype=torch.float32)
maxpool1d=nn.MaxPool1d(kernel_size=3, stride=1, padding=0, dilation=1)
output=maxpool1d(input)
print(input,output)

        二维数据与三维数据的最大池化,与一维情况相同,但池化窗口为2维张量或三维张量,移动步长也分为两个或三个方向,kernel_size,stride 可为元组值,如果只有一个int值则为square的。

平均池化

        前面最大池化所有的参数与意义完全相同,分为1d、2d、3d池化,输出是池化窗口所有数的平均值,而不是最大值;nn.AvgPool2d(kernel_size=(3,3),stride=(2,1),padding=0)。

LP池化

        受视觉皮层内阶层结构启发建立的池化模型。输出为池化窗口内每个数的 p 次方后求和再求均值,最后均值的1/p次方即为该部分窗口的输出结果。该函数需要参数 norm_type 指定 p 值,如果 p 为1,即与均值池化相同;如果p为无穷,则与最大池化相同。Pytorch中 LP 池化只有一维与二维两种;nn.LPPool2d(kernel_size=(2,2),stride=1,norm_type=1.5)。

自适应池化

        最终输出的size始终是函数指定的size,原理是:该函数可以根据输入size与我们指定的输出size来自动调整池化窗口、步长等参数,该函数没有kernel_size,stride,padding等参数,只需要指定输出size大小即可。如果需要让某一维度为原来大小,可以直接指定该部分参数为None;nn.AdaptiveMaxPool2d((None,2))。

随机池化

        Stochastic Pooling,自定义的一种池化方式,每次以一定的概率来选取池化窗口的值,窗口中的值越大,被选中作为输出的概率越大。需要用窗口中每一个数除以窗口中所有数的和,此时每个位置的值即为该位置被选中输出的概率。

import torch
from torch import nn
import numpy as np


class StochasticPool2d(nn.Module):
    
    def __init__(self, kernel_size, stride):
        super().__init__()
        self.kernel_size = kernel_size
        self.stride = stride

    def forward(self, input):
        b, c, h, w = input.shape
        output = []
        for B in range(b):
            batch = []
            for C in range(c):
                channel = []
                for i in range(0, h - self.kernel_size[0] + 1, self.stride[0]):
                    l = []
                    for j in range(0, w - self.kernel_size[1] + 1, self.stride[1]):
                        kernel = input[B, C, i:i + self.kernel_size[0], j:j + self.kernel_size[1]]
                        num = kernel.detach().numpy().reshape((1, -1))[0]
                        pro = (kernel / kernel.sum()).detach().numpy()
                        pro = pro.reshape((1, -1))[0]
                        out = np.random.choice(a=num, p=pro, replace=True)
                        l.append(out)
                    channel.append(l)
                batch.append(channel)
            output.append(batch)
            
        return torch.tensor(output, dtype=torch.float32)


if __name__ == '__main__':
    input = torch.randint(0, 2, size=(1, 1, 5, 5))
    pool = StochasticPool2d(kernel_size=(3, 3), stride=(1, 1))
    print(pool(input))

参考:

池化(Pooling)的种类与具体用法——基于Pytorch_pytorch 池化_生信小兔的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值