[15′ CVPR] Going deeper with convolutions (GoogleNet, inception) 핵심 리뷰

This entry is part 3 of 22 in the series Vision Model

1. 들어가며

딥러닝의 세계에서는 모델의 성능을 향상시키는 것이 끊임없는 추구의 대상입니다. 그러나 이러한 성능 향상은 종종 모델의 크기 증가, 과적합, 그리고 계산량의 급증과 같은 문제를 동반합니다. 이러한 문제들은 모델의 확장성과 효율성을 제한하며, 실제 세계의 다양한 응용 분야에서의 적용을 어렵게 만듭니다. 이러한 배경 속에서, Inception 모델은 이러한 문제들에 대한 독창적이고 효과적인 해결책을 제시합니다.

Inception 모델은 다양한 크기의 컨볼루션 필터를 병렬로 연결하여, 다양한 스케일의 특징을 동시에 학습할 수 있는 능력을 갖추고 있습니다. 이러한 구조는 모델이 더욱 유연하게 특징을 추출할 수 있게 해주며, 이를 통해 성능을 크게 향상시킬 수 있습니다. 또한, 1×1 컨볼루션을 통해 차원을 축소함으로써, 모델의 크기와 계산량을 효과적으로 줄일 수 있습니다. 이와 더불어, fully connected layer 대신 average pooling을 사용하여 모델의 파라미터 수를 줄이고, auxiliary classifier를 도입하여 gradient vanishing 문제를 완화하는 등의 독창적인 아이디어도 도입되었습니다.

이러한 Inception 모델의 구조와 아이디어들은 본 글에서 자세히 살펴볼 것입니다. 본 글에서는 Inception 모델의 핵심 개념과 구조, 그리고 이를 파이썬을 통해 어떻게 구현할 수 있는지에 대해 상세하게 설명할 것입니다. 또한, 실험 결과를 통해 Inception 모델의 성능을 다른 모델과 비교하고, 이를 통해 이 모델의 우수성을 명확히 드러낼 것입니다.

Inception 모델은 그 자체로도 탁월한 성능과 효율성을 자랑하지만, 그것만이 아닙니다. 이 모델은 Inception 모델 패밀리의 시작이며, 이후 여러 버전의 Inception 모델이 발표되면서 각각 중요한 아이디어와 개선점을 제시하고 있습니다. 이러한 다양한 버전의 Inception 모델과 그들의 기여에 대해서도 본 글에서는 자세히 알아볼 것입니다.

딥러닝과 컴퓨터 비전 분야에 관심이 있는 모든 이들에게, 이 글은 Inception 모델에 대한 깊이 있는 이해를 제공할 것이며, 이를 통해 여러분의 모델 설계와 구현 능력을 한 단계 더 향상시킬 수 있는 기회가 될 것입니다. 이제 Inception 모델이 어떻게 딥러닝 모델의 성능과 효율성을 동시에 향상시킬 수 있는지 알아보겠습니다!

2. 기존 방식의 문제점

AlexNet을 시작으로 본격적으로 Image Recognition을 위한 딥러닝 모델 연구가 시작되었습니다. 그리고 성능을 증대시키기 위해서는 더 깊고 큰 네트워크를 만들어야 한다는 사실이 자명해졌습니다. 하지만 더 깊고 큰 네트워크를 만들면 대표적으로 두 가지 문제가 발생했습니다.

첫 번째는 Overfitting입니다. 네트워크가 깊어지면서 표현력이 좋아지고, 이에 따라 모델이 학습 데이터에서만 최적화되는 문제가 발생했습니다.
두 번째는 Computational Cost입니다. 마찬가지로 네트워크가 깊어지면서 학습해야 할 파라미터 개수가 늘어나고, 필연적으로 계산량이 많아지는 문제가 발생했습니다.

3. 제안 방법

이러한 문제를 해결하기 위한 저자들의 제안 방법을 살펴보겠습니다.

3-1. 다양한 사이즈의 필터 사용

첫 번째 방법은 Convolution 연산 시 다양한 사이즈의 필터를 병렬로 사용하는 방법입니다.

