CNN 기초

인화·2025년 1월 17일
0

Deep Learning

목록 보기
1/6

CNN이란?

 CNN(Convolutional Neural Network)은 인간의 시각 처리 방식을 모델링한 것으로, 시각적인 데이터 처리를 위한 딥러닝의 한 형태이다.

 기존의 DNN(Deep Neural Network)은 MLP에서 은닉층 개수를 증가시켜 학습 결과를 향상시키는 방법이었다.

 하지만 이러한 DNN은 이미지를 flatten시켜서 입력으로 받기 때문에 어느 정도 정보 손실이 발생할 수 있다는 문제점이 존재했다. 그래서 이를 해결하기 위해 등장한 것이 CNN이다.

 CNN은 기존의 DNN과는 달리 이미지 그 자체를 입력으로 받는다. 즉, 기존의 DNN처럼 이미지를 flatten시켜서 입력으로 받을 필요 없이, 이미지 그대로를 입력으로 받을 수 있다는 것이다.

 그렇기에 이미지 자체의 공간적/지역적 정보를 유지한 채로 연산을 진행할 수 있다.

 또한, 기존 DNN과 같은 구조에선 중요하지 않은 모든 픽셀까지도 고려하는 경향이 있었는데, CNN은 이를 해결하여 오버피팅을 방지할 수도 있다.

 이러한 CNN에 대해 자세히 살펴보자.

1. CNN이 학습하는 방법

 일단, CNN의 기본적인 모델에 대해 살펴보자. 기본적인 CNN 네트워크는 "Input -> Convolutional layer -> Activation function -> Pooling layer -> FC layer"로 구성된다.

 이때, 컨볼루션 레이어와 풀링 레이어는 여러 번 되풀이되는 경우가 많다. 왜냐하면, 레이어가 깊어질수록 더 많은 정보들을 추출할 수 있기 때문이다. 예를 들어, cov1=Edge, conv3=Texture, Cov5=Object Part와 같이 레이어가 깊어질수록 더욱 더 추상화된 정보가 추출된다. 다시 말해 레이어가 깊어질수록, 사물의 의미를 이해하게끔 변화한다.

 아래의 사진을 살펴보면, 점 -> 선 -> 물체 순으로 이미지가 점점 고차원으로 압축되어 물체의 계층적 특징을 잡아나가고 있는 것을 확인할 수 있다.

 아래의 사진을 살펴보면 CNN 구조에 대한 이해가 더 쉽다. 이와 같이 정보 추출과 축소(Conv-Pooling)를 반복하면서, 주어진 이미지를 기반으로 핵심 특징을 학습하는 것이 CNN의 기본 구조이다.

 이때, input으론 이미지 그 자체가 입력되고, Convolutional layer에선 필터를 통해 이미지의 지역적 특징을 잡아내 이를 Feature map으로 출력한다. 이후, Feature map에 비선형성을 도입해서 복잡한 패턴을 학습할 수 있도록 도움을 주기 위한 Activation function을 적용한 뒤, 이미지의 중요한 특징만을 남기고 공간 크기를 줄이는 Pooling layer를 거친다.

 여기서 중요한 것은, 각 Convolutional layer의 입력이 원본 이미지가 아닌, 이전 레이어의 출력 결과라는 것이다. 즉, 추출된 특징들을 바탕으로 새로운 특징들을 계속 학습해 나간다. 우리가 Pooling layer를 사용해야 하는 이유는 여기에 있다. 이미지의 중요한 특징만을 남기고 크기를 줄이지 않으면, 연산량이 너무 많고, 이로 인해 overfitting이 발생할 우려가 있기 때문이다.

 모든 Conv->Pooling 과정을 거친 후엔 Fully Connected Layer로 이동하는데, 이때 FC Layer로 이동하기 전, Flatten 과정을 거쳐 다차원의 Feature map을 1차원 벡터로 평탄화시키는 과정이 필요하다. 왜냐하면 FC Layer는 1차원 배열 형태로 평탄화된 행렬을 통해 이미지를 분류하는 데 사용되는 계층이기 때문이다. 그래서 Flatten 과정을 거친 후, FC Layer에서 입력으로 받은 1차원 벡터의 특징들을 바탕으로 활성화 함수나 softmax를 적용해 최종적인 분류를 결정한다.

 이러한 과정을 거치면서 이미지의 중요한 특징들이 Feature map에 통합되고, 중요한 특징들을 파악해 나가면서 이미지가 어떤 클래스에 속하는지 찾아내는 과정이 CNN 모델의 전반적인 학습 과정이다.

 사실 FC Layer의 특성상 일부 공간 정보가 손실될 가능성이 있지 않을까? 그럼에도 불구하고 사용하는 이유는 무엇일까? 하는 궁금증이 들어서 이 부분에 대해서도 알아봤다.
 이론적으로, 합성곱 계층을 reshape해서 FC Layer의 역할을 대체할 수 있기 때문에 FC Layer가 필수적인 것은 아니다. 그럼에도 불구하고 사용하는 이유는 reshape하는 것보다 FC Layer를 사용하는 것이 더 익숙하고, 간단해서인 것도 있고, 합성곱과 풀링 계층은 이미지의 특정 부분을 고려하는 지역적 연산을 수행하는 데 FC Layer는 글로벌한 연산을 수행하여 입력의 모든 차원을 고려해 이미지를 판단 가능하도록 하기 때문이다.
 자세한 내용은 이곳을 참고하자.
