728x90
반응형

4차원 배열

  • CNN에서 계층 사이를 흐르는 데이터는 4차원이다.
    • 예 : 데이터의 형상이 (10,1,28,28)이라면 높이(28), 너비(28), 채널(1)개인 데이터가 10개라는 뜻이다.
# 7.4 4차원 배열
import numpy as np


x = np.random.rand(10, 1, 28, 28) # 무작위로 데이터 생성
x.shape

[그림1] 4차원 배열 예제

 

  • (10개 중) 첫 번째 데이터 접근 시 x[0]이라고 쓴다.
print(x[0].shape) # 1. 28. 28
print(x[1].shape) # 1. 28. 28

[그림2] 인덱스 확인

  • 첫 번째 데이터의 첫 채널의 공간 데이터 접근
print(x[0, 0]) # 또는x[0][0]

 

 

im2col 데이터 전개

  • 합성곱 연산 for문 사용시 매우 복잡해진다. 
  • for문 대신 im2col이라는 편의 함수 사용해 간단하게 구현
    • im2col은 입력 데이터를 필터링(가중치 계산)하기 좋게 전개하는(펼치는) 함수다.
    • 3차원 입력 데이터에 im2col을 적용시 2차원 행렬로 바뀐다. (배치 안의 데이터 수까지 포함한 4차원 데이터를 2차원으로 변환한다.)

 

(대략적) im2col 동작

[그림3] 대략적인 im2col동작

  • im2col은 필터링하기 좋게 입력 데이터를 전개한다
  • 필터를 적용하는 모든 영역에서 수행하는 것이 im2col

 

필터 적용 영역을 앞에서부터 순서대로 1줄로 펼친다.

[그림4] 필터 적용 영역을 앞에서부터 순서대로 1줄로 펼친다.

  • 실제 상황에서는 영역이 겹치는 경우가 대부분
  • 필터 적용 영역이 겹치게 되면 im2col로 전개한 후의 원소 수가 원래 블록의 원소 수보다 많아진다.
  • im2col을 사용해 구현하면 메모리를 더 많이 소비하는 단점이 있다.
  • 대신 컴퓨터는 큰 행렬을 묶어서 계산하는 데 탁월하다.
    • 행렬 계산 라이브러리(선형 대수 라이브러리) 등은 행렬 계산에 고도로 최적화되어 큰 행렬의 곱셈을 빠르게 계산할 수 있다.

im2col

  • image to column - 이미지에서 행렬로라는 뜻 
  • 카페(Caffe)와 체이너(Chainer)등의 딥러닝 프레임워크는 im2col이라는 이름의 함수를 만들어 합성곱 계층을 구현할 때 이용하고 있다.

합성곱 연산의 필터 처리 상세 과정

  • 필터를 세로로 1열로 전개하고 im2col이 전개한 데이터와 행렬 곱을 계산한다.
  • 마지막으로 출력 데이터 변형(reshape)한다.

[그림5] 합성곱 연산의 필터 처리 상세 과정

 

합성곱 계층 구현

# 7_4_3 합성곱 계층 구현하기
import numpy as np
import sys, os
sys.path.append(os.pardir)
from util import im2col

x1 = np.random.rand(1,3,7,7) # (데이터 수, 채널 수 , 높이, 너비)
col1 = im2col(x1, 5, 5, stride=1, pad=0) # 스트라이드 1
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

 

[그림6] 합성곱 계층 구현 결과

 

 

im2col 함수 인터페이스

  • im2col(input_data, filter_h, filter_w, stride = 1, pad=0)
    • input_data - (데이터 수, 채널 수 , 높이, 너비)의 4차원 배열로 이뤄진 입력 데이터
    • filter_h - 필터의 높이
    • filter_w - 필터의 너비
    • stride - 스트라이드
    • pad - 패딩
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-PW)/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는 필터 너비
  • transpose함수는 다차원 배열의 축 순서를 바꿔주는 함수다.

 

넘파이의 transpose 함수로 축 순서 변경 : 인덱스(번호)로 축의 순서 변경

[그림7] 넘파이 transpose 함수로 축 순서 변경

 

 

풀링 계층 구현

  • 채널 쪽이 독립적이라는 것이 합성곱 계층과 다르다.

입력 데이터에 풀링 적용 영역을 전개 (2x2 풀링 예)

[그림8] 풀링 계층 구현

  • 전개 후 전개한 행렬에서 최댓값을 구하고 적절한 형상으로 성형하기만 하면 된다.

풀링 계층 구현의 흐름 : 풀링 적용 영역에서 가장 큰 원소는 회색으로 표시

[그림9] 풀링 계층 흐름 구현

class Pooling:
    def __init__(self, pool_h, pool_w, stride=1, pad =0):
        self.pool_h = pool_h
        self.pool_w = pool_w
        self.stride = stride
        self.pad = pad
        
    def forward(self, x):
        N, C, H, W = x.shape
        out_h = int(1+(H-self.pool_h)/self.stride)
        out_w = int(1+(W-self.pool_w)/self.stride)
        
        # 전개(1)
        col = im2col(x, self.pool_h, self.pool_w, stride, self.pad)
        col = col.reshape(-1, self.pool_h * self.pool_w)
        
        # 최댓값(2)
        out = np.max(col, axis=1) # 가로 전개
        
        # 성형(3)
        out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2)
        
        return out
    

 

풀링 계층은 세 단계로 진행

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

최댓값은 np.max로 구할 수 있다. np.max(x,axis = 1)은 입력 x의 1번째 차원의 축마다 최댓값을 구한다.

 

 

출처 : 밑바닥부터 시작하는 딥러닝

https://www.hanbit.co.kr/store/books/look.php?p_code=B8475831198

 

밑바닥부터 시작하는 딥러닝

직접 구현하고 움직여보며 익히는 가장 쉬운 딥러닝 입문서

www.hanbit.co.kr

 

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기