본문 바로가기
IT/[혼공머신] 혼자 공부하는 머신러닝 + 딥러닝

[혼공머신] Ch.8 이미지를 위한 인공 신경망_1. 합성곱 신경망의 구성 요소

by vulter3653 2023. 10. 11.

 

 

<혼자 공부하는 머신러닝 + 딥러닝>의 'Ch.8 이미지를 위한 인공 신경망_1. 합성곱 신경망의 구성 요소'의 내용을 요약 및 정리한 내용입니다.

 

https://product.kyobobook.co.kr/detail/S000001810330

 

혼자 공부하는 머신러닝+딥러닝 | 박해선 - 교보문고

혼자 공부하는 머신러닝+딥러닝 | 혼자 해도 충분하다! 1:1 과외하듯 배우는 인공지능 자습서이 책은 수식과 이론으로 중무장한 머신러닝, 딥러닝 책에 지친 ‘독학하는 입문자’가 ‘꼭 필요한

product.kyobobook.co.kr


합성곱 신경망을 구성하는 기본 개념과 동작 원리를 배우고 간단한 합성곱, 풀링 계산 방법을 익힙니다.

1. 합성곱

합성곱은 입력 데이터에 마법의 도장을 찍어서 유용한 특성만 드러나게 하는 것으로 비유할 수 있습니다.

 

합성곱의 동작 원리를 자세히 알아보겠습니다.

 

밀집층에는 뉴런마다 입력 개수만큼의 가중치가 있으며, 모든 입력에 가중치를 곱합니다.

 

만약 특성이 [3, 1, 0, 7, 6, 4, 8, 2, 4, 5] 라면 밀집층의 계산은 아래와 같습니다.

 

$$  3*w_{1}+1*w_{2}+0*w_{3}+7*w_{4}+6*w_{5}+4*w_{6}+8*w_{7}+2*w_{8}+4*w_{9}+5*w_{10}+b $$

 

이렇게 인공 신경망은 처음에 가중치 w1~w10과 절편 b를 랜덤하게 초기화한 다음 에포크를 반복하면서 경사 하강법 알고리즘을 사용하여 손실이 낮아지도록 최적의 가중치와 절편을 찾아가며 모델 훈련을 합니다.

 

합성곱은 위의 밀집층의 계산과 조금 다릅니다. 그건 바로 입력 데이터 전체에 가중치를 적용하는 것이 아니라 일부에 가중치를 곱하는 것입니다. 이러한 가중치의 개수는 정해줘야 하는 하이퍼파라미터에 해당합니다.

 

만약 위의 특성이 뉴런이 3개의 가중치를 가질 경우라면 아래와 같습니다.

 

출처 :&nbsp;https://www.youtube.com/watch?v=tPLRox0YYc8&list=PLVsNizTWUw7HpqmdphX9hgyWl15nobgQX&index=20

 

1. 가중치 w1~w3이 입력의 처음 3개의 특성과 곱해져 1개의 출력을 만듭니다.

2. 이 뉴런이 한 칸 아래로 이동해 두 번째부터 네 번째 특성과 곱해져 1번과 다른 새로운 출력을 만듭니다.

3. 또 다시 한 칸 아래로 이동해 세 번째부터 다섯 번째 특성과 곱해져 1,2번과 다른 새로운 출력을 만듭니다.

. . .

 

여기에서 중요한 것은 첫 번쨰 합성곱에 사용된 가중치 w1~w3과 절편 b가 두 번째 합성곱에도 동일하게 사용됩니다. 이렇게 한 칸씩 아래로 이동하면서 출력을 만드는 것이 합성곱입니다. 여기에서는 이 뉴런의 가중치가 3개이기 때문에 모두 8개의 출력이 만들어집니다.

 

위의 그림에서는 구분에 도움을 주기 위해 8번의 계산을 다른 색으로 나타냈지만 모두 같은 뉴런에 해당합니다. 즉 모두 가중치 w1~w3과 절편 b를 사용합니다.

 

이러한 합성곱 신경망에서는 뉴런을 필터 혹은 커널이라고 부릅니다. 여기에서는 케라스 API와 이름을 맞추어 뉴런 개수를 이야기할 때는 필터라고, 입력에 곱해지는 가중치를 의미라 때는 커널이라고 부르겠습니다.

 

