[밑시딥] 7. CNN (합성곱 신경망)

PurinYun·2023년 12월 13일
0

AIffel

목록 보기
52/75

1. 전체 구조

Affine계층 : 완전히 연결된 계층
CNN에서는 새로운 합성곱 계층풀링 계층이 추가

합성곱 계층(Convolutional Layer)과 풀링 계층(Pooling Layer)은
합성곱 신경망(Convolutional Neural Network, CNN)에서 주로 사용되는 두 가지 유형의 계층입니다.

공통점:

특징 추출:
둘 다 입력 데이터로부터 특징을 추출하는 역할을 합니다.

파라미터 공유:
두 계층 모두 학습 가능한 파라미터를 공유하여 모델의 학습 파라미터 수를 줄이고, 데이터의 특징을 인코딩합니다.

차이점:

역할:
합성곱 계층: 입력 이미지에서 특징을 감지하고 추출합니다. 필터(커널)를 사용하여 입력과의 합성곱을 수행합니다.

풀링 계층: 공간적인 차원을 줄이거나 특정 특징을 강화하기 위해 출력 데이터를 다운샘플링합니다. 최대 풀링(Max Pooling)과 평균 풀링(Average Pooling) 등이 사용됩니다.

연산 방식:

합성곱 계층: 합성곱 연산을 통해 입력과 필터 간의 요소별 곱과 합을 계산하여 특징 맵을 생성합니다.

풀링 계층: 주로 최대 풀링(Max Pooling)이 사용되며, 주어진 영역에서 가장 큰 값을 선택하여 다운샘플링합니다. 다른 방식의 풀링도 있지만, 일반적으로는 최대 풀링이 많이 사용됩니다.

출력 크기:

합성곱 계층: 입력과 필터 크기, 스트라이드에 따라 출력의 크기가 달라집니다.

풀링 계층: 출력 크기는 일반적으로 입력의 크기를 줄이기 위해 다운샘플링됩니다.
이러한 계층들은 CNN에서 이미지 처리를 위해 함께 사용되며, 합성곱 계층은 특징 추출을 담당하고, 풀링 계층은 특징 맵의 크기를 줄이거나 강화하여 계산량을 줄이고 중요한 정보를 유지합니다.

Affine-ReLU 연결이 Conv-ReLU-(Pooling) 으로 변경

마지막 출력 계층에서는 "Affine-Softmax" 조합 그대로 사용

2. 합성곱 계층

CNN에서는 패딩, 스트라이드 등 CNN 고유의 용어가 등장한다.

패딩을 크게 하면 출력 크기는 커진다.
스트라이드를 크게 하면 출력 크기는 작아진다.

그리고 각 계층 사이에 3차원 데이터같이 입체적인 데이터가 흐른다는 점에서
완전연결 신경망과 다르다.

2-1. 완전연결 계층의 문제점

완전연결 계층 (Affine 계층) 에서는
인접하는 계층의 뉴런이 모두 연결되고
출력의 수는 임의로 정할 수 있다.

하지만, 완전연결계층은 데이터의 형상이 무시된다는 문제점이 있다.

예를 들면, 이미지는 3차원 데이터(가로, 세로, 색상)이지만
완전연결계층에 입력할 때는 1차원 데이터로 바꿔줘야 한다.
그렇기 때문에 형상에 담긴 정보를 살릴 수 없다.

하지만, 합성곱 계층은 형상을 유지한다.
이미지도 3차원 데이터로 입력받아서 형상을 가진 데이터로 제대로 이해할 수 있다.

CNN에서는 합성곱 계층의 입출력 데이터를 특징맵이라 하고,
입력 데이터를 입력 특징 맵, 출력 데이터를 출력 특징 맵이라고 한다.

2-2. 합성곱 연산

합성곱 연산은 이미지 처리에서 말하는 필터 연산이다. 입력 데이터에 필터를 적용한다.

필터의 윈도우를 일정 간격으로 이동해 가면서 입력 데이터에 적용한다.
윈도우는 회색 부분을 말한다.
입력과 필터에 대응하는 원소끼리 곱한 후에 그 총합을 구한다.

CNN에서 SMS 필터의 매개변수가 가중치에 해당하고 편향(고정값) 또한 존재할 수 있다
필터를 적용한 후에 편향을 더한다.
편향은 항상 하나만 존재한다.
그 하나의 값을 필터를 적용한 모든 원소에 더한다.

2-3. 패딩 (padding)

: 주로 합성곱 연산을 수행하기 전에
입력 데이터 주변을 0과 같은 특정 값으로 채우기도 하는 것
패딩은 주로 출력 크기를 조정할 목적으로 사용한다.

이 그림을 보면 패딩이 추가되어서 입력 데이터가 (6,6)이 된다. 이 입력에 (3,3) 필터를 걸면 (4,4) 출력 데이터가 만들어 진다.

만약 패딩을 하지 않았다면

