JINWOOJUNG

[ 컴퓨터 비전 ] Ch5. Deep Learning...3 본문

2024/Study

[ 컴퓨터 비전 ] Ch5. Deep Learning...3

Jinu_01 2024. 11. 26. 18:12
728x90
반응형

본 컴퓨터 비전 개념과 기법들에 대한 공부를 진행하면서 배운 내용들을 중심으로 정리한 포스팅입니다. 

책은 Computer Vision: Algorithms and Applications를 기반으로 공부하였습니다.

또한, 인하대학교 박인규 교수님의 컴퓨터 비전 과목을 기반으로 제작된 포스팅입니다.


https://jinwoo-jung.tistory.com/112

 

[ 컴퓨터 비전 ] Ch5. Deep Learning...2

본 컴퓨터 비전 개념과 기법들에 대한 공부를 진행하면서 배운 내용들을 중심으로 정리한 포스팅입니다. 책은 Computer Vision: Algorithms and Applications를 기반으로 공부하였습니다.또한, 인하대학교

jinwoo-jung.com


Difference of MLP and ConvNet

앞으로 살펴볼 CNN(=ConvNet)은 MLP와 차이가 있다. 

 

먼저 Convolution 연산 과정에서 Filter의 개수에 의해 Hidden Layer는 Volume을 가지는 3차원의 구조를 띈다. 

또한, Hidden Layer가 깊게 쌓이는 Deep한 구조를 가지며, MLP와 같이 Fully Connected가 아닌 Kernel Size에 따른 Locally Connected 구조를 가진다.

마지막으로 Activation Function은 ReLU가 주로 사용되는데, 이는 Layer가 Deep해질수록 학습 효과가 뛰어나기 때문이다. 

 

ReLU(Rectified Linear Units)

 

MLP에서 사용되는 Activation Function인 Sigmoid와 Tanh를 다시 살펴보자. Pre-activation Value가 커지면 커질수록 Gradient가 작아져 학습에 느리고 Global Optima에 도달하기 힘들다는 단점은 이미 언급하였다. 또 하나의 이유는, Activated Value의 Derivative Range는 $(0,0.25)$로 매우 작은 값을 가진다. Deep ConvNet에서는 Layer가 매우 Deep한 구조이기 때문에, Backpropagation 과정에서 Gradient가 곱해질수록 그 값은 0에 수렴하게 된다. 따라서 Weight의 Update가 일어나지 않아 학습에 영향을 준다. 이를 Vanishing Gradient Problem이라 한다. 

 

 

따라서 Activation Function으로 ReLU를 활용한다. 특히, ReLU의 미분의 경우 Sigmoid, Tanh와 같이 분자, 분모에 Exponential이 존재하지 않기 때문에 미분이 용이한 특징이 있다.

 

LeakyReLU

 

ReLU의 경우 $z \leq 0$의 경우 항상 0이기 때문에, 만약 Pre-activation Value가 음수인 경우 Gradient가 0이여서 Update가 않되는 Dying Node가 존재할 수 있다. 따라서 이를 보완한 것이 LeakyReLU이다. 

 

LeakyReLU의 경우 $z \leq 0$의 범위에서 역시 Gradient가 존재하는 특징이 있다. 

 

 

ELU(Exponential Linear Units)

 

ELU는 LeakyReLU에서 여전히 존재하는 0에서의 미분 불능을 해소한 Activation Function이라는 정도만 기억하고, $ z \leq 0$에서의 함수의 구조만 파악하고 넘어가자.

 

Convolutional Neural Network

아래는 AlexNet의 구조이다. CNN은 이처럼 Deep한 구조로 사용된다.

 

Input으로 사용되는 입력 영상은 R,G,B 3개의 체널을 가진 3 Dimension을 가진다. 이를 1D로 Flatten 할 수도 있지만, 픽셀과 이웃 픽셀간의 관계 등 구조적인 정보를 훼손하기 때문이 일반적으로 3D의 정보를 유지하게된다. 이처럼 3차원 구조를 가지는 Layer 구조를 Tensor라고 한다. 

 

 

