본문 바로가기

implement_ml_models/CNN

implement_CNN(start)

시각 피질 안의 뉴런들이 작은 국부 수용장을 가진다. 

이는 뉴런들이 시야의 일부 버위 안에 있는 시각 자극에만 반응한다는 뜻이다.

각 뉴런들은 동일한 수용장을 가지지만 다른 각도의 선분에 반응, 어떤 뉴런은 큰 수용장을 가져, 저수준 패턴이 조합된 더 복잡한 패턴에 반응한다.

고수준 뉴런이 이웃한 저수준 뉴런의 출력에 기반한다는 아이디어, 이러한 구조가 전체 시야 영역에 포함된 모든 종류의 복잡한 패턴을 감지할 수 있게 한다.

합성곱 층

수용장 안의 픽셀에만 연결된다.

class CNN:

  # 필터의 개수만큼 가중치가 존재
  cnn_weight = []

  # 가중치 연산 결과
  cnn_result = []
  
  def cal_cnn(self, input, target, 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 row in range(input.shape[0] - weight.shape[0] + 1):
        for col in range(input.shape[1] - weight.shape[1] + 1):
          result = []
          for w_row in range(weight.shape[0]):
            for w_col in range(weight.shape[1]):
              result.append(input[row + w_row, col + w_col] * weight[w_row, w_col])
          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] - weight.shape[0] + 1)

      # 연산 결과의 저장
      self.cnn_result.append(result_arr)

cnn 계산

cnn 계산 시, 입력 데이터와 원하는 필터의 크기, 필터의 개수를 입력받는다.

1 : 필터의 크기에 맞는 임의의 가중치가 생성된다.

2 : 합성곱 연산의 반복, 생성되는 합성곱 연산 결과는 입력 데이터의 행과 열, 가중치(핕터)의 크기에 따라 달라진다. 합성곱 연산 결과 행렬의 크기는 입력 데이터 행 - 필터 행 + 1 의 크기이다.

3 : 합성곱 [0][0] 부터 계산, 또는 반복을 줄이기 위해 입력 데이터의 각 요소에서 계산되는 값을 미리 넣어준 후 값을 누적시키는 방법을 사용할 수 있다.

4 : result_arr 에 리스트 형식으로 일렬로 저장되어 있는 값을 합성곱 연산 결과의 크기에 맞게 바꿔준다.

cnn = CNN()

cnn.cal_cnn(input, target, 7, 1)

cnn.cnn_result[0].shape
>>>
(22, 22)

cnn.cnn_weight[0].shape
>>>
(7, 7)

패딩과 풀링

합성곱 연산 이후 데이터의 차원 크기를 줄이기 위해 풀링을 수행할 수 있다.

이러한 풀링의 크기에 따라 가중치 연산 결과의 크기가 감소한다.

데이터 차원 크기와 풀링의 크기가 정확히 맞지 않을 때, 연산 전 빈 공간을 채우기 위해 패딩을 수행한다. 패딩은 임의의 범위를 0으로 채우는 것,

이러한 패딩을 수행하기 위해 패딩 연산 후의 데이터 차원 크기를 미리 계산한 후, 해당 크기의 0으로 이뤄진 행렬을 만들고, 데이터를 적절한 위치에 넣는 방식을 사용한다.

class PADDING:

  def padding(self, input, padding_size):
    """
    input : 입력 데이터
    padding_size : padding 연산 후의 데이터 크기
    """
    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

임의의 패딩크기를 입력받고, 해당 크기의 적절한 위치에 입력 데이터를 넣어준다.

 

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

implement_CNN(same_padding)  (0) 2023.03.09
implement_CNN(pooling)  (0) 2023.03.07
implement_CNN(pooling)  (0) 2022.12.06
impelment_CNN(stride)  (0) 2022.12.06
implement_CNN(padding)  (0) 2022.12.06