https://stackoverflow.com/questions/42317238/why-do-we-use-fully-connected-layer-at-the-end-of-cnn/42322414

2. Activation function

 딥러닝에서 사용하는 인공신경망은 이전 레이어로부터 값을 입력받아 “어떠한 함수”를 통과시킨 후 그 결과를 다음 레이어로 전달한다. 이때 사용하는 "어떠한 함수"가 바로 활성화 함수이다.

 활성화 함수는 네트워크의 출력을 조절해 원하는 형태로 만드는데, 이 과정에서 결정 경계에 비선형성을 제공한다. 여기서 비선형성을 제공하는 이유는, 복잡한(비선형) 패턴을 학습하도록 하기 위함이며, 모델에 비선형성이 없으면 모델은 linear transform만 가지게 되기 때문에 신경망 은닉층을 깊게 쌓는 의미가 없어진다.

 따라서 비선형 변환을 통해 신경망이 복잡한 함수를 학습할 수 있도록 해주는 것이 활성화 함수이다.

활성화 함수는 y = x, y = ax, y = ax + b와 같은 선형 함수 대신 비선형 활성화 함수(ex. Sigmoid, Tanh, ReLu)를 사용하는 것이 좋다. 예를 들어 g(z) = z라는 활성화 함수를 사용한다고 가정했을 때, 3개의 은닉층을 쌓아도 g(g(g(z))) = z가 되기 때문에 신경망을 깊게 쌓는 이유가 없어진다.

(1) Step function

  • 계단 함수 : 임계값을 경계로 출력이 바뀌는 활성화 함수
  • 입력이 0을 넘으면 1을, 그 외에는 0을 출력한다.
  • 퍼셉트론에선 일정 세기 이상 자극일 경우에만 신호를 전달하기 위해 활성화 함수로 계단 함수를 활용한다.
  • 계단 함수는 모든 구간에서 미분값이 0이 되기 때문에 가중치 업데이트가 불가능해 역전파 알고리즘을 사용하지 못한다.
  • 따라서 현대의 신경망에는 계단 함수를 잘 사용하지 않는다.