Input 영상에 대하여 5x5 크기의 Fiter를 이용하여 Convolution을 수행한다고 하자. 현재 Input 영상은 R,G,B 3체널이기 때문에 각 Kernel 역시 3x5x5가 된다. 하나의 Filter에 의한 Convolution 및 Activation Function을 거친 결과는 왼쪽의 결과 중 각각이 되고 이는 다음 Tensor의 하나의 층으로 구성하게 된다. 따라서 Filter의 개수가 Output의 Dimension(Tensor의 Depth)을 결정하게 된다. 

 

이처럼 ConvNet은 Convolutional Layers의 sequence라고 표현할 수 있다. 

 

5x5 Filter에 의한 Convolution 연산을 생각해 보자. 이때, Filter는 항상 Input Volume의 Depth와 동일한 Depth를 가짐을 주의하자. 왼쪽 그림과 같이, Convolution 결과 $5 \times 5 \times 3 + 1$개의 Weights가 존재한다. 이때 동일한 Filter를 가지고 Input에 대하여 Convolution을 수행하기 때문에 연산 때 마다 새로운 Weights가 생기지 않는다. 따라서 Fully Connected Layer 보다 학습해야 할 Weights의 수가 적다.

 

 

만약 Filter의 개수가 총 6개라고 가정하면, 하나의 Filter와 Input 영상의 Convolution은 Output Tesnor의 한 층을 이루기 때문에 최종적으로 Output 즉 다음 Layer의 Tensor Depth는 Filter의 개수와 동일하게 된다. 그리고 최종적으로 $ 6 \times (5 \times 5 \times 3 + 1)$개의 Weights가 존재한다.

 

이때, Convolution을 통해 Output Tensor의 Width, Height가 줄어든 것을 확인할 수 있다. 이는 Convolution 시 Filter의 중심에 Filtering 된 결과가 저장되어 Output을 구성하기 때문이다. 

 

Receptive Field

 

이처럼 하나의 Output Pixel에 영향을 주는 Input에서의영역을 Receptive Field라고 한다.  

 

Receptive Field가 넓을수록 Globally Optimize되기에 좋지만, 학습의 어려움이 있다. 반대로, 너무 작으면 Input의 Local한 부분만 관찰할 수 밖에 없기 때문에 영상의 전체적인 큰 문맥(Context), Segment를 관찰할 수 없다. 

 

간단하게 수식화 하면, Layer의 개수를 $L$, Kernel Size를 $K$라고 했을 때, Receptive Field Size는 $(1 + L \times (K - 1)) \times (1 + L \times (K - 1))$가 된다. 하지만, Input 영상의 Resolution이 커지면 커질수록, Receptive Field가 Input 영상의 Resolution이 되기 까지 매우 깊은 Layer가 필요하고, 그로인하 Weights의 개수도 많아질 것이다.  따라서 모델이 영상의 전체를 관찰하고 이해하는데 너무 깊은 Layer가 요구됩니다.

 

Stride

Stride는 Receptive Field를 빠르게 확장시킬 수 있는 하나의 방법입니다.

 

Stride는 Kernel이 Input에 대하여 Convolution 연산을 수행할 때 이동하는 크기라고 정의할 수 있습니다. Stride가 1인 경우는 아래와 같이 1칸씩 이동하면서 Convolution 연산을 수행하게 됩니다. 이때, Kernel 크기가 $3 \times 3$이므로 Width, Height 양 끝의 1픽셀은 연산될 수 없기 때문에 Output의 $5 times 5$의 크기를 가지게 됩니다.

 

현재 3D에 대하여 Convolution을 수행하기 때문에 $i,j,k$각각은 Channel, Row, Column의 Index를 의미하며, Convolution 수행결과 다음과 같은 결과를 도출할 수 있다. 

 

만약 Stride가 2로 2배가 된다면, Kernel이 이동 시 2칸을 이동함을 확인할 수 있다. 따라서 이동 과정에서 포함하는 영역이 더 많아지기 때문에, Receptive Field가 2배로 증가하게 된다. 즉, 하나의 Output이 포함하는 Input 영역이 2배가 됨을 의미한다. 

 

이때, Stride의 경우 Convolution 과정에서의 Downsampling이다. 즉, Convolution 연산을 하면서 Stride의 정도에 따라 Output의 Size가 감소하게 된다. 

 

Padding

Convolution 연산이 수행되면서 즉, Filtering 이후에는 Output Layer의 크기가 줄어듬을 확인했을 것이다. 하지만, 여러 이유로 Filtering 이후에도 Resolution을 유지할 필요가 있는데, 이때 사용되는 기법이 Padding 기법이다. 

 

