Computer Vision

- Image Classification

- Object detection

- Neural Style Transfer

컴퓨터 비전의 문제 중의 하나는 매우 큰 input을 가질 수 있다는 것인데, 만약 3채널(RGB)의 64 x 64 크기의 이미지로 작업을 한다고 했을 때에는 입력의 크기가 64 x 64 x 3 = 12288가 된다. 이정도는 그리 나쁜 것은 아니지만, 만약 1000 x 1000 크기의 매우 고화질의 이미지를 입력으로 사용한다면, 300만의 input size를 가지게 된다. 즉 입력은 300만 차원이 되는 것이고, 다음 hidden layer의 unit size가 1000이라면, (1000, 3m) 차원의 파라미터를 가지게 되는 것이다.

그렇다면 고화질 이미지에 대한 파라미터의 개수는 30억개가 되며, 이렇게 많은 파라미터를 가진 NN이 overfitting(과대적합)을 피할만큼 충분한 데이터를 얻는 것이 어렵고, 컴퓨터 사양이나 메모리 사용량을 고려한다면 실행이 불가능하다.

하지만, 컴퓨터 비전 app을 학습할 때, 작은 이미지에 한정되어서 사용하기는 원하지 않기 때문에, 이러한 문제점을 해결하기 위한 방법들을 배워보도록 할 것이다.

 

Edge detection Example

왼쪽 이미지가 있을 때, 오른쪽처럼 어떻게 수직 모서리나 수평 모서리를 감지할 수 있을까?

그렇다면, 위의 3x3 filter로 convolution 연산을 진행한 것이 어떻게 vertical edge detection을 수행하게 되는 것일까?

조금 더 단순한 이미지를 가지고 convolution 연산한 결과를 살펴보도록 하자.

이미지의 각 element의 숫자가 높을수록 밝고, 낮을수록 어둡다고 할 때, 각 이미지, filter, output은 위와 같이 연산된다.

input 이미지를 봤을 때, 중앙에 edge가 있으며 우리는 이것을 검출하면되는데, 3x3 vertical edge detection filter를 사용해서 연산을 하게 되면 오른쪽 4x4 output을 얻을 수 있다. 중앙에 아주 밟은 하얀색 부분이 존재하게 되는데, 이 부분에 의해서 vertical edge를 감지할 수 있다.

우리가 input 이미지를 꽤 작은 것으로 사용했기 때문에, 흰색 부분이 꽤 두꺼워 보일 수 있는데, 만약 1000x1000과 같은 고해상도의 이미지를 사용한다면, 이미지의 vertical edge가 더 잘 감지될 것이다.

 

More Edge Detection

이번에는 positive edgenegative edge의 차이점과 다른 유형의 edge detector를 살펴보도록 하자.

방금 전 위에서 봤던 예시인데, input 이미지가 왼쪽은 밝고 오른쪽은 어두운 이미지이다. 이러한 Edge를 positive edge라고 한다. 그리고 3x3 filter를 conv 연산을 통해서 이미지 가운데에 vertical edge를 감지하도록 했다.

만약 input 이미지의 색상이 뒤집어져서, 왼쪽이 어둡고 오른쪽이 밝게 된다면 어떻게 될까? 즉, negative edge인 이미지를 의미한다.

전환되는 명암이 반대가 되기 때문에, 위와 같이 conv 연산 결과값이 -30으로 나타나게 된다. 이것은 edge가 어두운 색에서 밝은 색으로 변환한 것을 감지했다는 의미이고, 만약 positive나 negative를 신경쓰지 않는다면, output matrix에 절대값을 얻어서 사용하면 된다.

지금까지 vertical edge detection을 살펴보았는데, horizontal edge detection은 아래의 filter를 사용해서 감지할 수 있다.

그래서 위와 같은 6x6 이미지가 조금 복잡한 예시이긴 하지만, 이 input 이미지를 horizontal edge filter와 conv연산을 하게 되면, 오른쪽 4x4 output matrix를 얻을 수 있다. 초록색 박스의 경우에는 10 -> 0으로 변화하는 positive edge의 결과이며, 보라색 박스의 경우는 0 -> 10으로 변화하는 negative edge의 결과이다. 여기서 노란색 박스의 10을 살펴보면, 왼쪽은 positive edge를 감지하고 있고, 오른쪽은 negative edge를 감지하고 있는 것을 볼 수 있다. 따라서 두 edge 감지가 섞여서 중간값을 나타내고 있는것이다. 6x6 이미지는 매우 작기 때문에 체감이 되지 않겠지만, 1000x1000 정도의 이미지라고 한다면, 10이나 -10과 같은 전환영역은 보이지 않게 된다.

