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
- (10개 중) 첫 번째 데이터 접근 시 x[0]이라고 쓴다.
print(x[0].shape) # 1. 28. 28
print(x[1].shape) # 1. 28. 28
- 첫 번째 데이터의 첫 채널의 공간 데이터 접근
print(x[0, 0]) # 또는x[0][0]
im2col 데이터 전개
- 합성곱 연산 for문 사용시 매우 복잡해진다.
- for문 대신 im2col이라는 편의 함수 사용해 간단하게 구현
- im2col은 입력 데이터를 필터링(가중치 계산)하기 좋게 전개하는(펼치는) 함수다.
- 3차원 입력 데이터에 im2col을 적용시 2차원 행렬로 바뀐다. (배치 안의 데이터 수까지 포함한 4차원 데이터를 2차원으로 변환한다.)
(대략적) im2col 동작
- im2col은 필터링하기 좋게 입력 데이터를 전개한다
- 필터를 적용하는 모든 영역에서 수행하는 것이 im2col
필터 적용 영역을 앞에서부터 순서대로 1줄로 펼친다.
- 실제 상황에서는 영역이 겹치는 경우가 대부분
- 필터 적용 영역이 겹치게 되면 im2col로 전개한 후의 원소 수가 원래 블록의 원소 수보다 많아진다.
- im2col을 사용해 구현하면 메모리를 더 많이 소비하는 단점이 있다.
- 대신 컴퓨터는 큰 행렬을 묶어서 계산하는 데 탁월하다.
- 행렬 계산 라이브러리(선형 대수 라이브러리) 등은 행렬 계산에 고도로 최적화되어 큰 행렬의 곱셈을 빠르게 계산할 수 있다.
im2col
- image to column - 이미지에서 행렬로라는 뜻
- 카페(Caffe)와 체이너(Chainer)등의 딥러닝 프레임워크는 im2col이라는 이름의 함수를 만들어 합성곱 계층을 구현할 때 이용하고 있다.
합성곱 연산의 필터 처리 상세 과정
- 필터를 세로로 1열로 전개하고 im2col이 전개한 데이터와 행렬 곱을 계산한다.
- 마지막으로 출력 데이터 변형(reshape)한다.
합성곱 계층 구현
# 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
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 함수로 축 순서 변경 : 인덱스(번호)로 축의 순서 변경
풀링 계층 구현
- 채널 쪽이 독립적이라는 것이 합성곱 계층과 다르다.
입력 데이터에 풀링 적용 영역을 전개 (2x2 풀링 예)
- 전개 후 전개한 행렬에서 최댓값을 구하고 적절한 형상으로 성형하기만 하면 된다.
풀링 계층 구현의 흐름 : 풀링 적용 영역에서 가장 큰 원소는 회색으로 표시
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
풀링 계층은 세 단계로 진행
- 입력 데이터를 전개한다.
- 행별 최댓값을 구한다.
- 적절한 모양으로 성형한다.
최댓값은 np.max로 구할 수 있다. np.max(x,axis = 1)은 입력 x의 1번째 차원의 축마다 최댓값을 구한다.
출처 : 밑바닥부터 시작하는 딥러닝
https://www.hanbit.co.kr/store/books/look.php?p_code=B8475831198
728x90
반응형
최근댓글