精华内容
下载资源
问答
  • nn.maxpool2d
    千次阅读
    2021-08-10 09:18:20

    引言

    torch.nn.MaxPool2dtorch.nn.functional.max_pool2d,在pytorch构建模型中,都可以作为最大池化层的引入,但前者为类模块,后者为函数,在使用上存在不同。

    1. torch.nn.functional.max_pool2d

    pytorch中的函数,可以直接调用,源码如下:

    def max_pool2d_with_indices(
        input: Tensor, kernel_size: BroadcastingList2[int],
        stride: Optional[BroadcastingList2[int]] = None,
        padding: BroadcastingList2[int] = 0,
        dilation: BroadcastingList2[int] = 1,
        ceil_mode: bool = False,
        return_indices: bool = False
    ) -> Tuple[Tensor, Tensor]:
        r"""Applies a 2D max pooling over an input signal composed of several input
        planes.
    
        See :class:`~torch.nn.MaxPool2d` for details.
        """
        if has_torch_function_unary(input):
            return handle_torch_function(
                max_pool2d_with_indices,
                (input,),
                input,
                kernel_size,
                stride=stride,
                padding=padding,
                dilation=dilation,
                ceil_mode=ceil_mode,
                return_indices=return_indices,
            )
        if stride is None:
            stride = torch.jit.annotate(List[int], [])
        return torch._C._nn.max_pool2d_with_indices(input, kernel_size, stride, padding, dilation, ceil_mode)
    
    
    def _max_pool2d(
        input: Tensor, kernel_size: BroadcastingList2[int],
        stride: Optional[BroadcastingList2[int]] = None,
        padding: BroadcastingList2[int] = 0,
        dilation: BroadcastingList2[int] = 1,
        ceil_mode: bool = False,
        return_indices: bool = False
    ) -> Tensor:
        if has_torch_function_unary(input):
            return handle_torch_function(
                max_pool2d,
                (input,),
                input,
                kernel_size,
                stride=stride,
                padding=padding,
                dilation=dilation,
                ceil_mode=ceil_mode,
                return_indices=return_indices,
            )
        if stride is None:
            stride = torch.jit.annotate(List[int], [])
        return torch.max_pool2d(input, kernel_size, stride, padding, dilation, ceil_mode)
    
    
    max_pool2d = boolean_dispatch(
        arg_name="return_indices",
        arg_index=6,
        default=False,
        if_true=max_pool2d_with_indices,
        if_false=_max_pool2d,
        module_name=__name__,
        func_name="max_pool2d",
    )
    

    使用如下:

    import torch.nn.functional as F
    input = torch.randn(20, 16, 50, 32)  # 输入张量
    F.max_pool2d(input, kernel_size=2, stride=1,padding=0)
    """
    其中:
    Shape:
            - Input: :math:`(N, C, H_{in}, W_{in})`
            - Output: :math:`(N, C, H_{out}, W_{out})`, where
    """
    

    2. torch.nn.MaxPool2d

    pytorch中的类模块,先实例化,再调用其函数,源码如下(笔者已将源码中的注释简化):

    class MaxPool2d(_MaxPoolNd):
    
        kernel_size: _size_2_t
        stride: _size_2_t
        padding: _size_2_t
        dilation: _size_2_t
    
        def forward(self, input: Tensor) -> Tensor:
            return F.max_pool2d(input, self.kernel_size, self.stride,
                                self.padding, self.dilation, self.ceil_mode,
                                self.return_indices)
    

    使用如下:

    import torch
    m = torch.nn.MaxPool2d(3, stride=2)  # 实例化
    # 或者
    m = torch.nn.MaxPool2d((3, 2), stride=(2, 1))  # 实例化
    input = torch.randn(20, 16, 50, 32)  # 输入张量
    output = m(input) # 使用该类
    """
        Shape:
            - Input: :math:`(N, C, H_{in}, W_{in})`
            - Output: :math:`(N, C, H_{out}, W_{out})`, where
    """
    

    3. 对比类和函数的使用

    通过上述比较,torch.nn.functional.max_pool2d作为函数可以直接调用,传入参数(input(四个维度的输入张量), kernel_size(卷积核尺寸), stride(步幅),padding(填充), dilation, ceil_mode,return_indices)即可。
    torch.nn.MaxPool2d,要先实例化,并在forward调用了torch.nn.functional.max_pool2d函数。
    综上:torch.nn.functional.max_pool2d函数包含于torch.nn.MaxPool2d类模块中,可以单独使用,也可以实例化类再使用。
    在模型构建下的使用:
    (1)使用类模块

    import torch
    class Net(torch.nn.Module):
        def __init__(self):
            super(Net, self).__init__()
            self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5)
            self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5)
            self.pooling = torch.nn.MaxPool2d(2)  # kernel_size = 2,实例化
            self.fc = torch.nn.Linear(320, 10)
    
        def forward(self, x):
            # Flatten data from(n,1,28,28) to (n,784)
            batch_size = x.s(0)
            x = F.relu(self.pooling(self.conv1(x)))
            x = F.relu(self.pooling(self.conv2(x)))
            x = x.view(batch_size, -1)
            x = self.fc(x)
            return x
    

    说明:kernel_size 是必须要指定的参数,否则会报错
    笔者修改了torch.nn.MaxPool2d的源码,说明传入参数要求(记得改回来!):
    在这里插入图片描述

    import torch
    pooling1 = torch.nn.MaxPool2d(1,2,3,4)
    print(pooling1)
    pooling2 = torch.nn.MaxPool2d(1)
    print(pooling2)
    

    输出为

    MaxPool2d(kernel_size=1, stride=2, padding=3, dilation=4, ceil_mode=False)
    MaxPool2d(kernel_size=1, stride=1, padding=0, dilation=1, ceil_mode=False)
    

    (2)直接调用函数

    import torch
    import torch.nn.functional as F
    class Net(torch.nn.Module):
        def __init__(self):
            super(Net, self).__init__()
            self.conv1 = torch.nn.Conv2d(1, 10, kernel_size=5)
            self.conv2 = torch.nn.Conv2d(10, 20, kernel_size=5)
            # 最大池化层无需实例化,直接在forward中调用
            self.fc = torch.nn.Linear(320, 10)
    
        def forward(self, x):
            # Flatten data from(n,1,28,28) to (n,784)
            batch_size = x.s(0)
            x = F.relu(F.max_pool2d(self.conv1(x), kernel_size=2))  # 一定要指定kernel_size
            x = F.relu(F.max_pool2d(self.conv2(x), kernel_size=2))
            x = x.view(batch_size, -1)
            x = self.fc(x)
            return x
    
    更多相关内容
  • torch.nn.MaxPool2d详解

    万次阅读 多人点赞 2020-11-22 20:18:38
    之后我们验证一下 stride 参数: import torch import torch.nn as nn # 仅定义一个 3x3 的池化层窗口 m = nn.MaxPool2d(kernel_size=(3, 3), stride=(2, 2)) # 定义输入 # 四个参数分别表示 (batch_size, C_in, H_...

    注意:这里展示的是本篇博文写时的版本最新的实现,但是后续会代码可能会迭代更新,建议对照官方文档进行学习。

    先来看源码:

    # 这个类是是许多池化类的基类,这里有必要了解一下
    class _MaxPoolNd(Module):
        __constants__ = ['kernel_size', 'stride', 'padding', 'dilation',
                         'return_indices', 'ceil_mode']
        return_indices: bool
        ceil_mode: bool
    	# 构造函数,这里只需要了解这个初始化函数即可。
        def __init__(self, kernel_size: _size_any_t, stride: Optional[_size_any_t] = None,
                     padding: _size_any_t = 0, dilation: _size_any_t = 1,
                     return_indices: bool = False, ceil_mode: bool = False) -> None:
            super(_MaxPoolNd, self).__init__()
            self.kernel_size = kernel_size
            self.stride = stride if (stride is not None) else kernel_size
            self.padding = padding
            self.dilation = dilation
            self.return_indices = return_indices
            self.ceil_mode = ceil_mode
    
        def extra_repr(self) -> str:
            return 'kernel_size={kernel_size}, stride={stride}, padding={padding}' \
                ', dilation={dilation}, ceil_mode={ceil_mode}'.format(**self.__dict__)
    
    class MaxPool2d(_MaxPoolNd):
        kernel_size: _size_2_t
        stride: _size_2_t
        padding: _size_2_t
        dilation: _size_2_t
    
        def forward(self, input: Tensor) -> Tensor:
            return F.max_pool2d(input, self.kernel_size, self.stride,
                                self.padding, self.dilation, self.ceil_mode,
                                self.return_indices)
    

    MaxPool2d 这个类的实现十分简单。

    我们先来看一下基本参数,一共六个:

    1. kernel_size :表示做最大池化的窗口大小,可以是单个值,也可以是tuple元组
    2. stride :步长,可以是单个值,也可以是tuple元组
    3. padding :填充,可以是单个值,也可以是tuple元组
    4. dilation :控制窗口中元素步幅
    5. return_indices :布尔类型,返回最大值位置索引
    6. ceil_mode :布尔类型,为True,用向上取整的方法,计算输出形状;默认是向下取整。

    关于 kernel_size 的详解

    注意这里的 kernel_size 跟卷积核不是一个东西。 kernel_size 可以看做是一个滑动窗口,这个窗口的大小由自己指定,如果输入是单个值,例如 3 3 3 ,那么窗口的大小就是 3 × 3 3 \times 3 3×3 ,还可以输入元组,例如 (3, 2) ,那么窗口大小就是 3 × 2 3 \times 2 3×2

    最大池化的方法就是取这个窗口覆盖元素中的最大值。

    关于 stride 的详解

    上一个参数我们确定了滑动窗口的大小,现在我们来确定这个窗口如何进行滑动。如果不指定这个参数,那么默认步长跟最大池化窗口大小一致。如果指定了参数,那么将按照我们指定的参数进行滑动。例如 stride=(2,3) , 那么窗口将每次向右滑动三个元素位置,或者向下滑动两个元素位置。

    关于 padding 的详解

    这参数控制如何进行填充,填充值默认为0。如果是单个值,例如 1,那么将在周围填充一圈0。还可以用元组指定如何填充,例如 p a d d i n g = ( 2 , 1 ) padding=(2, 1) padding=(2,1) ,表示在上下两个方向个填充两行0,在左右两个方向各填充一列0。

    关于 dilation 的详解

    不会

    关于 return_indices 的详解

    这是个布尔类型值,表示返回值中是否包含最大值位置的索引。注意这个最大值指的是在所有窗口中产生的最大值,如果窗口产生的最大值总共有5个,就会有5个返回值。

    关于 ceil_mode 的详解

    这个也是布尔类型值,它决定的是在计算输出结果形状的时候,是使用向上取整还是向下取整。怎么计算输出形状,下面会讲到。一看就知道了。

    ——————————————参数解析结束分界线——————————————

    最大池化层输出形状计算
    H o u t = ⌊ H i n + 2 × p a d d i n g ⌊ 0 ⌋ − d i l a t i o n ⌊ 0 ⌋ × ( k e r n e l _ s i z e ⌊ 0 ⌋ − 1 ) − 1 s t r i d e ⌊ 0 ⌋ + 1 ⌋ H_{out}=\lfloor \frac{H_{in} + 2 \times padding\lfloor 0 \rfloor - dilation \lfloor 0 \rfloor \times (kernel\_size\lfloor 0 \rfloor - 1)-1}{stride\lfloor 0 \rfloor} + 1 \rfloor Hout=stride0Hin+2×padding0dilation0×(kernel_size01)1+1

    W o u t = ⌊ W i n + 2 × p a d d i n g ⌊ 1 ⌋ − d i l a t i o n ⌊ 1 ⌋ × ( k e r n e l _ s i z e ⌊ 1 ⌋ − 1 ) − 1 s t r i d e ⌊ 1 ⌋ + 1 ⌋ W_{out}=\lfloor \frac{W_{in} + 2 \times padding\lfloor 1 \rfloor - dilation \lfloor 1 \rfloor \times (kernel\_size\lfloor 1 \rfloor - 1)-1}{stride\lfloor 1 \rfloor} + 1 \rfloor Wout=stride1Win+2×padding1dilation1×(kernel_size11)1+1

    看到向下取整的符号了吗?这个就是由 ceil_mode 控制的。

    ——————————————结束分界线——————————————

    下面我们写代码验证一下最大池化层是如何计算的:

    首先验证 kernel_size 参数

    import torch
    import torch.nn as nn
    
    # 仅定义一个 3x3 的池化层窗口
    m = nn.MaxPool2d(kernel_size=(3, 3))
    
    # 定义输入
    # 四个参数分别表示 (batch_size, C_in, H_in, W_in)
    # 分别对应,批处理大小,输入通道数,图像高度(像素),图像宽度(像素)
    # 为了简化表示,我们只模拟单张图片输入,单通道图片,图片大小是6x6
    input = torch.randn(1, 1, 6, 6)
    
    print(input)
    
    output = m(input)
    
    print(output)
    

    结果:
    在这里插入图片描述

    第一个tensor是我们的输入数据 1 × 1 × 6 × 6 1 \times 1 \times 6 \times 6 1×1×6×6 ,我们画红线的区域就是我们设置的窗口大小 3 × 3 3 \times 3 3×3 ,背景色为红色的值,为该区域的最大值。

    第二个tensor就是我们最大池化后的结果,跟我们标注的一模一样。

    这个就是最基本的最大池化。

    之后我们验证一下 stride 参数

    import torch
    import torch.nn as nn
    
    # 仅定义一个 3x3 的池化层窗口
    m = nn.MaxPool2d(kernel_size=(3, 3), stride=(2, 2))
    
    # 定义输入
    # 四个参数分别表示 (batch_size, C_in, H_in, W_in)
    # 分别对应,批处理大小,输入通道数,图像高度(像素),图像宽度(像素)
    # 为了简化表示,我们只模拟单张图片输入,单通道图片,图片大小是6x6
    input = torch.randn(1, 1, 6, 6)
    
    print(input)
    
    output = m(input)
    
    print(output)
    

    结果:

    在这里插入图片描述

    红色的还是我们的窗口,但是我们的步长变为了2,可以看到第一个窗口和向右滑动后的窗口,他们的最大值刚好是重叠的部分都是2.688,向下滑动之后,最大值是0.8030,再次向右滑动,最大值是2.4859。

    可以看到我们在滑动的时候省略了部分数值,因为剩下的数据不够一次滑动了,于是我们将他们丢弃了。

    其实最后图片的宽度和高度还可以通过上面两个公式来计算,我们公式中用的是向下取整,因此我们丢弃了不足的数据。现在我们试试向上取整。

    利用 ceil_mode 参数向上取整

    import torch
    import torch.nn as nn
    
    # 仅定义一个 3x3 的池化层窗口
    m = nn.MaxPool2d(kernel_size=(3, 3), stride=(2, 2), ceil_mode=True)
    
    # 定义输入
    # 四个参数分别表示 (batch_size, C_in, H_in, W_in)
    # 分别对应,批处理大小,输入通道数,图像高度(像素),图像宽度(像素)
    # 为了简化表示,我们只模拟单张图片输入,单通道图片,图片大小是6x6
    input = torch.randn(1, 1, 6, 6)
    
    print(input)
    
    output = m(input)
    
    print('\n\n\n\n\n')
    
    print(output)
    

    结果:

    在这里插入图片描述

    从结果可以看出,输出的size由原来的 2 × 2 2 \times 2 2×2 变成了现在的 3 × 3 3 \times 3 3×3 。这就是向上取整的结果。为什么会出现这样的结果呢?

    这看起来像是我们对输入进行了填充,但是这个填充值不会参与到计算最大值中。

    继续验证 padding 参数

    import torch
    import torch.nn as nn
    
    # 仅定义一个 3x3 的池化层窗口
    m = nn.MaxPool2d(kernel_size=(3, 3), stride=(3, 3), padding=(1, 1))
    
    # 定义输入
    # 四个参数分别表示 (batch_size, C_in, H_in, W_in)
    # 分别对应,批处理大小,输入通道数,图像高度(像素),图像宽度(像素)
    # 为了简化表示,我们只模拟单张图片输入,单通道图片,图片大小是6x6
    input = torch.randn(1, 1, 6, 6)
    
    print(input)
    
    output = m(input)
    
    print('\n\n')
    
    print(output)
    

    结果:

    在这里插入图片描述

    我们对周围填充了一圈0,我们滑动窗口的范围就变化了,这就是填充的作用。

    但是有一点需要注意,就是即使我们填充了0,这个0也不会被选为最大值。例如上图的左上角四个数据,如果我们全部变为负数,结果是-0.1711,而不会是我们填充的0值,这一点要注意。

    最后验证 return_indices 参数:

    import torch
    import torch.nn as nn
    
    # 仅定义一个 3x3 的池化层窗口
    m = nn.MaxPool2d(kernel_size=(3, 3), return_indices=True)
    
    # 定义输入
    # 四个参数分别表示 (batch_size, C_in, H_in, W_in)
    # 分别对应,批处理大小,输入通道数,图像高度(像素),图像宽度(像素)
    # 为了简化表示,我们只模拟单张图片输入,单通道图片,图片大小是6x6
    input = torch.randn(1, 1, 6, 6)
    
    print(input)
    
    output = m(input)
    
    print(output)
    

    结果:

    在这里插入图片描述

    仅仅是多返回了一个位置信息。元素位置从0开始计数,6表示第7个元素,9表示第10个元素…需要注意的是,返回值实际上是多维的数据,但是我们只看相关的元素位置信息,忽略维度的问题。

    最后一个参数 dilation ,不会

    展开全文
  • 卷积神经网络中nn.Conv2d()和nn.MaxPool2d() 卷积神经网络之Pythorch实现: nn.Conv2d()就是PyTorch中的卷积模块 参数列表 参数 作用 in_channels 输入数据体的深度 out_channels 输出数 据体的深度 ...

    卷积神经网络中nn.Conv2d()和nn.MaxPool2d()

    卷积神经网络之Pythorch实现:

    nn.Conv2d()就是PyTorch中的卷积模块

    参数列表

    参数作用
    in_channels输入数据体的深度
    out_channels输出数 据体的深度
    kernel_size滤波器(卷积核)的大小 注1
    stride滑动的步长
    padding零填充的圈数 注2
    bias是否启用偏置,默认是True,代表启用
    groups输出数据体深度上和输入数 据体深度上的联系 注3
    dilation卷积对于输入数据体的空间间隔 注4

    注:1. 可以使用一 个数字来表示高和宽相同的卷积核,比如 kernel_size=3,也可以使用 不同的数字来表示高和宽不同的卷积核,比如 kernel_size=(3, 2);

    1. padding=0表示四周不进行零填充,而 padding=1表示四周进行1个像素点的零填充;

    2. groups表示输出数据体深度上和输入数 据体深度上的联系,默认 groups=1,也就是所有的输出和输入都是相 关联的,如果 groups=2,这表示输入的深度被分割成两份,输出的深 度也被分割成两份,它们之间分别对应起来,所以要求输出和输入都 必须要能被 groups整除。

    3. 默认dilation=1详情见 nn.Conv2d()中dilation参数的作用或者CSDN

    nn.MaxPool2d()表示网络中的最大值池化

    参数列表:

    参数作用
    kernel_size与上面nn.Conv2d()相同
    stride与上面nn.Conv2d()相同
    padding与上面nn.Conv2d()相同
    dilation与上面nn.Conv2d()相同
    return_indices表示是否返回最大值所处的下标,默认 return_indices=False
    ceil_mode表示使用一些方格代替层结构,默认 ceil_mode=False

    注:一般不会去设置return_indicesceil_mode参数

    import torch.nn as nn
    
    
    class SimpleCNN(nn.Module):
        def __init__(self):
            super(SimpleCNN, self).__init__()
            layer1 = nn.Sequential()
            # 把一个三通道的照片RGB三个使用32组卷积核卷积,每组三个卷积核,组内卷积后相加得出32组输出
            layer1.add_module('conv1', nn.Conv2d(3, 32, (3, 3), (1, 1), padding=1))
            layer1.add_module('relu1', nn.ReLU(True))
            layer1.add_module('pool1', nn.MaxPool2d(2, 2))
            self.layer1 = layer1
    
            layer2 = nn.Sequential()
            layer2.add_module('conv2', nn.Conv2d(32, 64, (3, 3), (1, 1), padding=1))
            layer2.add_module('relu2', nn.ReLU(True))
            layer2.add_module('pool2', nn.MaxPool2d(2, 2))
            self.layer2 = layer2
    
            layer3 = nn.Sequential()
            layer3.add_module('conv3', nn.Conv2d(64, 128, (3, 3), (1, 1), padding=1))
            layer3.add_module('relu3', nn.ReLU(True))
            layer3.add_module('pool3', nn.MaxPool2d(2, 2))
            self.layer3 = layer3
    
            layer4 = nn.Sequential()
            layer4.add_module('fc1', nn.Linear(2048, 512))
            layer4.add_module('fc_relu1', nn.ReLU(True))
            layer4.add_module('fc2', nn.Linear(512, 64))
            layer4.add_module('fc_relu2', nn.ReLU(True))
            layer4.add_module('f3', nn.Linear(64, 10))
            self.layer4 = layer4
    
        def forward(self, x):
            conv1 = self.layer1(x)
            conv2 = self.layer2(conv1)
            conv3 = self.layer3(conv2)
            fc_input = conv3.view(conv3.size(0), -1)
            fc_out = self.layer4(fc_input)
            return fc_out
    
    model = SimpleCNN()
    print(model)
    

    输出

    SimpleCNN(
      (layer1): Sequential(
        (conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (relu1): ReLU(inplace=True)
        (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
      )
      (layer2): Sequential(
        (conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1))
        (relu2): ReLU(inplace=True)
        (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
      )
      (layer3): Sequential(
        (conv3): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (relu3): ReLU(inplace=True)
        (pool3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
      )
      (layer4): Sequential(
        (fc1): Linear(in_features=2048, out_features=512, bias=True)
        (fc_relu1): ReLU(inplace=True)
        (fc2): Linear(in_features=512, out_features=64, bias=True)
        (fc_relu2): ReLU(inplace=True)
        (f3): Linear(in_features=64, out_features=10, bias=True)
      )
    )
    

    提取模型的层级结构

    提取层级结构可以使用以下几个nn.Model的属性,第一个是children()属性,它会返回下一级模块的迭代器,在上面这个模型中,它会返回在self.layer1,self.layer2,self.layer4上的迭代器而不会返回它们内部的东西;modules()
    会返回模型中所有的模块的迭代器,这样它就能访问到最内层,比如self.layer1.conv1这个模块;还有一个与它们相对应的是name_children()属性以及named_modules(),这两个不仅会返回模块的迭代器,还会返回网络层的名字。

    提取出model中的前两层

    nn.Sequential(*list(model.children())[:2])
    

    输出:

    Sequential(
      (0): Sequential(
        (conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (relu1): ReLU(inplace=True)
        (pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
      )
      (1): Sequential(
        (conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
        (relu2): ReLU(inplace=True)
        (pool2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
      )
    )
    

    提取出model中的所有卷积层

    conv_model = nn.Sequential()
    for layer in model.named_modules():
        if isinstance(layer[1], nn.Conv2d):
            conv_model.add_module(layer[0].split('.')[1] ,layer[1])
    print(conv_model)
    

    输出:

    Sequential(
      (conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
      (conv3): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    )
    

    提取网络参数并对其初始化

    nn.Moudel里面有两个特别重要的关于参数的属性,分别是named_parameters()parameters()。前者会输出网络层的名字和参数的迭代器,后者会给出一个网络的全部参数的迭代器。

    for param in model.named_parameters():
        print(param[0])
        # print(param[1])
    

    输出:

    layer1.conv1.weight
    layer1.conv1.bias
    layer2.conv2.weight
    layer2.conv2.bias
    layer3.conv3.weight
    layer3.conv3.bias
    layer4.fc1.weight
    layer4.fc1.bias
    layer4.fc2.weight
    layer4.fc2.bias
    layer4.f3.weight
    layer4.f3.bias
    

    主流神经网络案例分析

    案例:使用卷积神经网络实现对Minist数据集的预测

    import matplotlib.pyplot as plt
    import torch.utils.data
    import torchvision.datasets
    import os
    import torch.nn as nn
    from torchvision import transforms
    
    
    class CNN(nn.Module):
        def __init__(self):
            super(CNN, self).__init__()
            self.layer1 = nn.Sequential(
                nn.Conv2d(1, 16, kernel_size=(3, 3)),
                nn.BatchNorm2d(16),
                nn.ReLU(inplace=True),
            )
    
            self.layer2 = nn.Sequential(
                nn.Conv2d(16, 32, kernel_size=(3, 3)),
                nn.BatchNorm2d(32),
                nn.ReLU(inplace=True),
                nn.MaxPool2d(kernel_size=2, stride=2),
            )
    
            self.layer3 = nn.Sequential(
                nn.Conv2d(32, 64, kernel_size=(3, 3)),
                nn.BatchNorm2d(64),
                nn.ReLU(inplace=True)
            )
    
            self.layer4 = nn.Sequential(
                nn.Conv2d(64, 128, kernel_size=(3, 3)),
                nn.BatchNorm2d(128),
                nn.ReLU(inplace=True),
                nn.MaxPool2d(kernel_size=2, stride=2)
            )
    
            self.fc = nn.Sequential(
                nn.Linear(128 * 4 * 4, 1024),
                nn.ReLU(inplace=True),
                nn.Linear(1024, 128),
                nn.Linear(128, 10)
            )
    
        def forward(self, x):
            x = self.layer1(x)
            x = self.layer2(x)
            x = self.layer3(x)
            x = self.layer4(x)
            x = x.view(x.size(0), -1)
            x = self.fc(x)
            return x
    
    
    
    os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
    
    data_tf = transforms.Compose(
        [transforms.ToTensor(),
         transforms.Normalize([0.5], [0.5])]
    )
    
    train_dataset = torchvision.datasets.MNIST(root='F:/机器学习/pytorch/书/data/mnist', train=True,
                                               transform=data_tf, download=True)
    
    test_dataset = torchvision.datasets.MNIST(root='F:/机器学习/pytorch/书/data/mnist', train=False,
                                              transform=data_tf, download=True)
    
    batch_size = 100
    train_loader = torch.utils.data.DataLoader(
        dataset=train_dataset, batch_size=batch_size
    )
    
    test_loader = torch.utils.data.DataLoader(
        dataset=test_dataset, batch_size=batch_size
    )
    
    model = CNN()
    model = model.cuda()
    criterion = nn.CrossEntropyLoss()
    criterion = criterion.cuda()
    optimizer = torch.optim.Adam(model.parameters())
    
    # 节约时间,三次够了
    iter_step = 3
    loss1 = []
    loss2 = []
    for step in range(iter_step):
        loss1_count = 0
        loss2_count = 0
        for images, labels in train_loader:
            images = images.cuda()
            labels = labels.cuda()
            images = images.reshape(-1, 1, 28, 28)
            output = model(images)
            pred = output.squeeze()
    
            optimizer.zero_grad()
            loss = criterion(pred, labels)
            loss.backward()
            optimizer.step()
    
            _, pred = torch.max(pred, 1)
    
            loss1_count += int(torch.sum(pred == labels)) / 100
    # 测试
        else:
            test_loss = 0
            accuracy = 0
            with torch.no_grad():
                for images, labels in test_loader:
                    images = images.cuda()
                    labels = labels.cuda()
                    pred = model(images.reshape(-1, 1, 28, 28))
                    _, pred = torch.max(pred, 1)
                    loss2_count += int(torch.sum(pred == labels)) / 100
    
        loss1.append(loss1_count / len(train_loader))
        loss2.append(loss2_count / len(test_loader))
    
        print(f'第{step}次训练:训练准确率:{loss1[len(loss1)-1]},测试准确率:{loss2[len(loss2)-1]}')
    
    plt.plot(loss1, label='Training loss')
    plt.plot(loss2, label='Validation loss')
    plt.legend()
    

    输出:

    第0次训练:训练准确率:0.9646166666666718,测试准确率:0.9868999999999996
    第1次训练:训练准确率:0.9865833333333389,测试准确率:0.9908999999999998
    第2次训练:训练准确率:0.9917000000000039,测试准确率:0.9879999999999994
    <matplotlib.legend.Legend at 0x21f03092fd0>
    

    展开全文
  • torch.nn.MaxPool2d参数详解

    千次阅读 2021-09-05 10:28:12
    MaxPool2d的使用方法。 API官网文档 MaxPool2d 参数介绍 kernel_size :表示做最大池化的窗口大小,可以是单个值,也可以是tuple元组 stride :步长,可以是单个值,也可以是tuple元组 padding :填充,可以是...

    在神经网络中 池化层是比较重要的,是提取重要信息的操作,可以去掉不重要的信息,减少计算开销。下面我们来介绍
    MaxPool2d的使用方法。

    API官网文档

    在这里插入图片描述
    在这里插入图片描述

    MaxPool2d 参数介绍

    • kernel_size :表示做最大池化的窗口大小,可以是单个值,也可以是tuple元组
    • stride :步长,可以是单个值,也可以是tuple元组
    • padding :填充,可以是单个值,也可以是tuple元组
    • dilation :控制窗口中元素步幅
    • return_indices :布尔类型,返回最大值位置索引
    • ceil_mode :布尔类型,为True,用向上取整的方法,计算输出形状;默认是向下取整。

    kernel_size 的详解

    注意这里的 kernel_size 跟卷积核不是一个东西。 kernel_size 可以看做是一个滑动窗口,这个窗口的大小由自己指定,如果输入是单个值,例如 3 ,那么窗口的大小就是 3 × 3 3 ,还可以输入元组,例如 (3, 2) ,那么窗口大小就是 3 × 2。
    最大池化的方法就是取这个窗口覆盖元素中的最大值

    stride 的详解

    上一个参数我们确定了滑动窗口的大小,现在我们来确定这个窗口如何进行滑动。如果不指定这个参数,那么默认步长跟最大池化窗口大小一致。如果指定了参数,那么将按照我们指定的参数进行滑动。例如 stride=(2,3) , 那么窗口将每次向右滑动三个元素位置,或者向下滑动两个元素位置

    padding 的详解

    这参数控制如何进行填充,填充值默认为0。如果是单个值,例如 1,那么将在周围填充一圈0。还可以用元组指定如何填充,例如 padding = ( 2 , 1 ) padding=(2, 1)padding=(2,1) ,表示在上下两个方向个填充两行0,在左右两个方向各填充一列0。

    dilation 的详解

    空洞卷积,默认 dilation=1,如果kernel_size =3,那么卷积核就是33的框。如果dilation = 2,kernel_size =3,那么每列数据与每列数据中间再加一列空洞,那么卷积核就变成55的框。

    return_indices 的详解

    这是个布尔类型值,表示返回值中是否包含最大值位置的索引。注意这个最大值指的是在所有窗口中产生的最大值,如果窗口产生的最大值总共有5个,就会有5个返回值。

    ceil_mode 的详解

    这个也是布尔类型值,它决定的是在计算输出结果形状的时候,是使用向上取整还是向下取整。怎么计算输出形状,下面会讲到。一看就知道了。

    最大池化层输出形状计算

    在这里插入图片描述
    看到向下取整的符号了吗?这个就是由 ceil_mode 控制的。

    参数示例介绍

    验证 kernel_size 参数

    import torch
    import torch.nn as nn
    
    # 仅定义一个 3x3 的池化层窗口
    m = nn.MaxPool2d(kernel_size=(3, 3))
    
    # 定义输入
    # 四个参数分别表示 (batch_size, C_in, H_in, W_in)
    # 分别对应,批处理大小,输入通道数,图像高度(像素),图像宽度(像素)
    # 为了简化表示,我们只模拟单张图片输入,单通道图片,图片大小是6x6
    input = torch.randn(1, 1, 6, 6)
    
    print(input)
    
    output = m(input)
    
    print(output)
    
    

    在这里插入图片描述
    第一个tensor是我们的输入数据 1 × 1 × 6 × 6 ,我们画红线的区域就是我们设置的窗口大小 3 × 3 ,背景色为红色的值,为该区域的最大值。

    第二个tensor就是我们最大池化后的结果,跟我们标注的一模一样。

    验证一下 stride 参数

    import torch
    import torch.nn as nn
    
    # 仅定义一个 3x3 的池化层窗口
    m = nn.MaxPool2d(kernel_size=(3, 3), stride=(2, 2))
    
    # 定义输入
    # 四个参数分别表示 (batch_size, C_in, H_in, W_in)
    # 分别对应,批处理大小,输入通道数,图像高度(像素),图像宽度(像素)
    # 为了简化表示,我们只模拟单张图片输入,单通道图片,图片大小是6x6
    input = torch.randn(1, 1, 6, 6)
    
    print(input)
    
    output = m(input)
    
    print(output)
    
    

    在这里插入图片描述
    红色的还是我们的窗口,但是我们的步长变为了2,可以看到第一个窗口和向右滑动后的窗口,他们的最大值刚好是重叠的部分都是2.688,向下滑动之后,最大值是0.8030,再次向右滑动,最大值是2.4859。

    可以看到我们在滑动的时候省略了部分数值,因为剩下的数据不够一次滑动了,于是我们将他们丢弃了。

    其实最后图片的宽度和高度还可以通过上面两个公式来计算,我们公式中用的是向下取整,因此我们丢弃了不足的数据。现在我们试试向上取整。

    利用 ceil_mode 参数向上取整

    import torch
    import torch.nn as nn
    
    # 仅定义一个 3x3 的池化层窗口
    m = nn.MaxPool2d(kernel_size=(3, 3), stride=(2, 2), ceil_mode=True)
    
    # 定义输入
    # 四个参数分别表示 (batch_size, C_in, H_in, W_in)
    # 分别对应,批处理大小,输入通道数,图像高度(像素),图像宽度(像素)
    # 为了简化表示,我们只模拟单张图片输入,单通道图片,图片大小是6x6
    input = torch.randn(1, 1, 6, 6)
    
    print(input)
    
    output = m(input)
    
    print('\n\n\n\n\n')
    
    print(output)
    
    

    在这里插入图片描述
    从结果可以看出,输出的size由原来的 2 × 2 变成了现在的 3 × 3。这就是向上取整的结果。为什么会出现这样的结果呢?

    这看起来像是我们对输入进行了填充,但是这个填充值不会参与到计算最大值中

    验证 padding 参数

    import torch
    import torch.nn as nn
    
    # 仅定义一个 3x3 的池化层窗口
    m = nn.MaxPool2d(kernel_size=(3, 3), stride=(3, 3), padding=(1, 1))
    
    # 定义输入
    # 四个参数分别表示 (batch_size, C_in, H_in, W_in)
    # 分别对应,批处理大小,输入通道数,图像高度(像素),图像宽度(像素)
    # 为了简化表示,我们只模拟单张图片输入,单通道图片,图片大小是6x6
    input = torch.randn(1, 1, 6, 6)
    
    print(input)
    
    output = m(input)
    
    print('\n\n')
    
    print(output)
    
    

    在这里插入图片描述
    我们对周围填充了一圈0,我们滑动窗口的范围就变化了,这就是填充的作用。

    但是有一点需要注意,就是即使我们填充了0,这个0也不会被选为最大值。例如上图的左上角四个数据,如果我们全部变为负数,结果是-0.1711,而不会是我们填充的0值,这一点要注意。

    验证 return_indices 参数

    import torch
    import torch.nn as nn
    
    # 仅定义一个 3x3 的池化层窗口
    m = nn.MaxPool2d(kernel_size=(3, 3), return_indices=True)
    
    # 定义输入
    # 四个参数分别表示 (batch_size, C_in, H_in, W_in)
    # 分别对应,批处理大小,输入通道数,图像高度(像素),图像宽度(像素)
    # 为了简化表示,我们只模拟单张图片输入,单通道图片,图片大小是6x6
    input = torch.randn(1, 1, 6, 6)
    
    print(input)
    
    output = m(input)
    
    print(output)
    
    

    在这里插入图片描述

    验证 dilation 参数

    
    ```python
    import torch
    import torch.nn as nn
    
    # 仅定义一个 3x3 的池化层窗口
    m = nn.MaxPool2d(kernel_size=(3, 3),dilation=2)
    
    # 定义输入
    # 四个参数分别表示 (batch_size, C_in, H_in, W_in)
    # 分别对应,批处理大小,输入通道数,图像高度(像素),图像宽度(像素)
    # 为了简化表示,我们只模拟单张图片输入,单通道图片,图片大小是6x6
    input = torch.randn(1, 1, 6, 6)
    
    print(input)
    
    output = m(input)
    
    print(output)
    

    在这里插入图片描述

    参考文档: https://blog.csdn.net/weixin_38481963/article/details/109962715

    展开全文
  • class torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False) 如下是MaxPool2d的解释: class MaxPool2d(_MaxPoolNd): r"""Applies a 2D max pooling over...
  • torch.nn.MaxPool2d和torch.nn.functional.max_pool2d两者本质上是一样的,具体可以参考torch.nn.MaxPool2d的源代码,核心源代码如下所示: from .. import functional as F class MaxPool2d(_MaxPoolNd): kernel_...
  • Pytorch nn.MaxPool1d; nn.functional.max_pool1d pytorch 中nn.MaxPool1d() 和nn.MaxPool2d()对比
  • 1.tf.nn.maxpool2d()函数介绍 tf.nn.max_pool2d(input, ksize, strides, padding, data_format='NHWC', name=None) 参数说明: Args input A 4-DTensorof the format specified bydata_format. ...
  • 作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客 ...本文是深度学习框架 pytorch 的API : torch.nn.MaxPool2d() 函数的用法。 本博客介绍了 torch.nn.MaxPool2...
  • Pytorch学习笔记(四):nn.MaxPool2d()函数详解

    千次阅读 多人点赞 2021-06-16 15:48:48
    相关文章 Pytorch学习笔记(一):torch.cat()模块的详解 文章目录1.函数语法格式和作用2.参数解释3.... 1.函数语法格式和作用 ...MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_
  • torch.nn.MaxPool2d 功能: MaxPool 最大池化层,池化层在卷积神经网络中的作用在于特征融合和降维。池化也是一种类似的卷积操作,只是池化层的所有参数都是超参数,是学习不到的。 作用: maxpooling有局部不变性...
  • torch.nn.MaxPool2d

    万次阅读 多人点赞 2020-07-28 15:57:52
    class torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False) 如果padding不是0,会在输入的每一边添加相应数目0 比如padding=1,则在每一边分别补0. ...
  • Pytorch中卷积使用的一些总结torch.nnnn.Conv2dnn.maxpool2dnn.Avg_pool空间金字塔池化(Spatial Pyramid Pooling)卷积神经网络——输入层、卷积层、激活函数、池化层、全连接层 torch.nn nn.Conv2d   nn.Conv2d ...
  • torch nn.MaxPool2d

    2020-08-22 17:42:09
    1.应用 import torch import torch.nn as nn m = nn.MaxPool2d(2) ...CLASS torch.nn.MaxPool2d(kernel_size: Union[T, Tuple[T, ...]], stride: Optional[Union[T, Tuple[T, ...]]] = None, padding: Union
  • 这里写目录标题一、nn.Sequential二、nn.Conv2d 一、nn.Sequential torch.nn.Sequential是一个Sequential容器,模块将按照构造函数中传递的顺序添加到模块中。另外,也可以传入一个有序模块。 为了更容易理解,官方...
  • nn.MaxPool2d(kernel_size=2, stride=(2, 1), padding=(0, 0)), 这样在用交叉熵做损失函数的时候,有时候会出现loss为nan的情况,检查的时候发现,某些样本的提取出来的feature全为nan。 以上这篇浅谈pytorch池化...
  • torch.nn.MaxPool2d()学习笔记

    千次阅读 2020-12-21 15:13:08
    参考链接: torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False) 参考链接: Convolution arithmetic 参考链接: 神经网络与深度学习 参考链接: 二维转置...
  • 使用最大值操作的池化层被称之为最大池化层(max pooling),使用平均值操作的池化层称之为平均池化层(average pooling),总的来说,池化层的作用是可以压缩数据和参数的量, 减小过拟合。 如下
  • nn.MaxPool2d()的kernel_size为tuple用法

    千次阅读 2020-08-10 23:05:00
    1. nn.Conv2d nn.Conv2d 输入信号的形式为(N, Cin, H, W), N表示batch size,Cin​表示channel个数,H,W分别表示特征图的高和宽。 参数说明: stride(步长):控制cross-correlation的步长,可...
  • pytorch 池化层——最大值池化nn.MaxPool 2dnn.MaxPool1d nn.MaxPool1d函数参数例子计算过程nn.MaxPool2d函数参数例子计算过程 nn.MaxPool1d 函数 class torch.nn.MaxPool1d(kernel_size, stride=None, padding=0, ...
  • 首先是pytorch中的卷积 nn.Conv2d 我们可以查看官方文档。 nn.Conv2d 输入信号的形式为(N,Cin,H,W),N表示batch size,Cin​表示channel个数,H,W分别表示特征图的高和宽。 参数说明: stride(步长):控制cross...
  • pytorch 中nn.MaxPool1d() 和nn.MaxPool2d()对比
  • tf.nn.max_pool(value, ksize, strides, padding, name=None) 参数是四个,和卷积很类似: 第一个参数value:需要池化的输入,一般池化层接在卷积层后面,所以输入通常是feature map,依然是[batch, height, width, ...
  • 本文主要讲解torch.mean()、torch.max() 和 nn.AdaptiveAvgPool2d()、nn.AdaptiveMaxPool2d() 这四个函数的基本用法以及区别
  • tf.nn.max_pool 原生的池化操作,而tf.layers.max_pooling2d是进行了封装,对许多参数进行了设置,使用起来更方便 tf.layers.max_pooling2d: 用于2D输入的最大池化层(例如图像). 参数: inputs:池的张量,秩...
  • 一、 如果在做卷积过程中出现WARNING:tensorflow:From D:\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py:4070: The name tf.... Please use tf.nn.max_pool2d instead.**** ,就是如下图所示的...
  • 最近在研究学习TensorFlow,在做识别手写数字时,遇到了tf.nn.conv2d这个方法,其中有些方法还不是很清楚,于是网上搜索后,记录如下: 卷积神经网络的核心是对图像的“卷积”操作 tf.nn.conv2d方法定义 tf.nn....
  • torch学习三之nn.Maxpool

    2020-11-25 18:31:26
    torch学习三之nn.Maxpool1dMaxpool1DMaxpool2D Maxpool1D 函数原型: torch.nn.MaxPool1d(kernel_size: Union[T, Tuple[T, ...]], stride: Optional[Union[T, Tuple[T, ...]]] = None, padding: Union[T, Tuple[T,...
  • 1 tf.nn.max_pool( 2 value, 3 ksize, 4 strides, 5 padding, 6 data_format='NHWC', 7 name=None 8 ) 池化与卷积差不多(个人认为!),原因在于池化类似于亚采样。 1 tf.layers.max_pooling2d( 2 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 34,277
精华内容 13,710
关键字:

nn.maxpool2d