지금까지 vertical, horizontal edge detection filter를 살펴봤는데, 이는 우리가 선택할 수 있는 filter들 중에 일부이다.

이렇게 우리가 9개의 숫자를 선택할 수 있는데, 딥러닝에서는 직접 선택할 필요가 없으며, 학습을 통해서 이 값들을 얻게 된다. 즉, 3x3 filter의 경우에는 9개의 학습할 parameter를 갖게 되는 것이다.

그렇기 때문에, 어느 방향의 edge detection이든지 데이터로부터 학습할 수 있다. (이것은 low-level의 feature가 된다)

따라서, CNN에서의 장점은 어떤 특정한 filter를 선택하는 것이 아니라, 학습을 통해서 최적의 filter(일종의 weight)를 얻게 되는 것이다.

 

Padding

6x6 이미지에 3x3 filter로 conv연산을 했을 때, output matrix가 4x4의 크기를 갖는 것을 보았다. 4x4 matrix가 되는 이유는 3x3 filter가 input 이미지에 놓일 수 있는 공간이 4x4이기 때문이다.

따라서, (n x n) image * (f x f) filter를 연산하면 (n - f + 1) x (n - f + 1)의 output을 얻을 수 있다.

이 부분에서 2가지 단점이 존재한다.

1. convolution 연산을 수행할 때마다 이미지가 작아진다. 계속해서 작아진다면, 몇 번의 conv연산 밖에 할 수 없게 된다.

2. 코너나 모서리에 존재하는 픽셀은 많이 사용되지 않는다. -> 코너나 모서리에 존재하는 픽셀의 정보를 버리는 것과 같다.

이렇게 이미지가 conv연산을 할 때마다 줄어든다면, 만약 100개의 deep layer를 가진 network가 있을 때 100 layer 이후에는 너무나 작은 이미지만 남게 되고, 또한 가장자리의 정보들을 버리게 된다.

이 문제점을 해결하기 위해서 우리는 경계에 이미지를 채워서(padding을 추가해서), conv연산을 이미지 전체에 적용하면 된다.

위와 같이, 원래 6x6 이미지에 padding을 추가해서 8x8이미지로 만들고 3x3 filter를 통해서 conv연산을 수행하면, output matrix는 입력 이미지와 동일한 6x6 크기의 matrix를 얻을 수 있게 되며, 원본 이미지의 크기를 보존하게 된다.

padding의 정도를 p라고 한다면, (기본 p = 0; no padding) 아래와 같은 공식으로 크기가 결정된다.

(n + 2p, n + 2p) image * (f, f) filter = (n + 2p - f + 1, n + 2p - f + 1) output

물론 p=2, 2개의 pixel을 추가해도 된다.

padding의 존재에 따라서 두 가지 옵션의 convolution이 있는데, 각각 Valid Convolution, Same Convolution이라고 부른다.

Valid Convolution은 기본적으로 padding없이 conv연산하는 것을 의미한다.

Same Convolution은 padding을 추가해서 input size가 output size와 동일하도록 conv연산하는 것을 의미한다.

Same Convolution에 대해서 조금 더 살펴보면, input image가 (n, n), filter가 (f, f), 그리고 padding을 p만큼 적용한다면, output matrix는 (n+2p-f+1, n+2p-f+1)이 된다. 우리는 이 size가 input과 동일하도록 만들기 위해서 방정식으로 정리하면, 결국 p = \frac{f - 1}{2}p=2f−1​로 나타낼 수 있다.

전형적으로 f는 거의 홀수이며, 만약 짝수라면, 비대칭 padding을 해야한다.(f를 홀수로 지정해서 중앙 포지션을 갖도록 하는 것이 computer vision에서 좋은 편이다) f가 홀수인 것이 항상 좋다는 이유는 될 수 없지만, 많은 논문에서 3x3 filter가 흔하며, 5x5, 7x7, 1x1의 filter도 존재하며, 만약 f가 짝수더라도 좋은 성능을 낼 수도 있다.

 

Strided Convolutions

Strided Convolution은 CNN에서 사용되는 기본적인 building block 중의 하나이다. 7x7 이미지를 3x3 filter와 conv연산을 수행하는데, stride = 2로 설정한다고 하면 다음과 같은 연산된다.