Padding은 아래와 같이 Input에 대하여 전체를 0인 값으로 감싸서 구현할 수 있는데, 이를 통해 Padding을 적용하기 이전에는 Convolution 연산할 수 없었던 Width, Height의 가장자리 픽셀에 대한 연산을 수행할 수 있어 Resolution이 유지되는 것을 확인할 수 있다. 실제로 $7 \times 7$의 Input 영상과 $3 \times 3% Kernel, Stride는 "2"인 Convolution 결과는 $3 \times 3$의 크기를 같는 Output이었지만, Padding 결과 $4 \times 4$로 Resolution이 어느정도 유지됨을 확인할 수 있다. 

 

따라서 Stride, Padding을 조합 해 보면, Input ($W_{in}$) , Kernel Size ($k$) , Padding ($p$) , Stride($s$)에 따른 Output의 크기는 왼쪽 아래 사진과 같이 정의된다. 특이사항으로는, Input과 Output의 영상의 크기가 같아지는 경우가 있는데, 실제 VGGNet에서는 이러한 목적으로 해당 조합을 사용하였다. 이때, $ \left \lfloor \right \rfloor$의 경우 Floor Function으로 안의 값을 내림하면 된다. 

 

Pooling

앞서 말한 것 처럼, Stride는 Convolution 과정에서의 Downsampling이지만, Pooling은 Input의 Dimension이 매우 클 때 Downsampling을 하여 차원을 축소하는 기법이다. 

 

일반적으로 Pooling은 Max Pooling이 사용된다. 이는 큰 값이 중요한 특징을 나타낸다는 것과 동일한 의미인데, Activation Function을 살펴보면 그 이유를 확인할 수 있다. ReLU를 살펴보면 $z > 0$인 경우 $R(z) = z$가 된다. 즉 Activation Function은 특정 입력이 주어졌을 때 활성화 된 정도를 나타내고, 이는 입력 데이터에서 중요한 정보를 발견했음을 의미한다. 따라서 Activation Function을 통과한 Output이 크다는 것은 중요한 정보임을 의미한다. 

 

따라서 Pooling 과정에서도 Average가 아닌 Max Pooling을 사용하는 것이다. 만약 작은 거나 음의 값을 가지는 Node와 Average를 수행하면, 전체적으로 0에 가까워지기 때문에 중요한 정보가 사라질 수 있고, Dying Node가 발생할 수 있다. 

 

 

결국 Pooling은 더 작은 차원으로 표현하면서 동시에 더 의미있는 정보를 유지하면서 표현하는 기법이다. 이를 통해 Receptive Field는 2배가 되며, 큰 Resolution을 가지는 Input Image를 더 작은 크기의 Class로 분류하기 위해서는 차원의 축소가 필수적이기 때문에 Pooling이 사용된다. 

 

Max Pooling 과정을 더 자세히 살펴보면 다음과 같다. $2 \times 2$ Filter, Stride 2로 Max Pooling 시키면 다음과 같다. 해달 Filter 내의 가장 큰 값만 가져오며 이때 원래 Node에서의 어느 위치에서의 값인지도 함께 저장한다. 이후, Backprop Gradient 과정에서 Max Pooling으로 선택된 Node에 대해서만 Update가 이루어진다. 

 

LeNet5

LeCun이 1998년에 제안한 CNN Architecture 입니다. 본 Architecture를 하나하나 분석 해 봅시다.

 

Input 영상의 경우 28x28의 GrayScale Image이다. 따라서 1x28x28의 Input 영상이 첫번재 Layer의 Input이 된다. 

이때, Kerner Size는 5, Padding은 2, Stride는 1이므로 수식에 근거하여 Output의 Size는 같다. 즉, 해상도는 유지하게 된다. 하지만, Kernel의 개수가 20개이므로 Output Size 20x28x28이 된다. 이때 발생되는 Weight의 경우, 각 Kernel 당 1x5x5개의 Weight가 발생하며 20개의 Kernel이 존재하므로 20x1x5x5개를 가진다. 

 

이후 Activation Function인 ReLU를 거치게 되며 Output Size는 그대로 유지한다. 

 

그다음 Max Pooling을 진행하는데, Kernel Size는 2, Stride는 2이다. 따라서 Output Size가 각각 $ \frac{1}{2}$되므로 Output Size는 20x14x14가 됨을 확인할 수 있다. 

 