(4,4) 입력데이터에 (3,3) 필터를 적용하여 (2,2)라는 출력을 받는다.
이는 합성곱 연산을 되풀이하는 심층 신경망에서 어느순간 출력 크기가 1이 되어버리는 문제가 생길 수 있다.
(더 이상 합성곱 연산 진행이 어렵다는 뜻)
이러한 사태를 막기 위해 패딩을 사용한다.

2-4. 스트라이드 (stride)

: 필터를 적용하는 위치의 간격
위의 예는 모두 스트라이드가 1이었지만, 스트라이드를 2로 하면 윈도우가 두 칸씩 이동한다.

스트라이드를 키우면 출력 크기는 작아지고 패딩을 크게 하면 출력 크기가 커진다.
이를 수식화 하면, 다음과 같다.

입력 크기를 (H,W), 필터 크기를 (FH, FW), 출력 크기를 (OG, OW), 패딩을 P, 스트라이드를 S라고 하면 출력의 크기는

OH=(H+2P-FH)/S+1

OW=(W+2P-FW)/S+1

출력 크기가 정수가 아니면 오류.
딥러닝 프레임워크 중에는 값이 딱 나눠떨어지지 않을 때는 가장 가까운 정수로 반올림하여
에러내지 않는 방법 구현도 가능하다.

2-5. 3차원 데이터의 합성곱 연산

입력 데이터와 필터의 합성곱 연산을 채널마다 수행하고 그 결과를 더해서 하나의 출력을 얻는다.

이 때 주의할 점은 입력 데이터의 채널수와 필터의 채널수가 같아야 한다는 것이다.
이 예에서는 3개로 같다.

2-6. 블록으로 생각하기

3차원 합성곱 연산을 직육면체 블록이라고 생각하면 쉽다.

필터를 FN개 적용하면 출력 맵도 FN개 생성
이렇게 합성곱 연산에서는 필터의 수도 고려해야 함
그런 이유로 필터의 가중치 데이터는 4차원 데이터이며
(출력채널수, 입력채널수, 높이, 너비) 순으로 쓴다.

2-7. 배치 처리

신경망 처리에서는 입력 데이터를 한 덩어리로 묶어 배치로 처리했다.

합성곱 연상에서는 각 계층을 흐르는 데이터의 차원을 하나 늘려
(데이터 수, 채널수, 높이, 너비) 4차원 데이터로 저장한다.
데이터는 4차원 형상을 가진 채 각 계층을 타고 흐른다.
4차원 데이터가 하나 흐를 때마다 데이터 n개에 대한 합성곱 연산이 이뤄진다.
즉, N회분의 처리를 한번에 수행한다.

3. 풀링 계층

풀링은 세로, 가로 방향의 공간을 줄이는 연산이다.
최대 풀링은 대상 영역 중에서 최댓값을 구하는 것이다.
설정한 스트라이드의 크기 대로 윈도우를 설정하고 그 간격으로 이동한다.

이 그림을 보면 2x2 최대 풀링을 스트라이드 2로 처리하는 것이다.
2x2 크기의 영역에서 가장 큰 원소 하나를 꺼내고 스트라이드 2로 설정했으므로
2x2 윈도우가 2칸 간격으로 이동한다.

3-1. 풀링 계층의 특징

1. 학습해야 할 매개변수가 없다.
풀링은 대상 영역에서 최댓값이나 평균을 취하는 명확한 처리이므로 학습할 것이 없다.

2. 채널수가 변하지 않는다.
폴링 연산은 입력 데이터의 채널 수 그대로 출력 데이터로 내보낸다.

3. 입력의 변화에 영향을 적게 받는다.

4. 합성곱/풀링 계층 구현하기

4-1. 4차원 배열

데이터 형상이 높이 28, 너비 28, 채널 1개, 데이터 10개를 구현
(10, 1, 28, 28)

4-2. im2col로 데이터 전개

넘파이에 for 문을 사용하면 성능이 떨어지기 때문에 im2col이라는 편의 함수를 이용해본다.
im2col은 입력 데이터를 필터링하기 좋게 전개하는 함수이다.

im2col을 사용하면 원소의 수가 원래 블록의 원소 수보다 많아 져서 메모리를 많이 소비한다.
하지만 컴퓨터는 큰 행렬의 곱셈을 빠르게 계산할 수 있기 때문에 im2col을 이용한다.
im2col로 데이터를 전개한 다음에는
합성곱 게층의 필터(가중치)를 1열로 전개하고
두 행렬의 내적을 계산하면 된다.
이렇게 출력한 결과는 2차원 행렬이다.
CNN은 4차원 배열 데이터로 저장하기 때문에 reshape을 이용해서 4차원으로 변형한다.

4-3. 합성곱 계층 구현

im2col 함수를 구현해보면

