이미지 상의 어떤 특징이 어느 부분에 나타나는지를 알 수 있으면 이미지를 분류할 때 매우 유용하다.
이 정보를 찾을 목적으로 사용하는 도구가 있는데, 그것이 바로 Convolution(합성곱)이다.
컨볼루션은 이미지 처리와 신호 처리 분야에서 매우 유명한 도구이다.
이미지 처리에서는 특징 패턴의 특징이 어느 부분에 등장하는지 파악하는 데 사용된다.
특징을 찾기 위해 컨볼루션 필터를 하나 가져왔다. 이 필터는 가로로 된 선이 어디서 나타났는지 찾는 필터이다. 입력 이미지와 이 필터를 가지고 컨볼루션 연산을 하게 된다.
컨볼루션 결과는 2차원 형태의 숫자 집합으로 만들어진다. 따라서, 이미지로 표현할 수 있다.
하얗게 보이는 부분은 숫자가 높은 것이고, 검은색으로 보이는 부분은 숫자가 0에 가까운 것이다. 컨볼루션의 결과가 대상 이미지의 가로선이 있는 부분에서 하얗게 표현된 것이 보인다. 하얗게 표현된 부분이 찾고 싶은 특징이 많이 나타난 위치라고 이해하면 된다.
이렇게 대상 이미지로부터 필터를 통해 특징을 잡아낸 것을 피처맵이라고 한다.
이번에는 세로선의 특징을 찾기 위한 컨볼루션 필터를 가져왔다. 이 필터에 의해서 만들어진 피처맵은 세로선이 있던 부분이 하얗게 나타나는 걸 볼 수 있다.
컨볼루션 필터 하나는 대상 이미지를 보고 피처맵 이미지 하나를 만들게 된다. 필터 하나가 이미지 하나를 만든다는 걸 기억해야한다.
#1. 과거의 데이터를 준비
(독립, 종속),_ = tf.keras.datasets.mnist.load_data()
독립 = 독립.reshape(60000,28,28,1)
종속 = pd.get_dummies(종속)
print(독립.shape, 종속.shape)
#2. 모델의 구조를 만든다.
X = tf.keras.layers.Input(shape=[28,28,1])
#컨볼루션 연산은 3차원 형태의 관측치를 입력으로 받는다. 텐서플로를 만든 사람이 정해놓은 것이기 때문에, 입력의 형태가 (28,28)이 아니라 (28,28,1)이어야 한다. 따라서, 독립변수를 (60000,28,28,1)로 reshape하는 코드를 추가했다. 컬러 이미지가 3차원 형태로 되어있기때문에 흑백 이미지도 3차원 형태로 변형해 준다고 생각하면 된다.
H = tf.keras.layers.Conv2D(3, kernal_size=5, activation='swish')(X)
H = tf.keras.layers.Conv2D(6, kernal_size=5, activation='swish')(X)
#컨볼루션 레이어를 2층 추가했다. 컨볼루션 레이어에서 우리가 결정할 것은 필터셋을 몇개 사용할지와 필터셋의 사이즈를 얼마로 할지이다. 3과 6의 필터셋의 개수이다.
#kernal_size는 필터셋의 크기를 의미한다. (5,5) 사이즈의 필터셋을 사용하기 위해 5라고 입력했다. 컨볼루션 레이어는 기존의 덴스 레이어와 같이 활성화 함수를 지정해 주어야한다.
H = tf.keras.layers.Flatten()(H)
#이렇게 만들어진 6채널의 특징 맵 모두를 Flatten 레이어에 의해서 픽셀 단위로 한줄로 펼친 후 학습하게 된다.
H = tf.keras.layers.Dense(84, activation='swish')(H)
Y = tf.keras.layers.Dense(10, kernal_size=5, activation='softmax')(H)
model = tf.keras.models.Model(X,Y)
model.compile(loss='categorical_crossentropy', metrics='accuracy')
첫번째 컨볼루션 레이어는 필터셋이 3개이므로 3장의 특징맵을 만든다. 달리 말해서, 3 채널의 특징맵을 만든다고 할 수 있다.
두번째 컨볼루션 레이어는 필터셋을 6개 썼으므로 6장의 특징맵을 만든다. 6채널의 특징맵을 만든다고 표현할 수 있다.