본문 바로가기

Information/구글 텐서플로우 자격증 따기

[코세라 강좌] 3주차 - 이론(1/2)

반응형

What are convolutions and pooling

앞에서 패션 MNIST 데이터에 대해 이미지 분류하는 모델링을 해봤는데, 정확도가 87% 정도였음.

 

정확도를 더 높일 수 있는 기법이 콘볼루션과 풀링 기법

 

콘볼루션(convolution) 예전부터 이미지 프로세싱에서 많이 쓰였던 기법으로, 수평 에지(edge)나 수직 에지를 검출할 때 쓰는 소벨 마스크 등이 콘볼루션 기법임

Convoloution

 

vertical edge detection filter

 

이처럼 콘볼루션은 이미지의 특성을 더 극명하게 나타내 줌. 즉, 에지가 있는 부분은 더 두드러지게 하고 아닌 부분은 더 약하게 해서 원래 이미지가 가지고 있는 고유의 특성이 더 강조되는 것임.

 

따라서, 이러한 콘볼루션 연산을 원본 이미지에 하게 되면, 그 원본 이미지가 다른 이미지와는 다른 고유의 특성을  더 잘 나타나게 되어서, 끝내는 다른 이미지와의 `구분` 작업이 용이해지게 되고, 이렇게 된 상태에서 딥러닝 학습을 하게 되면 더 분류 정확도가 높아지는 것 (물론 이미지 자체가 훼손되는 것은 맞음. 그러나 분류는 더 잘되는 상태로 바뀌게 됨)

Pooling

가장 큰 값만을 선택

 

 

 

콘볼루션 사용한 코딩

 

import tensorflow as tf

print(tf.__version__)

mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()

training_images=training_images.reshape(60000, 28, 28, 1)
training_images=training_images / 255.0

test_images = test_images.reshape(10000, 28, 28, 1)
test_images=test_images/255.0

model = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(2, 2),

    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),

    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.summary()

model.fit(training_images, training_labels, epochs=5)
test_loss = model.evaluate(test_images, test_labels)

 

Step 1. 트레이닝 데이터를 60000 x 28 x 28 x 1의 4D 배열로 변환

 

원래 트레이닝 데이터는 28x28x1인 3D 배열이 60000개인데, 이를 1개의 배열로 바꿈. 이유는 콘볼루션 연산인 Conv2D가 단일 배열을 입력으로 받기 때문

 

테스트 데이터에 대해서도 동일하게 reshape

 

training_images=training_images.reshape(60000, 28, 28, 1)
training_images=training_images / 255.0

test_images = test_images.reshape(10000, 28, 28, 1)
test_images=test_images/255.0

 

Step2. 모델 생성

tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(28, 28, 1)),

Conv2D의 파라미터를 보면,

  1. filters=64: the number of output filters in the convolution. 32의 배수로 지정하면 좋음
  2. kernel_size = (3,3): 2D 콘볼루션의 윈도 사이즈
  3. activation='relu': if x>0 then x else 0
  4. input_shape=(28,28,1) : 입력 데이터인 이미지의 픽셀 형태

tf.keras.layers.MaxPooling2D(2, 2),

MaxPooling2D는 주어진 필터 크기의 픽셀 데이터중 가장 큰 값 하나를 취함. 

(2x2) 필터이면, 4개의 픽셀 중 가장 큰 값을 가진 픽셀만 취하는 것으로, 원래 이미지 크기의 1/4만큼 축소되는 효과를 발휘함

 

Conv2D를 하고 나서 MaxPooling2D를 하는 게 일반적인데, 그 이유는,

Conv2D에 의해서 각 픽셀이 가지고 있는 값이 더 극단적으로 변했고(작은 값을 더 작게, 큰 값을 더 크게 했기에, 이미지가 가지고 있는 특성이 더 극대화된 것임), 이 상태에서 (2x2)의 4픽셀 중 가장 큰 값을 취하게 되면, 그 이미지가 가지고 있는 극단적인 값 즉, 그 특성은 어느정도 가져가면서 크기를 1/4로 줄이는 효과를 냄.

 

이렇게 하게되면 (28x28) 크기의 이미지는 Conv2D에 의해서 (26x26)으로 바뀌고 (양 끝단의 픽셀은 제외하기에, 풀링에 의해서 (13x13) 크기의 이미지로 작아지게 됨


    tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),

이제 이 콘볼루션과 풀링 연산을 한번 더 하게되면, 크기는 (13x13)->(11x11) -> (5x5)로 작아져서, 이 작아진 이미지로 학습을 하게되면, 학습 속도가 빨라지고, 각 이미지 간의 차별 특성도 오히려 더 좋아짐

    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')

 


model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.summary()

모델을 만들고, 만들어진 모델링에 의해서 입력 데이터의 크기가 바뀌는 것은 model.summary() 메서드에 의해서 알아볼 수 있습니다.

 


model.fit(training_images, training_labels, epochs=5)
test_loss = model.evaluate(test_images, test_labels)

모델을 이용해서 학습을 시켜보면, 콘볼루션을 적용하기 이전보다 적확도가 더 좋아졌습니다.

 

1875/1875 [==============================] - 94s 50ms/step - loss: 0.1906 - accuracy: 0.9290
313/313 [==============================] - 4s 13ms/step - loss: 0.2616 - accuracy: 0.9045

 

-끝-

반응형