(2) Sigmoid function

  • 신경망 학습을 위한 역전파 알고리즘이 등장하고, 역전파 알고리즘에 계단 함수가 적합하지 않다는 사실을 알게 됨.
  • 계단 함수와 비슷하면서 미분 가능한 함수에 대한 필요성에 의해 대두된 것이 시그모이드 함수
  • 입력이 작을 때의 출력은 0에 가깝고, 입력이 커질 때의 출력은 1에 가까워지는 구조
  • h(x)=11+exh(x)=\frac{1}{1 + e^{-x}}

  • 시그모이드 함수는 입력의 절대값이 커질수록 출력이 Saturation 상태에 가까워진다.
  • Saturation 상태에선 미분 값이 작아지는데, 이로 인해 역전파에서 가중치 업데이트 속도가 느려져 저속 수렴 문제와 Vanishing Gradient 문제가 발생할 수 있다.
  • 이게 아니더라도, 시그모이드 함수는 최대 미분값이 0.25이다. 다시 말해, 미분 값의 범위가 0.0~0.25 사이이기 때문에 층이 깊어질수록 가중치 업데이트 속도가 느려지는 문제가 발생한다. 그렇기에 결국엔 Vanishing Gradient 문제가 발생한다.
  • 또한, 시그모이드 함수의 출력은 0~1 사이의 값이므로, 함수값의 중심이 0.5이다.(non-zero-centered) 이로 인해 시그모이드의 편미분 값이 항상 양수가 되면서 가중치 업데이트 시 지그재그 형태로 업데이트되는 현상이 발생하는데, 이것이 학습 속도 저하를 야기한다.
  • 이러한 문제들 때문에 시그모이드는 로지스틱 회귀나 이진 분류와 같은 문제 이외엔 사용하지 않는 것이 좋다.

(3) Tanh function

  • Tanh 함수는 시그모이드 함수값의 중심을 0으로 맞춰 지그재그 현상을 개선하기 위해 고안된 함수이다.
  • 결과값이 (-1, 1) 사이이면서 양수와 음수가 나오는 비중이 비슷하기 때문에 zigzag 현상이 덜하며, 시그모이드보다 거의 항상 더 좋은 결과를 낸다는 특징이 있다.
  • 하지만, 여전히 미분값이 작아 시그모이드 함수에서 기인하는 Vanishing Gradient 문제를 해결하지 못했다.
  • f(x)=exexex+ex=21+e2x1f(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} = \frac{2}{1+e^{-2x}}-1

Tanh와 Sigmoid의 단점 : 입력값이 커질수록 기울기가 작아져서 학습 속도가 떨어진다. 이런 이유에서 은닉층에서는 주로 ReLU를 많이 사용한다.

(4) ReLU function

  • ReLu는 Sigmoid와 tanh가 가지는 Vanishing Gradient 문제를 해결하기 위해 고안된 함수로, 가장 자주 사용되는 활성화 함수이다.
  • h(x)=max(0,x)h(x)=max(0, x)
  • ReLU는 위와 같이 간단한 수식으로 표현할 수 있고, 미분값도 0 또는 1로 단순한 형태이기 때문에 계산 복잡도가 줄어들고, 비선형성을 추가할 수도 있어 효과적이라는 장점이 있다.
  • 다만, ReLu 함수의 특성상 0보다 작은 값들에서 노드가 죽을 수도 있는 단점이 존재한다. (Dying ReLU)
    • 이를 해결하기 위해 Leaky ReLU, Parametric ReLU 등을 활용한다. 이는 0 이하일 때도 어느 정도 값을 취하도록 하여 Dying ReLU 문제를 해결하고자 한 방법인데, 이에 관해선 밑에서 더 살펴볼 것이다.

 위에서 이야기한 Leaky ReLU, Parametric ReLU 등에 대해서도 간략히 살펴보자. 이것들은 쉽게 말해, 0 이하일 때도 어느 정도 값을 취하도록 하여 Dying ReLU 문제를 해결하고자 한 것이다.

Leaky ReLU:

  • Dying ReLU 현상을 해결하기 위해 나온 함수로, 0보다 작은 값에 대해 0.01*x를 반환한다. 이때 x에 곱해진 수는 꼭 0.01일 필요는 없고, 1보다 작은 값이면 무엇이든 가능하다.
  • 음수 영역의 미분값이 0이 되지 않는다는 점을 제외하면 기존 ReLu와 동일한 특성을 지닌다.
  • h(x)=max(0.01x,x)h(x) = max(0.01x, x)

Parametric ReLU (PReLU)

  • x에 곱해지는 작은 수를 사용자가 지정할 수 있도록 새로운 파라미터 α로 지정한 것이다.
  • 파라미터 α는 상수가 아니므로, 각 레이어에 알맞는 α를 갱신해 가면서 사용할 수 있기 때문에 효율적이다.
  • 대규모 데이터셋에 대해선 ReLu보다 성능이 크게 앞섰지만, 소규모 데이터셋에 대해선 overfitting의 위험성이 존재한다.
  • h(x)=max(αx,x)h(x) = max(αx, x)