첫 번째 element는 이전과 동일하게 진행하지만, 2번째 element는 원본 이미지에서 2칸 이동해서 element-wise 곱을 수행하게 된다.

그 결과, 우리는 7x7 image와 3x3 filter를 conv연산을 통해서 3x3 output matrix를 얻게 된다. input과 output 크기는 다음 공식에 따라서 결정된다. (padding p, stride s가 있을 때)

⌊z⌋=floor(z)를 의미하며, 만약 정수가 아니라면 소수점은 버리게 된다. 즉, 위에서 파란색 박스가 이미지 내에 완전히 포함될 경우에만 유효하다는 것을 의미한다.

여기서는 p = 0이고, s = 2 이기 때문에, 공식을 적용하면 다음과 같이 된다.

Convolutions Over Volumne

지금까지 2-dim에서의 convolution 연산을 살펴보았고, 이제는 3-dim 이상의 volume에서 어떻게 conv연산을 수행하는지 살펴보자.

우선 RGB channel을 가지고 있는 이미지를 convolution 연산을 수행한다면, 연산에 사용되는 filter의 channel은 input 이미지의 channel과 동일해야 한다. 이렇게 연산을 하게 되면, ouput은 4x4가 되는데, 이것은 4x4x1이라는 것을 명심해야한다. 어떻게 연산되는지 자세하게 살펴보자.

일반적인 conv연산과 거의 동일하며, 차이점은 input과 filter를 각각의 채널에서 요소간의 곱을 수행한다. 그러면 각 채널마다 9개의 결과값이 나오고, 총 27개의 결과값이 나오게 된다. 그리고 이 결과값들을 모두 더해주면, 최종 output이 되는 것이다. 나머지 element들도 기존과 동일한 방법으로 구하고, 채널끼리 conv 연산을 수행해서 모두 더해주면 된다.

그리고, 만약 R Channel에서만 Edge를 감지하고 싶다면, R channel만 채워고, 나머지 channel은 전부 0으로 채우면 된다.

이렇게 하면, R Channel에서만 Vertical Edge 감지하는 filter가 된다.

또는, vertical edge의 색상을 신경쓰지 않는다면, 3가지 channel에 모두 동일하게 vertical edge detector로 만들 수 있으며, 이렇게 만든다면 어느 색상의 모서리도 감지할 수 있는 filter가 된다.

이렇게 파라미터를 다르게 선택함으로써, 3x3x3 filter로부터 다른 feature detector를 얻을 수 있다.

위 예시는 6x6x3 input image를 3x3x3 filter로 conv연산을 수행하면 4x4, 즉, 하나의 필터를 사용해서 결과는 2-dim으로 나타나는 것을 보여주고 있다. 만약 우리가 동시에 여러 filter를 사용하고 싶다면 어떻게 해야 할까?

만약 동시에 2가지 filter를 사용하기 원한다면, 위와 같이 각각의 filter(여기서는 vertical edge와 horizontal edge detector)에 대해서 conv연산을 수행하고, 결과 matrix를 쌓으면 된다. 따라서, 결과는 4x4x2의 matrix가 된다.

요약하자면, 다음과 같이 나타낼 수 있다.

여기서 nc는 input 이미지의 channel을 의미하고, nc′​는 filter의 수를 의미한다.

이렇게 filter의 수를 추가함으로써 다른 feature들을 동시에 감지할 수 있도록 해준다.

여기서 input의 마지막 dimension을 channel의 수라고 언급했는데, 종종 다른 문헌에서는 volume의 'depth'라고 부르기도 한다. channel과 depth, 모두 문헌들에서 흔하게 사용되는 표현이지만, Neural network의 depth를 말할 때도 동일하게 depth를 사용하므로 혼동이 될 수도 있어서, 강의에서는 세 번째 dimension을 channel이라는 용어로 지칭한다.

 

One Layer of a Convolutional Network

이제 CNN에서 하나의 layer를 어떻게 구성하는지 살펴보도록 하자.

이전 강의까지 우리는 input 이미지를 filter를 통해 conv연산을 수행했는데, 연산을 수행하고 bias를 추가한 후에 non-linear(ReLU)를 적용한다. 이 과정이 하나의 CNN layer가 된다.

우리가 잘 아는 공식으로 나타낸다면, 다음과 같이 나타낼 수 있을 것이다.

a[0]은 input x이고, filter들이 w[1]와 같은 역할을 하게 된다.