1.다양한 필터 사용_1
그림1. 다양한 필터 사용 – 1

위의 논문에서 사용된 그림을 보면 Input Feature Map에 대해 1×1, 3×3, 5×5 Convolution을 병렬로 연산하는 모습을 볼 수 있습니다. 이를 직관적으로 볼 수 있게 Convolution Filter와 Feature Map을 표현하면 다음과 같습니다.

2.다양한 필터 사용_2
그림2. 다양한 필터 사용 – 2

3개의 Convolution(남색)과 Max Pooling(주황색)을 적용하여 나온 4개의 Feature Map을 Channel Wise Concat(초록색) 하여 최종 Output Feature Map을 구성하는 모습을 볼 수 있습니다.

이를 기존의 Convolution 연산 방법과 비교해보겠습니다. 기존 Convolution 연산을 동일한 방법으로 표현하면 다음과 같습니다.

3.기존 convolution
그림3. 기존 Convolution 연산

당시 보통 Convolution Filter 사이즈를 10×10 정도를 사용했음을 감안하면 Convolution Filter에 사용되는 파라미터 개수 (파란색)가 저자들의 제안 방법보다 훨씬 많음을 알 수 있습니다.

3-2. 1×1 Convolution 사용

다양한 사이즈의 필터를 병렬로 연결함으로써 파라미터 개수가 약간 줄어들긴 했지만, Convolution 연산의 특성상 뒤로 갈수록 Channel 사이즈에 따라 파라미터 개수가 기하급수적으로 증가하여 아직도 많은 연산 양을 요구합니다. 이를 해결하기 위한 방법으로 저자들은 1×1 Convolution의 사용을 제안합니다.

4.1x1 convolution 사용_1
그림4. 1×1 Convolution 사용 – 1

위의 논문에서 사용된 그림을 보면 3×3, 5×5 Convolution 앞에, 그리고 3×3 Max Pooling 뒤에 1×1 Convolution을 적용한 모습을 볼 수 있습니다. 이를 다시 2-1에서와 동일한 방식으로 표현하면 다음과 같습니다.

5.1x1 convolution 사용_2
그림5. 1×1 Convolution 사용 – 2

연산량이 가장 많은 3×3, 5×5 Convolution에 앞서 1×1 Convolution으로 채널 수를 줄여줌으로써 학습할 파라미터 개수(파란색)가 확 줄어든 모습을 볼 수 있습니다. 이렇게 구성한 모듈을 저자들은 Inception Module이라고 부릅니다.

3-3.  Average Pooling 사용

이어서 저자는 추가적으로 학습 파라미터 수도 줄이고 Overfitting을 방지할 수 있는 방법을 제안합니다. 네트워크의 마지막 부분에서 Fully Connected 연결 대신 Average Pooling을 사용하는 방법입니다. 보통 네트워크의 마지막 부분은 다음과 같이 구성됩니다.

6.fully connected 방식
그림6. Fully Connected 방식

마지막 Feature Map을 Flatten 하여 1차원 값으로 바꿔준 뒤 Fully Connected 연결되어 있는 모습입니다. 반면 저자들이 제안하는 Fully Connected 대신 Average Pooling을 사용하는 방법은 다음과 같습니다.

7.average pooling 방식
그림7. Average Pooling 방식

Feature Map을 Channel Wise로 Average Pooling을 하는 모습을 볼 수 있습니다.

3-4. Auxiliary Classifier 사용

이렇게 구성을 하면 깊은 네트워크를 구성하면서도 연산량을 대폭 줄일 수 있습니다. 하지만 네트워크가 깊어짐으로 인해 생기는 Gradient Vanishing 문제는 아직 해결되지 않았습니다. 저자들은 이를 해결하기 위해 Auxiliary Classifier를 추가하는 방법을 제안합니다. 이는 네트워크의 중간중간에 Classifier를 추가하여 학습 Loss를 흐르게 만들어주는 방법입니다. 마치 긴 터널의 중간중간에 환기구를 뚫어 공기 흐름을 원활하게 해 주는 것과 같은 이치라고 할 수 있습니다.