이처럼 기본적인 CNN Architecture는 [ Conv, ReLU, Pool  ]이 하나의 Package 형태로 구성된다. 

 

다음 Conv Layer로 들어오는 Input Size는 20x14x14가 된다. 따라서 K가 5인 각 Kernel의 크기는 20x5x5가 된다. Convolution 연산은 Input에 대하여 수행되기에 각 Kernel의 Depth는 Input의 Depth와 동일해야 함을 생각하면 된다. 해당 Convolution 연산 역시 P는 2, S는 1이므로 동일하게 Output Size는 14x14로 유지하게 된다. 하지만, Kernel이 총 50개이므로 최종적인 Output은 50x14x14가 되고 Weight는 50x20x5x5개가 발생한다. 

 

동일하게 ReLU를 거친 뒤, Max Pooling을 통해 Output Size는 50x7x7이 된다.

 

이후 Flatten을 통해 Tensor 형태를 1차원의 Vector 형태로 변환한다. 이후 MLP를 거쳐 0~9의 숫자를 분류하는 Task이므로 Output이 10이 되도록 연산을 거친 뒤 Softmax를 통해 각 Class에 해당할 확률을 계산하여 최종적인 클래스를 예측하는 Architecture이다.

 

다른 분류 모델의 Architecture 역시 LeNet5와 유사한 구조를 가지면서 더 층이 깊어지는 구조를 가짐을 확인할 수 있다. 

 

AlexNet

다음으론  AlexNet이다. 이 역시 유사하지만 더 깊은 [ Conv, ReLU, Pool  ] 층이 존재함을 확인할 수 있다. 이처럼 Convolution을 통해 특징을 추출하는 부분을 Backbone이라 한다. AlexNet은 Max Pooling 뿐만 아니라, norm(Normalization)을 수행함을 확인할 수 있다. 이는 특정 Layer의 Output이 너무 커서 다른 Layer의 학습에 방해를 줄 수 있기에 Activation Value를 정규분포하는 과정이다. 자세한건 밑에서 다룰 것이다. 

 

SGD(Stochastic Gradient Descent)

Weight Update는 Backpropagation을 통해 Gradient Descent 방향으로 진행된다고 배웠다. 만약, 모든 Training Dataset에 대하여 Loss를 구한 뒤 평균을 계산하고, 그 평균을 이용하여 Gradient를 계산한다고 가정 해 보자. 이는 모든 데이터에 대한 Gradient를 계산하기 때문에 최적의 Gradient 방향을 제공하지만, 데이터 셋이 크면 비용이 매우 크고 메모리 사용량도 방대 해 질 것이다. 

 

이로인해 Stotachastic Gradient Descent 개념이 도입되었는데, 모든 Training Dataset이 아닌 매번 Training Dataset에서 하나의 샘플을 무작위로 선택해 해당 샘플에 대한 Loss와 Gradient를 계산하고 Weight를 Update하는 방법이다. 이는 빠른 업데이트가 가능하지만, Loss와 Gradient가 Noisy 해 학습의 불안정성이 존재한다. 

 

따라서 최종적으로는 Mini-batch Gradient Descent가 사용된다. 이는 하나의 샘플이 아닌 Mini-Batch 단위로 Random하게 데이터를 선별해서 Mini-Batch에 대해 Loss를 계산하고 Gradient를 계산하여 Weight를 업데이트 한다. 이는 계산 효율성과 안정성을 가짐과 동시에 일반화가 더 잘되고 Batch Gradient Descent와 동일한 수렴과 복잡성을 가진다. 

 

Mini-batch Gradient Descent

 

Mini-batch Gradient Descent는 아래와 같은 과정으로 동작합니다. 먼저 Training Dataset 중 Batch Size만큼 Random 하게 선택하여 Mini-Batch를 구성합니다. 이후 Forwards Pass를 거치면서 Mini-Batch 단위의 평균  Loss를 계산합니다. 이후 Backward Pass를 거치면서 Gradient를 계산하고 Parameter(Weight)를 Update 합니다. 이 과정을 전체 Batch에 대해서 수행할 때 까지 반복하며, 그때 1 Epoch이 진행되었다고 계산합니다.

 

최근에는 Adam Optimizer를 많이 사용하는데 이는 추후 자세히 알아보자.

 

728x90
반응형