본문 바로가기

implement_ml_models/CNN

implement_CNN(same_padding)

 
 
2023.03.07 - [분류 전체보기] - implement_CNN(pooling)

implement_CNN(pooling)

2023.03.07 - [분류 전체보기] - implement_CNN(start) implement_CNN(start) 시각 피질 안의 뉴런들이 작은 국부 수용장을 가진다. 이는 뉴런들이 시야의 일부 버위 안에 있는 시각 자극에만 반응한다는 뜻이다.

teach-meaning.tistory.com

입력 데이터와 동일한 크기의 합성곱을 수행하는 same_padding 구현

  def same_padding_cnn(self, input, filter_size, filter_count):
    # 입력 받은 필터의 개수만큼 반복
    for i in range(filter_count):

      # 필터 크기에 맞는 임의의 가중치 생성
      weight = np.random.random(filter_size * filter_size).reshape(filter_size, filter_size)
      
      self.cnn_weight.append(weight)
      
      # 합성곱 연산 결과가 저장된다.
      result_arr = []

      for col in range(input.shape[0] - weight.shape[0] + 1):
        for row in range(input.shape[1] - weight.shape[1] + 1):
          result = []
          for w_col in range(weight.shape[0]):
            for w_row in range(weight.shape[1]):
              result.append(input[col + w_col, row + w_row ] * weight[w_col, w_row])
          result_arr.append(np.sum(result))

      # 연산 결과를 크기에 맞게 바꿔준다.
      result_arr = np.array(result_arr).reshape(input.shape[0] - weight.shape[0] + 1, -1)

      print(input.shape[0] - result_arr.shape[0])

      result_arr = self.pad.padding(result_arr, input.shape[0] - result_arr.shape[0])
      
      # 연산 결과의 저장
      self.cnn_result.append(result_arr)

기존과 동일한 합성곱 연산과 입력 데이터 크기와 연산 결과 크기의 차, 패딩 크기를 계산하여 패딩을 수행한다.

class PADDING:

  def padding(self, input, padding_size):
    """
    input : 입력 데이터
    padding_size : padding 연산 후의 데이터 크기
    """
    if(padding_size == 0):
      return input

    padding_matrix = np.zeros((input.shape[0] + padding_size, input.shape[1] + padding_size))

    for i in range(input.shape[0]):
      for j in range(input.shape[1]):
        padding_matrix[i + int(padding_size / 2)][j + int(padding_size / 2)] = input[i][j]
    
    return padding_matrix

패딩 클래스 구현 모습
 
64개의 필터와 7*7 크기의 필터를 사용,

cnn.same_padding_cnn(input, 7, 64)

print(len(cnn.cnn_result),len(cnn.cnn_weight))
>>>
64, 64

64개의 합성곱 연산 결과와 가중치(7,7)가 생성된 모습

class POOLING:
  pad = PADDING()

  pool_result = []

  def max_pooling(self, input, pooling_size):
    """
    input : 입력 데이터
    pooling_size : pooling size
    """
    self.pool_result = []
    
    pooling_matrix = self.pad.padding(input, input.shape[0] % pooling_size)

    for col in range(0, pooling_matrix.shape[0], pooling_size):
      for row in range(0, pooling_matrix.shape[1], pooling_size):
        pool_arr = []
        for pooling_col in range(pooling_size):
          for pooling_row in range(pooling_size):        
            pool_arr.append(pooling_matrix[pooling_col + col, pooling_row + row])
        self.pool_result.append(max(pool_arr))
    
    # 연산 결과를 크기에 맞게 바꿔준다.
    return np.array(self.pool_result).reshape(int(pooling_matrix.shape[0] / pooling_size), -1)

이후 각 합성곱 연산에 max_pooling 을 수행한다. 
 

  def pooling(self, pooling_size):
    self.cnn_result_reset()

    # 각 합성곱 연산 결과별 pooling 연산을 수행한다.
    for i in range(self.data_size):
      pooling_result = self.pool.max_pooling(self.layer_result[self.layer - 1][i], pooling_size)

      self.cnn_result.append(pooling_result)
    
    self.layer_result.append(self.cnn_result)

    # 레이어의 추가
    self.layer = self.layer +1

 

cnn.pooling(2)

cnn.layer_result[1][0].shape
>>>
(14, 14)

pooling 연산 후 2 개의 레이어가 생성되고, 28,28 사이즈의 데이터는 그 반인 (14,14) 사이즈로 감소한 것을 확인할 수 있다.
 

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

implement_CNN(MLP 전 까지)  (0) 2023.03.09
implement_CNN(수정)  (0) 2023.03.09
implement_CNN(pooling)  (0) 2023.03.07
implement_CNN(start)  (0) 2023.03.07
implement_CNN(pooling)  (0) 2022.12.06