ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [ pytorch ] MaxPool2d, AvgPool2d 알아보기 ( Pooling Layer )
    AI-ML 2023. 3. 27. 12:21
    728x90
    반응형

    - 목차

     

    키워드.

    • - Pooling Layer
    • - MaxPool2d
    • - AvgPool2d

     

    들어가며.

    이번 글에서는 CNN 의 Pooling Layer 를 구성하는 MaxPool2d 와 AvgPool2d 모듈에 대해서 알아보도록 하겠습니다.

     

    함께 보면 좋은 글.

    https://westlife0615.tistory.com/749

     

    pytorch - Conv2D 알아보기 ( CNN )

    - 목차 키워드.- CNN- Convolution- conv2d 들어가며.CNN 을 구성하기 위해서 사용되는 nn.Conv2d 의 구체적인 동작 방식에 대해서 알아보려고 합니다. 함께 보면 좋은 글.https://westlife0615.tistory.com/765 Cross

    westlife0615.tistory.com

     

     

    Pooling Layer 란 ?

    일반적으로 CNN 은 Convolution Layer 와 Pooling Layer 그리고 Linear Layer 로 구성됩니다.

    CNN 을 통해서 어떠한 이미지들의 패턴을 인식하고, 이를 토대로 이미지의 분류를 수행할 수 있는데요.

    이미지의 사이즈와 CNN 의 커널 사이즈가 커질수록 CNN 모델은 깊어지게 됩니다.

    이 과정에서 Overfitting 을 방지하는 목적으로 Pooling Layer 가 사용됩니다.

    이는 마치 딥러닝의 Dropout Layer 가 과적합을 방지하기 위해서 신경망의 일부 뉴런을 비활성화시키는 구조와 유사합니다.

     

    CNN 은 Convolution Layer 를 통해서 뉴런의 크기가 작아지게 됩니다.

    예를 들어, 3x28x28 과 같은 RGB & 28x28 픽셀의 이미지가 4x4 커널과 결합하여 25x25 크기의 Tensor 로 크기가 줄어듭니다.

    이처럼 Pooling Layer 를 통해서도 크기가 축소된 Tensor 가 한차례 더 크기가 축소될 수 있습니다.

    이러한 과정을 통해서 과적합이 방지되게 되죠.

    이미지는 일반적으로 3개의 차원으로 구성되며, 이는 Channel, Width, Height 로 이뤄집니다.

    CNN 은 여러 Kernel Filtering 를 활용하여 이미지의 부분적인 패턴을 인식해야합니다.

    따라서 CNN 네트워크를 거치면서 Channel 의 수는 증가하게 됩니다.

    이 과정에서 Overfitting 을 방지하기 위해 CNN 을 통과하는 Tensor 의 크기를 줄여줄 필요가 있게 되는데요.

    Channel 의 수보다 Width, Height 에 해당하는 Spatial Size 를 축소하는 방향을 선택해야합니다.

    그리고 Pooling Layer 는 이러한 Spatial Size 를 줄이는 역할을 수행합니다.

     

    Pooling Layer 는 Max Pooling Layer 그리고 Average Pooling Layer 2가지가 존재합니다.

    이어지는 글에서 Pooling Layer 의 사용법과 종류에 대해서 자세히 알아보도록 하겠습니다.

     

    MaxPool2d 사용해보기.

    MaxPool2d 는 커널 사이즈에 해당하는 이미지 텐서에서 가장 큰 값이 선택됩니다.

    예를 들어, 아래와 같은 Image Tensor 와 MaxPool2d 레이어가 존재한다고 하겠습니다.

    image_tensor = torch.tensor([
        [1, 1, 1, 1],
        [2, 2, 2, 2],
        [3, 3, 3, 3],
        [4, 4, 4, 4],
    ])
    
    max_pooling_layer = nn.MaxPool2d(2, 2)

     

    MaxPool2d 모듈은 kernel_size, stride 라는 두가지 인자를 필요로합니다.

    위 예시에선 kernel_size 와 stride 를 각각 2로 설정하였구요.

    이 경우에 아래와 같은 4개의 커널이 만들어집니다.

    그 이유는 2x2 커널이 stride 2 만큼의 보폭으로 움직여지기 때문이죠.

    # 1 kernel 
    [
      [1, 1],
      [2, 2],
    ]
    
    # 2 kernel 
    [
      [1, 1],
      [2, 2],
    ]
    
    # 3 kernel 
    [
      [3, 3],
      [4, 4],
    ]
    
    # 4 kernel 
    [
      [3, 3],
      [4, 4],
    ]

     

    그 결과 MaxPool2d 의 결과는 아래와 같이 구성됩니다.

    max_pooling_layer(image_tensor.view(1, 1, 4, 4))
    
    # tensor([[[[2, 2],
    #           [4, 4]]]])

     

    AvgPool2d.

    반면, AvgPool2d 의 경우에는 결과가 달라집니다.

    커널에 해당하는 값들의 평균이 Pooling Layer 의 출력이 되기 때문입니다.

    AvgPool2d 의 첫번째 item 의 결과값인 1.5 는 1, 1, 2, 2 의 평균값이 1.5 와 동일합니다.

    이처럼 AvgPool2d 는 이미지 텐서에서 커널에 해당하는 Item 들의 평균값을 출력합니다.

     

    import torch
    import torch.nn as nn
    
    avg_pooling_layer = nn.AvgPool2d(2, 2)
    
    image_tensor = torch.tensor([
        [1, 1, 1, 1],
        [2, 2, 2, 2],
        [3, 3, 3, 3],
        [4, 4, 4, 4],
    ])
    
    avg_pooling_layer(tensor.view(1, 1, 4, 4))
    
    # tensor([[[[1.5000, 1.5000],
    #           [3.5000, 3.5000]]]])

     

     

    Conv2d 와 함께 사용해보기.

    먼저 Conv2d 레이어를 구성합니다.

    in_channels 값은 3으로 설정합니다. 이유는 RGB 를 가지는 이미지 텐서의 Channel 이 3이기 때문이구요.

    out_channels 은 임의로 6으로 설정하였습니다.

    그리고 Input Tensor 인 이미지는 RGB 로 구성된 3x3 이미지를 가정하여 Input Tensor 를 구현하였구요.

    결과적으로 3x3x3 인 사이즈의 텐서가 되게 됩니다.

     

    이는 3x3 인 이미지가 2x2 커널과 콘볼루션하기 때문에 2x2 사이즈의 텐서가 출력되구요.

    출력된 2x2 텐서는 2x2 Max Pooling Layer 에 의해서 1x1 인 텐서로 출력되게 됩니다.

    conv = nn.Conv2d(in_channels=3, out_channels=6, kernel_size=2, stride=1)
    max_pooling = nn.MaxPool2d(2, 2)
    
    red_image_tensor = torch.tensor([
        [1.0, 1.0, 1.0],
        [1.0, 1.0, 1.0],
        [1.0, 1.0, 1.0],
    ], dtype=torch.float32)
    
    blue_image_tensor = torch.tensor([
        [2.0, 2.0, 2.0],
        [2.0, 2.0, 2.0],
        [2.0, 2.0, 2.0],
    ], dtype=torch.float32)
    
    green_image_tensor = torch.tensor([
        [1.0, 1.0, 1.0],
        [3.0, 3.0, 3.0],
        [3.0, 3.0, 3.0],
    ], dtype=torch.float32)
    
    image_tensor = torch.concat([
        red_image_tensor.view(1, 1, 3, 3), 
        blue_image_tensor.view(1, 1, 3, 3), 
        green_image_tensor.view(1, 1, 3, 3)
    ], dim=1)
    
    # tensor([[[[1., 1., 1.],
    #           [1., 1., 1.],
    #           [1., 1., 1.]],
    
    #          [[2., 2., 2.],
    #           [2., 2., 2.],
    #           [2., 2., 2.]],
    
    #          [[3., 3., 3.],
    #           [3., 3., 3.],
    #           [3., 3., 3.]]]])

     

    아래는 MaxPool2d 와 Conv2d 연산 결과이구요.

    out_channels 이 6이므로 1x6x1x1 인 사이즈의 텐서가 출력되게 됩니다.

    output = max_pooling(conv(image_tensor))
    # tensor([[[[ 0.0557]],
    
    #          [[ 1.5113]],
    
    #          [[-0.4264]],
    
    #          [[-0.5233]],
    
    #          [[ 2.2187]],
    
    #          [[-2.6951]]]], grad_fn=<MaxPool2DWithIndicesBackward0>)

     

     

    반응형

    'AI-ML' 카테고리의 다른 글

    [pytorch] Dropout 알아보기  (0) 2023.08.17
    Association Rules (연관규칙) 이해하기  (0) 2023.05.16
    [pytorch] torch.cat 알아보기  (0) 2023.03.12
    [pytorch] nn.Linear 알아보기  (0) 2023.02.20
    [pytorch] DataLoader 알아보기  (0) 2022.07.18
Designed by Tistory.