Study/class note

딥러닝 / 풀링계층 구현하기

chanzae 2022. 4. 18. 15:22

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)

 

 

 

반응형