3-5. 전체 구조

위에서 설명한 모든 방식을 합친 전체 구성은 다음과 같습니다.

8.전체 구조
그림8. 전체 구조

초기 연산은 Inception Module을 사용하지 않고 일반적인 Traditional Convolution과 연결해주었습니다. 이후 Inception Module이 깊게 쌓이고, 중간중간 Auxiliary Classifier가 연결되어 있는 모습입니다.

4. 파이썬 구현

이번 챕터에서는 위에서 설명한 Inception Model을 파이썬으로 직접 구현해 보겠습니다.

4-1. Import Module

먼저 필요한 Module을 Import 합니다.

import torch
import torch.nn as nn
import torch.nn.functional as F

4-2. Inception Module Class 정의하기

다음으로 Inception Module Class를 정의해줍니다. Inception Module Class의 핵심은 다양한 Convolution 연산과 Pooling 연산을 병렬로 연결해주는 것인데요. 다양한 Convolution 연산과 Pooling 연산을 __init__ 함수에서 정의해준 뒤 forward 함수에서 병렬로 연결해주는 모습을 볼 수 있습니다.

class InceptionModule(nn.Module):
    def __init__(self, in_channels):
        super(InceptionModule, self).__init__()
        
        # 1x1 Convolution
        self.conv1 = nn.Conv2d(in_channels, 64, kernel_size=1)
        
        # 1x1 Conv followed by 3x3 Conv
        self.conv3 = nn.Sequential(
            nn.Conv2d(in_channels, 64, kernel_size=1),
            nn.Conv2d(64, 128, kernel_size=3, padding=1)
        )
        
        # 1x1 Conv followed by 5x5 Conv
        self.conv5 = nn.Sequential(
            nn.Conv2d(in_channels, 64, kernel_size=1),
            nn.Conv2d(64, 128, kernel_size=5, padding=2)
        )
        
        # 3x3 MaxPooling followed by 1x1 Conv
        self.pool = nn.Sequential(
            nn.MaxPool2d(3, stride=1, padding=1),
            nn.Conv2d(in_channels, 32, kernel_size=1)
        )
        
    def forward(self, x):
        conv1_out = self.conv1(x)
        conv3_out = self.conv3(x)
        conv5_out = self.conv5(x)
        pool_out = self.pool(x)
        
        # Concatenate along channel dimension
        output = torch.cat([conv1_out, conv3_out, conv5_out, pool_out], dim=1)
        
        return output

4-3. Inception Model Class 정의하기

다음은 위에서 정의한 Inception Module Class들을 사용하여 최종적인 Inception Model Class를 정의해보겠습니다. forward 함수를 보면 입력 x에 대해 Convolution 연산을 수행한 뒤 Inception Module의 연산을 거쳐 최종적으로 Classifier를 통해 Logit 값이 출력되는 구조를 확인할 수 있습니다.

# Create a simple model using the Inception module
class SimpleInception(nn.Module):
    def __init__(self):
        super(SimpleInception, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, kernel_size=3, padding=1)
        self.inception1 = InceptionModule(64)
        self.fc = nn.Linear(64*4*32*32, 10)  # Assuming input size is [32, 32, 3]
        
    def forward(self, x):
        x = self.conv1(x)
        x = self.inception1(x)
        x = x.view(x.size(0), -1)
        x = self.fc(x)
        return x

4-4. Inception Model 사용하기

이렇게 정의된 Inception Model은 다음 예시와 같이 사용할 수 있습니다.

# Create the model
model = SimpleInception()

5. 효과

다음은 이렇게 제안한 방법의 효과에 대해 알아보겠습니다.

5-1. ImageNet 성능

ImageNet 성능을 보면 다음과 같습니다.

9.imagenet 성능
그림9. ImageNet 성능