또한 합성곱은 1차원뿐 아니라 2차원에서도 사용가능한 장점이 존재합니다. 이 경우, 2차원 구조를 그대로 사용하기 때문에 합성곱이 이미지 처리 분야에서 뛰어난 성능을 보입니다.

 

다음으로 케라스에서 합성곱 층을 어떻게 만드는지 보겠습니다.

 

2. 케라스 합성곱 층

 

케라스의 층은 모두 keras.layer 패키지 아래 클래스로 구현되어 있습니다. 합성곱 층도 마찬가지입니다. 특별히 입력 위를 (왼쪽에서 오른쪽으로 ,위에서 아래로) 이동하는 합성곱은 Conv2D 클래스로 제공합니다.

 

from tensorflow import keras
keras.larers.Conv2D(10, kernel_size=(3,3), activation='relu')

 

Conv2D 클래스의 첫 번째 매개변수는 필터의 개수입니다. kernel_size 매개변수는 필터에 사용할 커널의 크기를 지정합니다. 필터의 개수와 커널의 크기는 반드시 지정해야 하는 매개변수입니다.

 

마지막으로 밀집층에서처럼 활성화 함수를 지정합니다. 여기서는 렐루 함수를 선택했습니다.

 

이렇게 케라스 API를 사용하면 합성곱 층을 사용하는 것이 어렵지 않습니다. 이전에 Dense 층을 사용했던 자리에 대신 Conv2D 층을 넣으면 됩니다. 다만 kernel_size와 같이 추가적인 매개변수들을 고려해야 합니다.

 

좋습니다. 합성곱 층이 구현된 케라스 API를 잠시 살펴보았습니다. 그런데 합성곱 신경망을 실제 만들려면 조금 더 알아야 할 것이 있습니다. 호흡을 가다듬고 패딩과 스트라이드를 알아보겠습니다.

 

2.1 패딩과 스트라이드

커널 크기는 (3,3)으로 그대로 두고 출력의 크기를 입력과 동일하게 (4,4)로 만들려면 어떻게 해야 할까요?

 

(4,4) 입력과 동일한 크기의 출력을 만들려면 마치 더 큰 입력에 합성곱 하는 척해야 합니다.

 

예를 들어 실제 입력 크기는 (4,4)이지만 (6,6)처럼 다룬다고 가정해 보겠습니다. 이 경우에 (3,3) 크기의 커널로 합성곱을 하게 되면 출력의 크기는 (4,4)가 되게 됩니다.

 

(3,3) 커널로 도장을 찍어보면 출력의 크기가 (4,4)가 되는 것을 알 수 있습니다. 다음 그림의 빨간색 상자가 커널을 나타냅니다. 왼쪽 위에서 오른쪽 아래까지 한 칸씩 이동하면서 합성곱을 수행하면 입력과 같은 (4,4) 크기의 출력을 만들 수 있습니다.

 

출처 :&nbsp;https://www.youtube.com/watch?v=tPLRox0YYc8&list=PLVsNizTWUw7HpqmdphX9hgyWl15nobgQX&index=20

 

이렇게 입력 배열의 주위를 가상의 원소로 채우는 것을 패딩이라고 합니다. 실제 입력값이 아니기 때문에 패딩을 0으로 채웁니다. 즉 (4,4) 크기의 입력에 0을 1개 패딩 하면 다음과 같은 (6,6) 크기의 입력이 됩니다. 패딩의 역할은 순전히 커널이 도장을 찍을 횟수를 늘려주는 것밖에는 없습니다. 실제 값은 0으로 채워져 있기 때문에 계산에 영향을 미치지는 않습니다.

 

출처 :&nbsp;https://www.youtube.com/watch?v=tPLRox0YYc8&list=PLVsNizTWUw7HpqmdphX9hgyWl15nobgQX&index=20

 

이렇게 입력과 특성 맵의 크기를 동일하게 만들기 위해 입력 주위에 0으로 패딩 하는 것을 세임 패딩이라고 부릅니다. 합성곱 신경망에서는 세임 패딩이 많이 사용됩니다. 이를 바꿔 말하면 입력과 특성 맵의 크기를 동일하게 만드는 경우가 많다는 의미입니다.

 