Exponential Linear Unit (ELU)

  • ReLU나 PReLU는 음수 구간이 직선이므로 기울기가 작더라도 큰 음수 값이 들어오면 출력값이 마이너스 무한대로 발산할 수 있다는 단점이 있다.
  • 이를 해결하기 위해 등장한 것이 ELU이다. 이는 ReLU의 단점을 최소화하면서도, 보다 부드럽게 만든 형태의 함수로 음수값이 들어오면 지수 함수를 사용해 부드럽게 꺾어준다.
  • 따라서 입력값이 음수 방향으로 커지더라도 출력값이 0에 가까운 일정한 음수 값이 되며, 아주 큰 음수값이 들어오더라도 큰 영향을 미치지 않는다. (이러한 특성 때문에 노이즈에 덜 민감하다고 이야기한다)
  • ELU(x)={xif x>0α(ex1)if x0\text{ELU}(x) = \begin{cases} x & \text{if } x > 0 \\ \alpha (e^x - 1) & \text{if } x \leq 0 \end{cases}
  • 단점이 있다고 하면, 지수함수를 포함하므로 일반적인 ReLU보다 연산량이 많고, 계산 비용이 더 높다.

Maxout

  • 입력값에 대해 여러 선형 함수를 적용한 후, 그 중 최댓값을 선택하는 방식
  • Maxout(x)=max(W1Tx+b1,W2Tx+b2)\text{Maxout}(x) = \max(W_1^T x + b_1, W_2^T x + b_2)
  • 두 선형 함수의 최대값을 계산함으로써 비선형성을 제공하고, 음수 입력에 대해서도 유효한 출력을 생성할 수 있으므로 ReLU의 장점을 모두 갖고, Dying ReLU 문제 또한 해결한다는 장점이 있으나, 다른 활성화 함수보다 더 많은 파라미터가 필요해 계산량이 많다는 단점이 존재한다.

 지금까지 살펴본 활성화 함수들을 한 번에 모아보면 다음과 같다.

(5) Softmax function

  • 소프트맥스 함수는 전체 입력 값의 상대적인 관계를 확률로 표현해 각 입력값의 중요도를 확인하는 함수이다.
  • 다시 말해, 입력 값을 정규화하여 모든 출력의 합이 1이 되도록 해 데이터를 확률적 형태로 표현하는 함수이다.
  • 이러한 특성 때문에 다중 클래스 분류 모델을 만들 때, 출력층의 활성화 함수로 주로 소프트맥스 함수를 사용한다.
  • yk=exp(ak)i=1nexp(ai)y_k = \frac{exp(a_k)}{\sum_{i=1}^{n} exp(a_i)}
  • y=exy=e^x는 단조 증가 함수이므로, 소프트맥스 함수를 적용해도 각 원소의 대소 관계는 변하지 않는다. 다시 말해, 출력이 가장 큰 뉴런의 위치는 변하지 않는다는 것이다. 그렇기에 추론 단계에서는 지수 함수 계산으로 인해 발생하는 자원 낭비를 줄이기 위해 소프트맥스 함수를 생략하기도 한다.
  • 다만, 신경망 학습 과정에선 출력층에서 소프트맥스 함수를 사용하는 게 좋은데 이건 교차 엔트로피 오차 함수를 통해 모델의 가중치 매개변수 값을 조정할 때, 소프트맥스 계층을 사용하면 역전파가 말끔히 떨어지고((y1t1,y2t2,y3t3y_1-t_1, y_2 - t_2, y_3 - t_3)와 같이 말끔히 떨어진다 -> 계산 복잡도의 감소), 큰 오차를 전달해 줄 수 있어서 가중치 값을 조절할 때 효과적이기 때문이다.
  • 예를 들어, 정답 레이블이 (0. 1, 0)이고 Softmax 계층이 (0.3, 0.2, 0.5)라면, Softmax 계층의 역전파는 (0.3, -0.8, 0.5)를 전파한다. 이를 통해 모델은 더 나은 가중치를 학습할 수 있다.

3. Pooling Layer

 앞에서도 말했듯, CNN에서는 정보의 추출과 축소를 반복하면서 주어진 이미지를 기반으로 핵심적인 특징을 학습한다. 이때, 중요 특징 정보를 압축하는 역할을 하는 계층이 풀링 계층이다.

 이러한 풀링 계층이 필요한 이유는, 컨볼루션 계층에서 필터가 늘어날수록 Feature Map의 차원이 늘어나는데, 이렇게 차원이 늘어나면 늘어날수록 모델의 계산 복잡성이 증가하고, 너무 많은 연산과 가중치 파라미터로 오버피팅 문제가 발생할 가능성이 존재한다. 따라서 이를 해결하기 위해 다운샘플링을 통해 파라미터 개수를 줄이고, 모델에서 핵심적인 특징 정보만 추출하는 과정을 거치는 것이다.

 풀링의 종류에는 평균 풀링(average pooling)과 최대 풀링(max pooling)이 있다.

Max Pooling

 Max Pooling은 이미지 내에서 가장 두드러진 특징(강한 신호)만을 남기는 과정이다. 이를 위해 이미지의 픽셀값에 대해 최대값을 구한다.

 예시를 살펴보자. 다음과 같은 데이터가 존재하고, stride=2로 두고 Max Pooling을 진행하면, 각 픽셀에서 최대값만을 뽑아내는 것을 확인할 수 있다.

Average Pooling

 Average Pooling은 이미지의 픽셀값에 대해 평균값을 취해 좀 더 부드럽고 일반적인 특징을 파악한다. 다만, 이러한 Average Pooling은 커널 안의 모든 값에 대해 평균 취하는 연산 과정에서 중요한 정보 손실의 가능성이 있다.

 그럼에도 불구하고 Average Pooling을 사용하는 이유는, Global Average Pooling Layer(GAP)로 활용할 수 있기 때문이다.

 GAP란, 쉽게 말해서 feature map에서 각 채널마다 전체 평균을 구해 채널 수는 유지한 채로 이미지의 특징을 1차원 벡터로 만드는 것이다.

 이러한 GAP를 왜 사용하는지 이해하기 위해선 기존 FC Layer에서 발생하던 문제를 이해해야 한다.

 기존 FC Layer를 사용한 분류에서는 Flatten Layer를 통해 입력받은 값을 하나의 긴 벡터로 만든 다음, 그 벡터를 FC Layer에 넣는 방식으로 하나하나 매핑해서 클래스를 분류했다.

 그래서 이 과정에서 공간적 정보를 잃어버리기도 했고, 많은 파라미터가 필요해 계산량이 많다는 문제가 존재했다. 그래서 이를 해결할 방법으로 대두된 것이 GAP이다. GAP를 사용하면 이러한 Flatten Layer의 문제를 효과적으로 해결할 수 있다.

 단순히 각 채널에 존재하는 Feature map의 평균값을 구해서 출력 노드에 입력하기 때문에 파라미터를 줄일 수 있고, 평균 풀링의 특성상 정보 손실의 가능성이 있음에도 불구하고 Flatten Layer를 사용했을 때보다 성능이 좋다. 이러한 이유에서 Average Pooling을 사용하는 것이다.

Pooling Layer의 특징

  • 풀링 계층에선 이미지의 공간적 크기를 줄이고, 중요한 특징 정보를 유지하기 때문에 이동 불변성(Translation invariant)을 지킬 수 있게 해준다.
    -> 즉, 이미지에서 패턴의 위치가 바뀌어도 그 패턴을 인식할 수 있게 된다는 것이다. 그렇기에 적은 수의 훈련 샘플을 사용해 일반화 능력을 가진 표현을 학습할 수 있게 된다. 이러한 풀링의 특성 때문에 CNN이 위치 변화에 강인하다고 이야기하기도 한다.

  • 풀링은 각 채널에 대해 독립적으로 연산된다. 따라서 입력 데이터의 채널 수 그대로 출력 데이터로 내보내게 된다. (즉, depth에 영향을 미치지 않는다는 말과 같다)

  • 풀링 계층은 합성곱 계층과는 달리 학습해야 할 매개변수가 없다.

 이러한 풀링의 종류에, 사실 Min Pooling도 존재한다. 하지만, 대부분 활성화 함수들이 0 이하의 값을 처리하는 방식을 살펴보면, 층이 깊어질수록 Min Pooling을 사용하는 건 적합하지 않다는 걸 알 수 있다. (ReLu만 봐도 0 이하의 값은 0으로 처리한다.)
 하지만, 흑백 이미지를 처리할 때, 만약 밝은 배경에 어두운 객체가 있는 이미지를 처리해야 한다면 배경은 높은 픽셀값, 객체는 낮은 픽셀값을 지니기에 이러한 경우엔 Min Pooling을 사용하기도 한다. (하지만 대부분의 경우에선 Max Pooling을 사용한다)

4. Convolutional Layer

 Convolutional Layer에서는 컨볼루션 연산을 수행한다. 이때, 컨볼루션 연산이란, 이미지의 지역적 특징을 찾아내는 것으로, 이미지를 작은 영역으로 나눠 각 영역에 대한 특정 패턴을 찾아낸다.

 아래의 사진과 같은 필터가 있다고 생각했을 때, 컨볼루션 레이어에선 커널을 이동시키면서 각 커널에 대한 컨볼루션 값에 활성화 함수를 취해 Feature map을 생성한다. 아래의 예시에선 활성화 함수로 ReLu를 활용한다.

 이렇게, 컨볼루션 연산을 수행하고 그 결과에 대해 활성화 함수를 적용하는 계층이 Convolutional Layer이다.

 하나의 컨볼루션 레이어에서 여러 개 커널을 동시에 학습하는 경우가 많은데, 그 이유는 여러 개 커널을 사용하면, 이를 통해 엣지, 텍스쳐, 패턴 등 더 많은 정보와 지역적인 특징, 복잡한 특징을 추출해 신경망이 더 정교하교 세밀한 패턴을 학습할 수 있기 때문이다.

 하지만, 커널 수가 너무 많으면 계산 비용과 모델 복잡도가 증가해 overfitting 현상이 발생할 수 있다.

 또한, 이미지는 (높이, 너비, 채널 크기)의 3차원 형태로 표현되는데 이때, 필터의 채널 수와 입력 이미지의 채널 수는 같아야 한다. 다시 말해, 입력 데이터의 채널 수가 3개고, 256개의 커널이 존재한다면, 첫 번째 커널의 채널 개수는 3개, 두 번째 커널의 채널 개수도 3개, 256번째 커널의 채널 개수도 3개 이런 식으로 총 256*3개의 파라미터를 가지는 것이다.

 컨볼루션 연산을 수행한 후에는, 커널의 개수가 레이어의 채널 크기가 된다.

 이러한 채널 크기를 깊이라고 이야기하기도 한다. 이러한 깊이가 깊어지면, low-level 특징(에지, 텍스처)뿐만 아니라 high-level 특징(형태, 객체 등)까지도 효과적으로 추출할 수 있어진다.

 CNN에도 편향 노드를 추가할 수 있는데, 이때 편향은 항상 하나(1*1)만 존재하며, 하나의 값을 필터를 적용한 모든 원소에 더한다.

 편향이 추가되면, 출력되는 feature map의 기본 공식은 다음과 같다.

  • output=activation((inputkernel)+bias)output = activation(∑(input * kernel) + bias)

 CNN은 이러한 Convolutional Layer와 Pooling Layer를 통해 정보를 추출하고 축소하는 과정을 반복해 주어진 이미지를 기반으로 핵심적인 특징을 학습한다.

 Conv-Pooling 계층을 반복해 가면서 깊은 CNN 모델을 쌓을 수도 있다. 이렇게 하면 모델의 성능 향상을 기대해 볼수도 있다. 다만, 단순히 깊게 쌓기만 하면, 너무 지역적인 특성들까지도 학습하게 되기 때문에 깊은 CNN을 구성하게 된다면, shortcut connection과 같은 방법들을 고려해 보는 것이 좋다.

profile
얼렁뚱땅 바보 학부생...

0개의 댓글