수학/딥러닝 이론

[딥러닝] 합성곱 신경망(CNN) - 합성곱 계층 구현하기

AI 꿈나무 2020. 10. 5. 20:29
반응형

사이토고키의 <밑바닥부터 시작하는 딥러닝>을 공부하고 정리해보았습니다.

 


 

 

[딥러닝] 합성곱신경망(CNN) - im2col로 데이터 전개하기

사이토고키의 <밑바닥부터 시작하는 딥러닝>을 공부하고 정리해보았습니다. 을 공부하고 정리해보았습니다. 을 공부하고 정리해보았습니다. 을 공부하고 정리해보았습니다. 을 공부하고 정리��

deep-learning-study.tistory.com

 이전 포스팅에서 합성곱 연산을 할 때 im2col로 데이터를 전개하는 방법에 대해 알아보았습니다.

 이번에는 im2col을 적용한 합성곱 계층을 구현해보겠습니다.

 

합성곱 계층 구현하기

 이 책에서는 im2col 함수를 미리 만들어 제공합니다.

 im2col 함수는 '필터 크기', '스트라이드'. '패딩'을 고려하여 입력 데이터를 2차원 배열로 전개합니다.

 

 im2col을 실제로 적용해보겠습니다.

 

x1 = np.random.rand(1, 3, 7, 7) # 데이터 수, 채널 수, 높이, 너비
col1 = im2col(x1, 5, 5, stride=1, pad=0)
print(col1.shape) # (9, 75)

x2 = np.random.rand(10, 3, 7, 7) # 데이터 10개
col2 = im2col(x2, 5, 5, stride=1, pad=0)
print(col2.shape) # (90, 75)

 

 여기에서는 두 가지 예를 보여주고 있습니다.

 첫 번째는 배치 크기가 1(데이터 1개), 채널은 3개, 높이 너비가 7 X 7의 데이터이고,

 두 번째는 배치 크기만 10이고 나머지는 첫 번째와 같습니다.

 

 im2col 함수를 적용한 두 경우 모두 2번째 차원의 원소는 75개입니다.

 이 값은 필터의 원소 수와 동일합니다.(채널 3개, 5 X 5 데이터)

 또한, 배치 크기가 1일 때는 im2col의 결과의 크기가 (9, 75)이고,

 10일 때는 그 10배이 (90, 75) 크기의 데이터가 저장됩니다.

 

 이제 이 im2col을 사용하여 합성곱 계층을 구현해보겠습니다.

 여기에서는 합성곱 계층을 Convolution이라는 클래스로 구현하겠습니다.

 

class Convolution:
    def __init__(self, W, b, stride=1, pad=0):
        self.W = W
        self.b = b
        self.stride = stride
        self.pad = 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.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)
        
        return out

 

 합성곱 계층은 필터(가중치), 편향, 스트라이드, 패딩을 인수로 받아 초기화합니다.

 필터는 (FN, C, FH, FW)의 4차원 형상입니다.

 여기서 FN은 필터 개수, C는 채널, FH는 필터 높이, FW는 필터 너비입니다.

 

 입력 데이터를 im2col로 전개하고 필터도 reshape을 사용해 2차원 배열로 전개합니다.

 그리고 이렇게 전개한 두 행렬의 곱을 구합니다.

 

 필터를 전개하는 부분은 각 필터 블록을 1줄로 펼쳐 세웁니다.

 이때 reshape의 두 번째 인수를 -1로 지정했는데, 이는 reshape이 제공하는 편의 기능입니다.

 reshape에 -1을 지정하면 다차원 배열의 원소 수가 변화 후에도 똑같이 유지되도록 적절히 묶어줍니다.

 

 foward 구현의 마지막에서는 출력 데이터를 적절한 형상으로 바꿔줍니다.

 이때 넘파이의 transpose 함수를 사용하는데, 이는 다차원 배열의 축 순서를 바꿔주는 함수입니다.

 아래 그림과 같이 인덱스를 지정하여 축의 순서를 변경합니다.

 

 im2col로 전개한 덕분에 완전연결 계층의 Affine 계층과 거의 똑같이 구현할 수 있었습니다.

 

 합성곱 계층의 역전파를 구현할 때는 im2col을 역으로 처리해야 합니다.

 col2im 함수를 이용하면 됩니다.

 col2im을 사용한다는 점을 제외하면 합성곱 계층의 역전파는 Affine 계층과 똑같습니다.

 

반응형