이러한 패딩 없이 순수한 입력 배열에서만 합성곱을 하여 특성 맵을 만드는 경우를 밸리드 패딩이라고 합니다. 밸리드 패딩을 특성 맵의 크기는 당연히 줄어들게 됩니다.

 

합성곱에서 패딩을 사용하는 이유

그럼 왜 합성곱에서는 패딩을 즐겨 사용할까요?

 

만약 패딩이 없다면 위의 예에서 (4,4) 크기의 입력에 패딩 없이 합성곱을 한다면 네 모서리들은 커널 도장에 딱 한 번만 찍히게 됩니다. 반면 다른 원소들은 2번 이상 커널과 계산됩니다. 특히 가운데 있는 4개의 원소 4, 8, 5, 1은 4번의 합성곱 계산에 모두 포함되게 됩니다.

 

만약 이 입력을 이미지라고 생각하면 모서리에 있는 중요한 정보가 특성 맵으로 잘 전달되지 않을 가능성이 높습니다. 반면 가운데 있는 정보는 두드러지게 표현됩니다.

 

출처 :&nbsp;https://www.youtube.com/watch?v=tPLRox0YYc8&list=PLVsNizTWUw7HpqmdphX9hgyWl15nobgQX&index=21

 

위의 그림을 보면 패딩을 하지 않을 경우 중앙부와 모서리 픽셀이 합성곱에 참여하는 비율은 크게 차이 납니다 (4:1). 1픽셀을 패딩 하면 이 차이는 크게 줄어듭니다(9:4). 만약 2픽셀을 패딩하면 중앙부와 모서리 픽셀이 합성곱에 참여하는 비율이 동일해집니다.(1:1)

 

적절한 패딩은 이처럼 이미지의 주변에 있는 정보를 잃어버리지 않도록 도와줍니다. 앞에서도 말한 것 처럼 일반적인 합성곱 신경망에서는 세임 패딩이 많이 사용됩니다. 케라스 Conv2D 클래스에서는 padding 매개변수로 패딩을 지정할 수 있습니다. 기본값은 'valid'로 밸리드 패딩을 나타냅니다. 세임 패딩을 사용하려면 'same'으로 지정합니다.

 

keras.layers.Conv2D(10, kernel_size=(3,3), activation='relu', padding='same')

 

지금까지 본 합성곱 연산은 좌우, 위아래로 한 칸씩 이동했습니다. 하지만 두 칸씩 건너뛸 수도 있습니다. 이렇게 두 칸씩 이동하면 커널의 횟수가 줄어들기에 만들어지는 특성 맵의 크기는 더 작아지게 됩니다.

 

이런 이동의 크기를 스트라이드라고 합니다. 기본으로 스트라이드는 1입니다. 즉 한 칸씩 이동합니다. 이 값이 케라스 Conv2D의 strides 매개변수의 기본값입니다.

 

keras.layers.Conv2D(10, kernel_size=(3,3), activation='relu', padding='same', strides=1)

 

strides 매개변수는 오른쪽으로 이동하는 크기와 아래쪽으로 이동하는 크기를 (1,1)과 같이 튜플을 사용해 각각 지정할 수eh 있습니다. 하지만 커널의 이동 크기를 가로세로 방향으로 다르게 지정하는 경우는 거의 없습니다. 또 1보다 큰 스트라이드를 사용하는 경우도 드뭅니다. 대부분 기본값을 그대로 사용하기 때문에 strides 매개변수는 잘 사용하지 않습니다.

 

여기서 꼭 기억해야 할 것은 세임 패딩의 경우 입력과 만들어진 특성 맵의 가로세로 크기가 같다는 점입니다.

 

합성곱 신경망의 마지막 구성 요소인 풀링으로 넘어가 보겠습니다.

 

2.2 풀링

풀링은 합성곱 층에서 만든 특성 맵의 가로세로 크기를 줄이는 역할을 수행합니다. 하지만 특성 맵의 개수는 줄이지 않는다는 특징이 있습니다. 예를 들면 다음 그림처럼 (2,2,3) 크기의 특성 맵에 풀링을 적용하면 마지막 차원인 개수는 그대로 유지하고 너비와 높이만 줄어들어 (1,1,3) 크기의 특성 맵이 됩니다.

 

