본문 바로가기

implement_ml_models/CNN

implement_CNN(CNN_backpropagation)

 

2023.03.12 - [분류 전체보기] - implement_CNN(MLP_weight_update)

 

implement_CNN(MLP_weight_update)

2023.03.12 - [분류 전체보기] - implement_CNN(back_propagation) implement_CNN(back_propagation) 2023.03.10 - [분류 전체보기] - implement_CNN(MLP) implement_CNN(MLP) 2023.03.09 - [분류 전체보기] - implement_CNN(MLP 전 까지) implement_CNN

teach-meaning.tistory.com

cnn 의 MLP 층의 back_propagation 계산과 이를 통해 얻은 delta 값을 통한 weight update 를 수행했다. 

해당 delta 값에는 flatten 층의 노드들에 대한 비용 함수의 변화량 또한 포함

해당 값을 통해 cnn 의 back propagation 연산을 수행할 수 있다.

flatten 후 4096 개의 노드들에 대한 MLP 연산 수행, 해당 노드들에 대한 delta 값도 계산할 수 있었다.

해당 delta 값에 연결된 가중치는 필터에 해당하는 가중치와 연결된다.

먼저 이는 max_pooling 층에 연결되어 있다. 이에 대한 역전파 계산의 수행은 최댓값을 내놓는 입력층 유닛 i 에만 가중치를 1로 설정하고 그 외의 유닛은 0으로 설정한다. 

즉, 샘플마다 순전파 계산 시점의 풀링 결과에 의해 가중치가 변화한다. 

역전파 계산에서는 최댓값을 내놓는 유닛의 델타가 그대로 전달된다.

 

마지막에서 (3,3) 크기의 커널, 256개 에서 (2,2) 크기의 max_pooling 을 수행했다. 풀링 수행 결과로 (2,2) 크기의 커널 256 개가 생성된다.

따라서 역전파 과정에서는 (2,2) 크기의 각 커널 값, 여기선 가장 큰 값에만 대해서 수행되는 가중치에 대해서만 업데이트가 수행될 것, 

각 층별 출력 필터의 크기 확인

for i in range(len(cnn.layer_result)):
  print(cnn.layer_result[i][0].shape)
  
>>>
(28, 28)
(14, 14)
(14, 14)
(7, 7)
(7, 7)
(4, 4)
(1,)
(1,)
(1,)
(1,)

1 : (7,7) 합성곱, same_padding 결과 (64, 28,28)

2 : (2,2) 풀링 결과 (64, 14,14)

3 : (3,3) 합성곱, same_padding 결과 (128, 14,14)

4 : (2,2) 풀링 결과 (128, 7,7)

5 : (3,3) 합성곱, same_padding 결과 (256, 7,7)

6 : (2,2) 풀링 결과 (256, 4,4)

7 ~ 10 : flatten, MLP 연산

 

7 ~ 10 까지의 delta 값은 계산,

6 에서의 결과를 통해 4 - 5에서 업데이트할 가중치를 선택 및 기울기 업데이트 가능,

(2,2) 커널에서 업데이트할 가중치의 위치는 출력 데이터와 동일한 값(max_pooling) 을 통해 선택할 수 있다.

- 풀링층 결과를 가져온다.

- 풀링층 결과와 동일한 입력 데이터의 위치 저장, 해당위치에 해당하는 가중치의 업데이트 크기 계산가능

 

5 의 단계에서 사용된 (3,3) 크기의 가중치 256 개에 대한 기울기 업데이트가 필요, 6에서의 (4,4) 풀링 결과를 통해 5 에서의 (7,7) 크기의 합성곱 연산 결과에서 (4,4) 16개의 풀링 결과에 해당하는(동일한) 값을 찾고, 해당 값과 연결되는(해당 값을 만들어낸) 합성곱 필터의 가중치 업데이트를 수행할 수 있다.

# 풀링 결과와 매칭되는 입력값을 찾고, 해당 입력값과 연결되는 가중치에 대한 업데이트를 수행하기 위한 함수
  def matching_pooling_result(self, input, result, w, pooling_size):
    """
    input : pooling 수행 전 입력 데이터
    result : pooling 수행 후의 데이터
    w : pooling 수행 전 입력 데이터의 결과를 만들어낸 결과 w
    pooling_size
    """
    self.pool_result = []
    
    pooling_matrix = self.pad.padding(input, input.shape[0] % pooling_size)

    position_arr = []
    
    # 전체 데이터에 대한 반복 (스트라이드 1)
    for col in range(0, pooling_matrix.shape[0], pooling_size):
      for row in range(0, pooling_matrix.shape[1], pooling_size):
        # 풀링 연산 수행사이즈
        for pooling_col in range(pooling_size):
          for pooling_row in range(pooling_size):        
            # 풀링 결과와 동일한 값을 찾는다. 그 위치의 탐색
            if(pooling_matrix[pooling_col + col, pooling_row + row] == result[pooling_col, pooling_row]):
              data_position = [pooling_col + col, pooling_row + row]
        
        position_arr.append(data_position)

    return position_arr

position_arr 에 수행 전 입력 데이터에 대한 위치가 position_arr 에 저장된다.

 

'implement_ml_models > CNN' 카테고리의 다른 글

implement_CNN(CNN_backpropagation_cnn)  (0) 2023.03.16
implement_CNN(CNN_backpropagation_pooing)  (0) 2023.03.15
implement_CNN(MLP_weight_update)  (0) 2023.03.12
implement_CNN(back_propagation)  (0) 2023.03.12
implement_CNN(MLP)  (0) 2023.03.10