2012년에 제안된 AlexNet에 비해 성능이 거의 10% 가까이 좋아져 인간의 수준인 5%에 거의 근접한 모습을 볼 수 있습니다. 더 놀라운 건 이렇게 좋은 성능을 보였음에도 AlexNet 대비 파라미터 개수는 1/12 수준이었다는 점입니다.

6. 의의

다음은 Inception 논문의 의의에 대해 살펴보겠습니다.

첫 번째 의의는 다양한 스케일의 특징을 동시에 학습하는 방법을 제안한 것입니다. 전통적인 CNN(Convolutional Neural Networks)은 주로 하나의 크기의 필터를 사용하여 이미지의 특징을 추출합니다. 그러나 이러한 접근법은 다양한 크기와 모양의 객체를 효과적으로 인식하기 어렵습니다. Inception은 이 문제를 해결하기 위해 여러 크기의 Convolution 필터와 Pooling 레이어를 병렬로 적용합니다. 이를 통해 네트워크는 작은 물체에서부터 큰 물체까지, 다양한 스케일과 방향의 특징을 동시에 학습할 수 있습니다. 이러한 다양한 스케일의 특징 추출은 이미지 분류, 객체 탐지, 이미지 세그멘테이션 등 다양한 비전 태스크에서 뛰어난 성능을 보입니다.

두 번째 의의는 네트워크 내의 네트워크(Network In Network)라는 개념의 활용 방법을 제안한 것입니다. 이 덕분에 복잡한 연산량을 줄이면서도 높은 성능을 유지할 수 있었습니다. 이는 모델의 효율성과 확장성을 높이는 중요한 요소입니다.

세 번째 의의는 여러 버전을 발표하며 각각 중요한 아이디어를 제안한다는 점입니다. 각 버전마다 성능과 효율성을 개선하는 다양한 기술이 도입되었습니다. 이러한 지속적인 발전 덕분에 Inception은 딥러닝 커뮤니티에서 널리 사용되고 있으며, 다양한 응용 분야에서 뛰어난 성능을 보이고 있습니다.

7. 마치며

Inception 모델의 여행을 마무리 지으면서, 이 모델이 어떻게 다양한 스케일의 특징을 효과적으로 학습하고, 모델의 크기와 계산량을 최적화하는 동시에 성능을 향상시킬 수 있는지에 대한 근본적인 이해를 얻었기를 바랍니다. 이번 글에서는 Inception 모델의 핵심 아이디어와 구조, 그리고 이를 파이썬으로 구현하는 방법에 대해 상세하게 탐구했습니다. 또한, 실험 결과를 통해 이 모델의 성능이 얼마나 우수한지도 확인할 수 있었습니다.

Inception 모델은 다양한 크기의 컨볼루션 필터를 병렬로 사용하여 다양한 스케일의 특징을 동시에 학습할 수 있는 능력, 차원 축소를 위한 1×1 컨볼루션의 활용, 그리고 auxiliary classifier를 통한 gradient vanishing 문제 완화 등 다양한 독창적인 아이디어를 선보였습니다. 이러한 아이디어들은 모델의 성능과 효율성을 동시에 향상시키는 데 큰 역할을 해, Inception 모델을 성공으로 이끌었습니다.

여기서 멈추지 않고 Inception 모델은 계속해서 발전하고 있으며, 여러 버전의 Inception 모델이 새로운 아이디어와 개선점을 제시하고 있습니다. 이러한 최신의 연구와 개발을 지속적으로 주시하면 다양한 좋은 아이디어를 얻을 수 있을 것입니다.

Inception 모델과 같은 혁신적인 아이디어와 기술은 딥러닝 분야를 지속적으로 발전시키고 있습니다. 이러한 발전은 우리가 더욱 복잡하고 어려운 문제를 해결할 수 있게 해주며, 이를 통해 우리의 생활을 더욱 풍요롭고 편리하게 만들어줍니다. 이번 글이 많은 도움이 되었기를 바랍니다!

Series Navigation<< [12′ NIPS] ImageNet Classification with Deep Convolutional Neural Networks (AlexNet) 핵심 리뷰[15′ ICLR] VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION (VGGNet) >>
0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x
Scroll to Top