출처 :&nbsp;https://www.youtube.com/watch?v=tPLRox0YYc8&list=PLVsNizTWUw7HpqmdphX9hgyWl15nobgQX&index=21

 

풀링도 합성곱처럼 입력 위를 지나가면서 도장을 찍습니다. 위 그림에서는 (2,2) 크기로 풀링을 합니다. 하지만 풀링에는 가중치가 없습니다. 도장을 찍은 영역에서 가장 큰 값을 고르거나 평균값을 계산합니다. 이를 각각 최대 풀링평균 풀링이라고 부릅니다.

 

최대 풀링의 예를 보겠습니다. 다음은 (4,4)의 특성맵이며 (2,2) 최대 풀링을 적용한 경우 입니다.

 

 

출처 :&nbsp;https://www.youtube.com/watch?v=tPLRox0YYc8&list=PLVsNizTWUw7HpqmdphX9hgyWl15nobgQX&index=21

 

최대 풀링은 가장 큰 값을 고르기 때문에 첫 번째 (2,2) 영역에서 9를 고르고 그다음 7, 8, 6을 차례대로 골라 (2,2) 크기의 출력을 만듭니다. 특성 맵이 여러 개라면 동일한 작업을 반복합니다. 즉 10개의 특성 맵이 있다면 풀링을 거친 특성 맵도 10개가 됩니다.

 

여기서 볼 점은 풀링 영역이 두 칸씩 이동했다는 점입니다. 합성곱에서는 커널이 한 칸씩 이동했기 때문에 겹치는 부분이 있었습니다. 하지만 풀링에서는 겹치지 않고 이동합니다. 따라서 풀링의 크기가 (2,2)이면 가로세로 두 칸씩 이동합니다. 즉 스트라이드가 2입니다. (3,3) 풀링이면 가로세로 세 칸씩 이동합니다.

 

풀링은 가중치가 없고 풀링 크기와 스트라이드가 같기 때문에 이해하기 쉽습니다. 또 패딩도 없습니다. 케라스에서는 MaxPooling2D 클래스로 풀링을 수행할 수 있습니다.

 

keras.layers.MaxPooling2D(2)

 

 

MaxPooling2D의 첫 번째 매개변수로 풀링의 크기를 지정합니다. 대부분 풀링의 크기는 2입니다. 즉 가로세로 크기를 절반으로 줄입니다. 가로세로 방향의 풀링 크기를 다르게 하려면 첫 번째 매개변수를 정수의 튜플로 지정할 수도 있습니다. 하지만 이런 경우는 극히 드뭅니다.

 

합성곱 층과 마찬가지로 strides와 padding 매개변수를 제공합니다. strides의 기본값은 자동으로 풀링의 크기이므로 따로 지정할 필요가 없습니다. padding의 기본값은 'valid'로 패딩을 하지 않습니다. 앞서 언급한 대로 풀링은 패딩을 하지 않기 때문에 이 매개변수를 바꾸는 경우 역시 거의 없습니다.

 

위에서 사용된 최대 풀링과 같은 코드의 예는 다음과 같습니다.

 

keras.layers.MaxPooling2D(2, strides=2, padding='valid')

 

평균 풀링을 제공하는 클래스는 AveragePooling2D입니다. 최댓값 대신 평균을 계산하는 것만 빼면 MaxPooling2D와 동일하며 제공하는 매개변수도 같습니다. 하지만 평균 풀링은 특성 맵에 있는 중요한 정보를 희석시킬 수 있기 때문에 많은 경우, 최대 풀링을 많이 사용합니다. 

 

여기서 꼭 기억할 점은 풀링은 가로세로 방향으로만 진행한다는 것과 특성 맵의 개수는 변하지 않고 그대로라는 점 입니다. 이제 합성곱의 중요한 모든 요소를 배웠습니다. 합성곱 신경망의 전체 구조를 살펴보겠습니다.

 

3. 합성곱 신경망의 전체 구조

지금까지 합성곱 층, 필터, 패딩, 스트라이드, 풀링 등 중요한 합성곱 신경망의 개념을 모두 살펴보았습니다.

 