def im2col(input_data, filter_h, filter_w, stride=1, pad=0):
    """다수의 이미지를 입력받아 2차원 배열로 변환한다(평탄화).
    
    Parameters
    ----------
    input_data : 4차원 배열 형태의 입력 데이터(이미지 수, 채널 수, 높이, 너비)
    filter_h : 필터의 높이
    filter_w : 필터의 너비
    stride : 스트라이드
    pad : 패딩
    
    Returns
    -------
    col : 2차원 배열
    """
    N, C, H, W = input_data.shape
    out_h = (H + 2*pad - filter_h)//stride + 1
    out_w = (W + 2*pad - filter_w)//stride + 1

    img = np.pad(input_data, [(0,0), (0,0), (pad, pad), (pad, pad)], 'constant')
    col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))

    for y in range(filter_h):
        y_max = y + stride*out_h
        for x in range(filter_w):
            x_max = x + stride*out_w
            col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]

    col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1)
    return col

합성곱 계층을 구현한 것

class Convolution:
    def __inti__(self, w, b, stride=1, pad=0):
        self.w=w
        self.b=b
        self.stride=stride
        self.pad
    
    def forward(self, x):
        fn, c, fh, fw=self.w.shape
        n,c,h,w=x.shape
        out_h=int(1+(h+2*self.pad-fh)/self.stride)
        out_w=int(1+(w+2*self.pad-fw)/self.stride)
        
        col=im2col(x, fh, fw, self.stride, self.pad)
        col_w=self.w.reshape(fn, -1).T
        out=np.dot(col,col_w)+self.b
        
        out=out.reshpae(n, out_h, out_w, -1).transpose(0,3,1,2)
        
        return out

필터는 (FN, C, FH, FW)의 4차원 형상이다. FN은 필터 개수, C는 채널, FH는 필터 높이, FW는 필터 너비이다.
col=im2col(x, fh, fw, self.stride, self.pad))

    col_w=self.w.reshape(fn, -1).T

    out=np.dot(col,col_w)+self.b

이 부분에서 입력 데이터를 im2col로 전개하고
필터도 reshape를 사용해 2차원 배열로 전개한다.
이렇게 전개한 두 행렬의 내적을 구한다.
각 필터 블록을 1줄로 펼쳐 세우고 reshpae에 -1을 지정해서
다차원 배열의 원소 수가 변환 후에도 똑같이 유지되도록 적절히 묶어준다.

지막 출력 데이터를 적절한 형상으로 바꿔주는 것이 forward 구현의 마지막이다.

4-4. 풀링 계층 구현

채널이 독립적이라는 점이 합성곱 계층 때와는 다르다.

위와 같이 전개한 후 행별 최댓값을 구한후에 적절한 형상으로 성형한다.

풀링 계층 구현의 세단계

(1) 입력 데이터를 전개한다.
(2) 행별 최댓값을 구한다.
(3) 적절한 모양으로 성형한다.

5. CNN구현

CNN 네트워크는 Convolution-ReLU-Pooling-Affine-ReLU-Affine-Softmax 순으로 흐른다.

6. CNN 시각화

6-1. 1번째 층의 가중치 시각화하기

학습 전 필터는 무작위로 초기화되고 있어 흑백의 정도에 규칙성이 없다.
학습을 마친 필터는 규칙이 있는 이미지가 되었다.

흰색에서 검은색으로 변화하고 덩어리를 가지기도 하는 규칙을 나타낸다.
규칙성이 있는 필터는 색상이 바뀐 경계선인 에지와 덩어리진 영역인 블롭을 보고 있다.
이렇게 합성곱 계층의 필터는 에지나 블롭 등 원시적인 정보를 추출할 수 있다.
이런 원시적인 정보가 뒷단 계층에 전달되는 것이 CNN에서 일어나는 일이다.

6-2. 층 깊이에 따른 추출 정보 변화

계층이 깊어질수록 추출되는 정보는 더 추상화된다.

위의 그림은 일반 사물 인식을 수행한 8층의 CNN이다.
이 네트워크는 AlexNet이라고 한다. 합성곱 계층과 풀링 계층을 여러 겹 쌓고,
마지막으로 완전연결 계층을 거쳐 결과를 출력한다.
1층은 에지와 블롭, 3층은 텍스쳐, 5층은 사물의 일부, 마지막은 사물의 클래스에 뉴런이 반응한다.

층이 깊어질수록 뉴런이 고급 정보에 반응한다. 즉, 사물의 의미를 이해하도록 변화한다.

7. 대표적인 CNN

7-1. LeNet

: 손글씨 숫자를 인식하는 네트워크
합성곱 계층과 풀링 계층을 반복하고
마지막으로 완전연결 계층을 거치면서 결과를 출력한다.

LeNet과 현재의 CNN과의 차이점

LeNex는 시그모이드 함수를 사용하고 현재는 ReLU를 사용한다.
LeNex는 서브샘플링을 하여 중간데이터 크기가 작아지지만 현재는 최대 풀링이 주류다.

7-2. AlexNet

합성곱 계층과 풀링 계층을 거듭하며 마지막으로 완전연결 계층을 사용하지만, 다음과 같은 변화가 있다

활성화 함수로 ReLU를 이용한다

LRN이라는 국소적 정규화를 실시하는 계층을 이용한다.

드롭아웃을 사용한다.

profile
Fantivation

0개의 댓글