딥러닝 / 풀링계층 구현하기
6 풀링계층 구현하기
convolution층이 이미지의 특징을 잡아내는 역할을 한다면 pooling층은 feature map 이미지를 선명하는 만드는 역할.
말 그대로 출력값에서 일부분만 취하는 기능.
convolution층이 이렇게 저렇게 헤집어 놓은 그림들을 가지고 feature map이미지의 각 부분에서 대표값들을 뽑아 사이즈가 작은 이미지를 만드는 것.
마치 사진을 축소하면 해상도가 좋아지는 듯한 효과와 비슷.
ㅇ풀링(pooling)의 종류 3가지
1.최대풀링 : 피처맵에서 가장 큰 값을 대표값으로 선택, 이미지를 선명하게 하는 효과
2.평균풀링 : 피처맵에서 평균값을 대표값으로 선택, 이미지를 부드럽게 하는 효과
3.확률적 풀링 : 피쳐맵에서 임의 확률로 한 개를 선택, 운좋게 이미지를 좀 잘 보이게 하는 효과
문제181. 파이썬으로 아래의 행렬을 만드시오.
a = np.array([21,8,8,12,12,19,9,7,8,10,4,3,18,12,9,10]).reshape(4,4)
a
문제182. 위의 입력데이터는 2차원인데 신경망 이미지의 사이즈에 맞도록 4차원으로 변경하시오.
a = np.array([21,8,8,12,12,19,9,7,8,10,4,3,18,12,9,10]).reshape(1,1,4,4) # 개수, 색조, 세로, 가로
a
문제183. 위의 4차원 이미지를 im2col를 이용해서 2차원으로 변경하시오.
result = im2col(a, 2, 2, 2, 0)
print(result)
# [[21. 8. 12. 19.]
# [ 8. 12. 9. 7.]
# [ 8. 10. 18. 12.]
# [ 4. 3. 9. 10.]]
문제184. 위의 결과에서 각 리스트의 최댓값을 출력하시오.
a = np.array([21,8,8,12,12,19,9,7,8,10,4,3,18,12,9,10]).reshape(1,1,4,4) # 개수, 색조, 세로, 가로
#im2col(입력이미지, 필터가로, 세로, 스트라이드 갯수, 패딩)
result = im2col(a, 2, 2, 2, 0)
print(result)
res_max = np.max(result, axis = 1)
print(res_max) #[21. 12. 18. 10.]
문제185. 위의 출력된 결과를 numpy의 reshape를 이용해서 2x2행렬로 변경하시오.
np.array(res_max).reshape(2,2)
maxpooling과정 정리
1. 4차원 형태의 입력 데이터 생성
2. 입력 데이터 x를 im2col함수로 2차원 변경
3. np.max의 axis = 1로 행에서의 최대값을 취함
4. 최대값만 취한 데이터를 다시 2x2형태로 reshape함
위에서는 흑백 사진에서의 maxpooling을 취한거고 컬러 형태일때 maxpooling을 할 수 있어야 함.
7 RGB채널일 때 maxpooling - p.248
1. 입력데이터 준비
x = np.array([[[21,8,8,12],[12,19,9,7],[8,10,4,3],[18,12,9,10]],
[[19,8,7,12],[1,19,9,7],[4,2,4,3],[4,12,9,10]],
[[2,8,8,12],[10,19,9,7],[5,6,4,3],[1,12,9,12]]])
x.shape #(3, 4, 4)
2. 입력데이터를 4차원으로 변경
x.ndim #3 <- 차원확인
x2 = x.reshape(1,3,4,4) #4차원으로 변경 (데이터 갯수, 채널, 높이, 가로)
x2
3. x2를 im2col함수로 2차원으로 변경함.
x_changed = im2col(x2, 2, 2, 2, 0)
x_changed
4개씩 끊어서 모양을 변경해야함.
x_re = x_changed.reshape(-1,4)
x_re
3. 행에서의 최대값을 취함
result = np.max(x_re, axis = 1) #array([21., 19., 19., 12., 12., 12., 18., 12., 12., 10., 10., 12.])
result
4. 위의 데이터를 다시 2x2 형태로 4차원 데이터로 reshape함
a = result.reshape(1,2,2,-1)
print(a.shape) #(1, 2, 2, 3)
5. N,H,W,C ---> N,C,H,W 형태로 transpose해줌.
(reshape는 차원을 변경하는 것, transpose는 순서를 바꿈)
a.transpose(0,3,1,2)
RGB채널의 이미지의 max pooling 순서
1. 4차원 입력데이터 준비
2. im2col함수를 이용해서 4차원 -> 2차원으로 변경
3. np.max를 이용해서 각 행에서 최대값 취함
4. 2x2형태의 4차원 행렬로 변환
5. N,H,W,C -> N,C,H,W로 transpose
문제186. 위의 5가지 순서로 구현한 pooling 클래스를 책 249페이지를 보면서 구현하시오.
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 #stride 값(보통 2)
self.pad = pad #패딩(보통0)
def forward(self, x):
N, C, H, W = x.shape #4차원 입력이미지 값을 받음
out_h = int(1+(H - self.pool_h) / self.stride)
out_w = int(1+(W - self.pool_w) / self.stride)
#전개
col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad) #im2col로 4차원 -> 2차원으로 변경
col = col.reshape(-1, self.pool_h*self.pool_w) #열이 4개이기만 하면 행은 알아서 계산
#최대값
out = np.max(col, axis = 1) # 각각의 행에서 max값
#성형
out = out.reshape(N, out_h, out_w, C).transpose(0,3,1,2) #4차원으로 변경하고 transpose함
return out
문제187. 위에서 생성한 설계도 pooling 클래스를 객체화해서 아래의 입력데이터를 넣고 maxpooling을 하여 결과를 출력하시오.
x = np.array([[[21,8,8,12],[12,19,9,7],[8,10,4,3],[18,12,9,10]],
[[19,8,7,12],[1,19,9,7],[4,2,4,3],[4,12,9,10]],
[[2,8,8,12],[10,19,9,7],[5,6,4,3],[1,12,9,12]]])
x2 = x.reshape(1,3,4,4)
pooling = Pooling(2,2,2,0)
pooling.forward(x2)
문제188. 위의 pooling클래스를 최대 풀링이 아니라 평균 풀링이 되도록 수정하고 문제 187번을 다시 수행해서 결과를 출력하시오.
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)
#전개
col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad)
col = col.reshape(-1, self.pool_h*self.pool_w)
#최대값
out = np.mean(col, axis = 1) #평균값으로 출력
#성형
out = out.reshape(N, out_h, out_w, C).transpose(0,3,1,2)
return out
x = np.array([[[21,8,8,12],[12,19,9,7],[8,10,4,3],[18,12,9,10]],
[[19,8,7,12],[1,19,9,7],[4,2,4,3],[4,12,9,10]],
[[2,8,8,12],[10,19,9,7],[5,6,4,3],[1,12,9,12]]])
x2 = x.reshape(1,3,4,4)
pooling = Pooling(2,2,2,0)
pooling.forward(x2)