이들을 합쳐서 전체 구조를 표현한 그림은 아래와 같습니다. 

 

출처 :&nbsp;https://www.youtube.com/watch?v=tPLRox0YYc8&list=PLVsNizTWUw7HpqmdphX9hgyWl15nobgQX&index=21

 

먼저 입력층부터 살펴보겠습니다.

 

합성곱 층에서 사용할 커널의 크기는 (3,3) 크기이고 세임 패딩이므로 1픽셀이 입력 데이터 주변에 추가되었습니다. 이때 패딩은 텐서플로에서 자동으로 추가하므로 수동으로 입력해 어떤 작업을 추가할 필요가 없습니다. 그다음 패딩이 추가된 입력에서 합성곱이 수행됩니다.

 

이 그림에서 합성곱의 필터는 3개입니다. 각각 (3,3) 크기 가중치를 가지고 있으며 필터마다 절편이 하나씩 있습니다. 이때 밀집층의 뉴런과 마찬가지로 필터의 가중치는 각기 서로 다릅니다.

 

따로 언급하지 않는다면 합성곱의 스트라이드는 항상 1입니다. 따라서 만들어지는 특성 맵의 크기는 입력과 동일한 (4,4)입니다. 3개의 필터가 하나씩 합성곱의 출력을 만들고 이 출력을 만들고 이 출력이 합쳐져서 (4, 4, 3) 크기의 특성 맵이 만들어집니다. 밀집층과 마찬가지로 합성곱 층에서도 활성화 함수를 적용합니다. 합성곱 층은 활성화 함수로 렐루 함수를 많이 사용합니다.

 

그다음은 풀링 층입니다. 풀링 층은 합성곱 층에서 만든 특성 맵의 가로세로 크기를 줄입니다. 보통 (2,2) 풀링을 사용해 절반으로 줄입니다. 특성 맵의 개수는 변하지 않으므로 (4,4,3)에서 (2,2,3)으로 특성 맵 개수는 유지된 게 보입니다.

 

풀링을 사용하는 이유는 합성곱에서 스트라이드를 크게 하여 특성 맵을 줄이는 것보다 풀링 층에서 크기를 줄이는 것이 더 나은 성능을 내기 때문입니다. 합성곱 신경망은 이렇게 합성곱 층에서 특성 맵을 생성하고 풀링에서 크기를 줄이는 구조가 쌍을 이룹니다.

 

풀링을 거친 특성 맵의 크기는 절반으로 줄었기 때문에 (2, 2, 3)이 됩니다. 밀집층인 출력층에 전달하려면 이 3차원 배열을 1차원으로 펼쳐야 합니다. 이 배열은 12개의 원소를 가진 1 차원 배열이고 출력층의 입력이 됩니다.

 

출력층에는 3개의 뉴런을 두었습니다. 즉 3개의 클래스를 분류하는 다중 분류 문제입니다. 출력층에서 계산된 값은 소프트맥스 활성화 함수를 거쳐 최종 예측 확률이 됩니다.

 

3.1 컬러 이미지를 사용한 합성곱

 

지금까지는 입력을 2차원 배열이라고 가정했습니다. 이 장에서 다룰 패션 MNIST 데이터는 실제로 흑백 이미지이기 때문에 2차원 배열로 표현할 수 있습니다. 하지만 컬러 이미지라면 얘기가 달라집니다. 컬러 이미지는 RGB 채널로 구성되어 있기 때문에 컴퓨터는 이를 3차원 배열로 표시합니다. 이를 표현한 그림은 아래와 같습니다.

 

출처 :&nbsp;https://www.youtube.com/watch?v=tPLRox0YYc8&list=PLVsNizTWUw7HpqmdphX9hgyWl15nobgQX&index=21

 

즉 하나의 컬러 이미지는 너비와 높이 차원 외에 깊이 차원이 있습니다. 이런 경우에는 어떻게 합성곱이 수행될까요?

 

깊이가 있는 입력에서 합성곱을 수행하기 위해서는 도장도 깊이가 필요합니다. 즉 필터의 커널 크기가 (3,3)이 아니라 (3,3,3)이 됩니다. 이 합성곱의 계산은 (3,3,3) 영역에 해당하는 27개의 원소에 27개의 가중치를 곱하고 절편을 더하는 식이 됩니다. 

 

