MLP에서는 각 입력마다 다른 가중치들이 계산되며 적용되었는데, CNN에서는 이 가중치 뉴런이 한 뭉탱이로 묶여 입력들 사이로 이동하며 계산이 된다.
이때 이런 하나의 뭉탱이(?)인 가중치를 필터 혹은 커널 이라고 한다.
일반적인 CNN 모델을 치면 나오는 이미지이다. 아직은 이를 보면 어떤 식으로 동작하는 건지 잘 와닿지 않겠지만, 이 포스팅이 끝나면 이러한 CNN 모델들을 이해할 수 있게 될 것이다.
필터(Filter)를 통해 이미지의 특징(feature)을 추출
Filter라는걸 통해서 어떻게 이미지의 feature(특징)를 뽑을 수 있는지 예시를 통해 살펴보자.
이미지처리에서 자주 등장하는 sobel filter는 이미지의 가로세로 feature를 뽑아낼 수 있는 필터이다.
필터를 보면 이런 값을 가지고 있다.
위의 원본 이미지에 sobel 필터를 차례대로 적용시키면 다음과 같은 결과를 확인할 수 있다.
왼쪽이 sobel-x가 적용이 된 이미지이고, 오른쪽이 sobel-y가 적용된 이미지이다.
각 이미지의 특징을 보니 왼쪽은 세로선이 detect되고 오른쪽은 가로선이 detect된 것을 확인할 수 있다.
이 둘을 합치면 아래와 같이 원본사진의 feature를 확인할 수 있다.
이처럼 CNN에서도 여러개 필터를 이용해 이미지의 세부 특징을 추출해서 학습을 할 수 있다.
CNN은 신경망에서 학습을 통해 자동으로 적합한 필터를 생성해 준다는 것이 특이사항이다.
이미지 가장자리에 0을 덧댐으로써, 특정 이미지에서 Convolution을 가장자리에서도 하게 하려는 것
입력데이터보다 출력데이터가 작아지는것을 방지하는 방법이 Padding이다.
n칸씩 건너뛰면서 convolution을 하는 것
해당 필터에 대한 특징이 “있다”와 “없다”로 바꾸어주는 과정
일반적으로 렐루(ReLU) 함수를 사용한다.
렐루는 양수일 경우에는 입력을 그대로 내보내며, 음수인 경우에는 0으로 변경한다.
# keras.Sequential(): 순차적인 레이어(keras.layers.~~)를 더하는(add) 형태로 구성되는 모델
model = keras.Sequential()
model.add(keras.layers.Conv2D(32, kernel_size=3, activation='relu',
padding='same', input_shape=(28,28,1)))
⇒ 위의 함수 사용 결과
특징(feature)을 강화시키고, 이미지의 크기를 줄임
사진 전체 부분을 유지한 상태로 픽셀만 줄이는 것 (해상도를 줄인다고 생각)
서브 샘플링은 두 종류의 풀링 연산으로 합성곱 신경망에 적용된다.
최대 풀링(max-pooling)과 평균 풀링(mean-pooling 또는 average-pooling)이다.
풀링 층은 보통 로 표시한다. 아래 첨자 nxm는 최댓값과 평균 연산이 수행되는 이웃한 픽셀 크기이다.
이런 이웃 픽셀 개수를 풀링 크기라고 한다.
최대 풀링은 이웃한 픽셀에서의 최댓값을 취하고, 평균 풀링은 픽셀의 평균을 계산한다.
최대 풀링은 입력 데이터에 있는 잡음에 좀 더 안정적인 특성을 생성한다. 또한 이러한 풀링은 특성 크기를 줄이므로 계산 효율성을 높인다. 특성(feature) 개수가 줄어들면 과대적합도 감소한다.
model.add(keras.layers.MaxPooling2D(2))
⇒ 위의 함수 사용 결과
2차원의 배열 형태 이미지를 1차원의 형태로 펼쳐주는 작업
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(100, activation='relu'))
model.add(keras.layers.Dropout(0.4))
model.add(keras.layers.Dense(10, activation='softmax'))
⇒ 위의 함수 사용 결과
model = keras.Sequential()
model.add(keras.layers.Conv2D(32, kernel_size=3, activation='relu',
padding='same', input_shape=(28,28,1)))
model.add(keras.layers.MaxPooling2D(2))
model.add(keras.layers.Conv2D(64, kernel_size=(3,3), activation='relu',
padding='same'))
model.add(keras.layers.MaxPooling2D(2))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(100, activation='relu'))
model.add(keras.layers.Dropout(0.4))
model.add(keras.layers.Dense(10, activation='softmax'))
model.summary()
참고 자료: https://www.edwith.org/deeplearningchoi/lecture/15293