이 예제에서는 2개의 filter를 사용했기 때문에, output이 4x4x2로 나타나고, 만약 10개의 filter를 사용했다면, 4x4x10의 결과를 얻을 수 있다.

예제를 같이 풀어보면서 한 layer에서 파라미터의 개수가 어떻게 되는지 한번 살펴보도록 하자.

만약 CNN Layer에서 3x3x3의 filter 10개를 사용한다면, 이 layer에서 파라미터의 개수는 어떻게 될까?

하나의 filter를 먼저 살펴보면, 각 filter는 3x3x3=27 parameters와 1개의 bias가 존재하며, 따라서 하나의 filter에는 28개의 parameter가 존재한다.

따라서, 총 280개의 파라미터가 존재하게 된다.

여기서 CNN의 장점이 나타나는데, input 이미지의 크기가 아무리 크다고 하더라도 파라미터의 수는 280개로 항상 고정되어 있다. 따라서, 매우 큰 이미지가 있더라도 overfitting하지 않도록 할 수 있게 된다.

Notation 정리

- if layer l is a convolution layer

기본적인 notation은 위와 같고, 이제 input/output, filter의 크기가 어떻게 표시되는지 살펴보자.

m개의 example이 있다면, activation, weight, bias는 다음과 같이 나타낼 수 있다.

 

Simple Convolutional Network Example

 

Pooling layer 

일반적으로 합성곱 층(합성곱 연산 + 활성화 함수) 다음에는 풀링 층을 추가하는 것이 일반적입니다. 풀링 층에서는 특성 맵을 다운샘플링하여 특성 맵의 크기를 줄이는 풀링 연산이 이루어집니다. 풀링 연산에는 일반적으로 최대 풀링(max pooling)과 평균 풀링(average pooling)이 사용됩니다. 우선 최대 풀링을 통해서 풀링 연산을 이해해봅시다.

풀링 연산에서도 합성곱 연산과 마찬가지로 커널(=필터)과 스트라이드의 개념을 가집니다. 위의 그림은 스트라이드가 2일 때, 2 x 2 크기 커널로 맥스 풀링 연산을 했을 때 특성맵이 절반의 크기로 다운샘플링되는 것을 보여줍니다. 맥스 풀링은 커널과 겹치는 영역 안에서 최대값을 추출하는 방식으로 다운샘플링합니다.

다른 풀링 기법인 평균 풀링은 최대값을 추출하는 것이 아니라 평균값을 추출하는 연산이 됩니다. 풀링 연산은 커널과 스트라이드 개념이 존재한다는 점에서 합성곱 연산과 유사하지만, 합성곱 연산과의 차이점은 학습해야 할 가중치가 없으며 연산 후에 채널 수가 변하지 않는다는 점입니다.

pooling의 목적

 

1. input size를 줄임(Down Sampling).
: 텐서의 크기를 줄이는 역할을 한다.

2. overfitting을 조절
: input size가 줄어드는 것은 그만큼 쓸데없는 parameter의 수가 줄어드는 것이라고 생각할 수 있다. 훈련데이터에만 높은 성능을 보이는 과적합(overfitting)을 줄일 수 있다.

3. 특징을 잘 뽑아냄.
: pooling을 했을 때, 특정한 모양을 더 잘 인식할 수 있음.

4. 지역적 이동에 노이즈를 줌으로써 일반화 성능을 올려준다. maxpooling의 경우 주어진 픽셀중 큰것만 뽑기때문에 모양이 조금 달라지는 특성을 가지고 있다.

 

CNN example

Fully Connected Layer

CNN에서는 필터를 이용한 Convolution연산을 반복적으로 진행하면서 이미지의 특징을 검출하기 때문에 생각보다 구조가 간단합니다. 다음의 세 가지 layer를 기억하시면 됩니다.

1. Convolution layer : 특징 추출(feature extraction)

2. Pooling layer : 특징 추출(feature extraction)

3. Fully-connected layer : 분류(classificaiton)

Fully-Connected layer는 CNN 마지막에서 분류(Classification)를 결정하는 단계입니다.

1. flatten : 각 레이어를 1차원 벡터로 변환

2. fully-conneced layer : 1차원 벡터로 변환된 레이어를 하나의 벡터로 연결 (각 층의 노드들은 하나로 연결)

마지막으로 Softmax 함수를 이용해 가장 확률이 높은 class를 output으로 분류합니다.

+ Recent posts