출처 :&nbsp;https://www.youtube.com/watch?v=tPLRox0YYc8&list=PLVsNizTWUw7HpqmdphX9hgyWl15nobgQX&index=21

 

여기서 중요한 것은 입력이나 필터의 차원이 몇 개인지 상관없이 항상 출력은 하나 값이라는 점입니다. 즉 특성 맵에 있는 한 원소가 채워집니다.

 

케라스의 합성곱 층은 항상 이렇게 3차원 입력을 기대합니다. 만약 패션 MNIST 데이터처럼 흑백 이미지일 경우에는 깊이 차원이 1인 3차원 배열로 변환하여 전달합니다.

 

예를 들어 (28, 28) 크기의 2차원 배열을 (28, 28, 1) 크기의 3차원 배열로 변환합니다. 원소 개수는 동일하면서 차원만 맞춘 것입니다.

 

이와 비슷한 경우가 또 있습니다. 합성곱 층-풀링 층 다음에 다시 또 합성곱 층이 올 때입니다. 예를 들어 첫 번째 합성곱 층의 필터 개수가 5개라고 가정하여 첫 번째 풀링 층을 통과한 특성 맵의 크기가 (4,4,5)라고 해보죠.

 

두 번째 합성곱 층에서 필터의 너비와 높이가 각각 3이라면 이 필터의 커널 크기는 (3,3,5)가 됩니다. 왜냐하면 입력의 깊이와 필터의 깊이는 같아야 하기 때문입니다. 그후 이 합성곱의 결과는 1개의 출력을 만듭니다.

 

두 번째 합성곱 층의 필터 개수가 10개라면 만들어진 특성 맵의 크기는 (2,2,10)이 될 것입니다. 이렇게 합성곱 신경망은 너비와 높이는 점점 줄어들고 깊이는 점점 깊어지는 것이 특징입니다. 그리고 마지막에 출력층 전에 특성 맵을 모두 펼쳐서 밀집층의 입력으로 사용합니다.

 

합성곱 신경망에서 필터는 이미지에 있는 어떤 특징을 찾는다고 생각할 수 있습니다. 처음에는 간단한 기본적인 특징을 찾고 층이 깊어질수록 다양하고 구체적인 특징을 감지할 수 있도록 필터의 개수를 늘립니다. 또 어떤 특징이 이미지의 어느 위치에 놓이더라도 쉽게 감지할 수 있도록 너비와 높이 차원을 점점 줄여갑니다.

 

4. 합성곱 층과 풀링 층 이해하기

이번에는 합성곱 신경망을 구성하는 핵심 개념을 살펴보았습니다. 여기에는 합성곱, 필터, 패딩, 스트라이드 풀링 등이 포함되어 있었습니다. 합성곱 신경망은 직관적으로 이해하기 쉽지 않지만 이미지 처리에서 뛰어난 성능을 발휘할 수 있도록 발전된 결과물입니다.

 

또한 합성곱 층과 풀링 층은 거의 항상 함께 사용됩니다. 합성곱 층에서 입력의 크기를 유지하며 각 필터가 추출한 특성 맵을 출력 하면 풀링 층에서 특성 맵의 가로세로를 줄입니다. 일반적으로 최대 풀링을 즐겨 사용하며 특성 맵을 절반으로 줄입니다. 마지막에는 특성 맵을 1차원 배열로 펼쳐서 1개 이상의 밀집층에 통과시켜 클래스에 대한 확률을 만듭니다.


Q. OX 문제

1. 밀집층에는 뉴런마다 입력 개수 만큼의 가중치가 존재한다. (O)

2. 합성곱 신경망에서 여러 번 계산을 하더라도, 모두 같은 뉴런이다. (O)

3. 밸리드 패딩을 입력 주위에 0으로 패딩하는 것을 말한다. (X)

4. 풀링에는 가중치가 없다. (O)

5. 컬러 이미지는 RGB 채널로 구성되어 있기에 3차원 배열로 표시되며, 흑백 이미지는 흑백 채널로 구성되어 있기에 2차원 배열로 표시된다. (X)