본문 바로가기

BLOG/딥러닝

이미지 분류하기

【2】CNN_합성곱 신경망 / 이미지 분류하기

이미지 분류하기

 

CNN으로 이미지를 분류해보자.

 

try:

  %tensorflow_version 2.x

except Exception:

  pass

import tensorflow as tf #텐서플로우 2.x 실행

 

CNN을 돌리기에 앞서 텐서플로우(Tensorflow) 버전을 2.x으로 바꿔야 한다.

그래서 위에 코드를 실행하면 2.x로 바뀝니다.

 

from tensorflow.keras import datasets, layers, models 

 

모델을 작성하기에 앞서 keras 패키지를 호출한다.

 

(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()

 

이미지 분류에 사용할 Mnist 데이터셋을 부릅니다.

Mnist 데이터는 0 ~ 9 숫자들이 손글씨 작성된 이미지들이 6만개로 데이터 형태는 28 x 28 되어있다.

 

train_images = train_images.reshape((60000, 784, 1)) 
test_images = test_images.reshape((10000, 784, 1)) 
train_images, test_images = train_images / 255.0, test_images / 255.0

 

데이터셋을 불러왔고 해당 데이터들을 학습에 맞게 전처리를 해야한다.

Conv1D는 입력데이터가 2차원의 형태로 존재를 해야한다.

입력데이터의 형태는 2가지로 학습이 가능하고 784  x 1과 28 x 28 입니다.

책에서는 784 x 1의 형태로 학습으로 진행한다. 

 

데이터셋을 형변환까지 했다면 이번에는 데이터를 정규화를 진행을 하는데 이미지 데이터셋은 RGB가 255까지 표현되며 255를 나누면 된다.

 

model = models.Sequential() #모델 생성.

model.add(layers.Conv1D(64, 3, activation='relu', input_shape=(784, 1)))  #Conv1D 모델을 추가한다.

model.add(layers.MaxPooling1D(2)) #Maxpooling 추가를 한다.

model.add(layers.Conv1D(32, 3, activation='relu'))

model.add(layers.MaxPooling1D(2))

model.add(layers.Conv1D(32, 3, activation='relu'))

 

이번에는 모델을 구축을 해보자

 

Sequential() 명령어로 모델을 생성가능하고 만들어진 모델에 add 명령어로 층을 쌓을 수가 있다.

 

Conv1D 명령어로 층을 쌓을 수가 있는데 매개변수를 생략이 가능하고 생략을 하게 되면 필터사이즈, 커널사이즈 순으로 변수가 적용이 된다.

여러 매개변수들이 존재하지만 많이 쓰는 매개변수를 알아보자

 

첫번째는 활성함수다.

CNN 뿐만이 아닌 다른 립러닝을 할 때 가장 많이 쓰인다. 

활성함수는 많은 종류가 있지만 시그모이드(sigmoid),렐루(relu)를 보편적으로 사용한다. 

 

두번째는 input_shape다. 

모델을 Sequential()로 생성하게 되면 입력층이 정해져 있지 않기 때문에 input_shape로 직접 입력형태를 지정을 해야한다.

 

세번째는 패딩이다. 

여러 층을 쌓게 되면 커널사이즈 때문에 데이터가 손실이 발생한다. 커널사이즈로 인해 줄어드는 데이터를 유지하기 위해 사용하는 매개변수다.

valid, same, causal가 있으며 디폴트는 valid로 되어있다.

 

네번째는 보폭(strides)이다.

데이터를 줄이기 위해서 사용되는 매개변수며 보폭이 설정된 크기만큼 나누게 된다.

 

Conv1D의 데이터 입력의 차원은 3차원이지만 Conv2D에서는 4차원을 사용하기에 커널사이즈, 보폭의 크기가 1차원이 아닌 2차원으로 변경된다.

 

풀링(pooling)은 Conv레이어의 출력 데이터를 줄여 과적합(overfitting)을 줄이는 데 사용하는 명령어다

pooling에는 종류가 최대값인 max와 평균값인 average가 있고, 1차원으로 출력하는 global 풀링이 존재한다.

 

model.add(layers.Flatten()) 

model.add(layers.Dense(32, activation='relu')) 

model.add(layers.Dense(10, activation='softmax')) 

 

mnist 이미지 분류 데이터셋이므로 분류를 위해서 뉴럴넷(FFNN : Feed-forward Neural Network)로 바꿔줘야한다.

Conv1D 출력은 3차원이고 뉴럴넷은 2차원이므로 차원이 맞지 않는 오류가 발생한다.

그래서 Flatten을 사용하면 차원을 낮출 수 있다.

마지막 뉴럴넷의 유닛을 10으로 지정함으로써 이미지 분류를 할 수 있다.

 

model.compile(optimizer='adam',

              loss='sparse_categorical_crossentropy',

              metrics=['accuracy'])

 

 

model.fit(train_images, train_labels, epochs=1,verbose=1) 

 

모델은 완성하였고 학습을 시키기 전 컴파일 과정을 진행을 해야 한다.

컴파일은 크게 옵티마이저(optimizer), 로스함수(loss function)를 설정한다.

메트릭스(metrics)는 선택사항이며 설정을 하면 학습 과정에서 측정항목인 acc,val_loss을 나태나며 표시를 해준다.

fit는 만들어진 모델을 학습을 시키는 명령어다.

fit(X의 값, y의 값)을 표시하며 에포크(epochs)는 반복횟수, 버보스(verbose) 학습을 할 때 과정을 출력해준다.

 

_, test_acc = model.evaluate(test_images,  test_labels, verbose=2) 

 

모델 학습이 끝나면 평가를 해야 하는데 evalutae라는 명령어로 확인이 가능하다.

 

 

 

 


작성자 김강빈 kkb08190819@gmail.com / 이원재 ondslee0808@gmail.com