개발공부

여러 클래스로 분류하는 모델링, 액티베이션 함수 softmax, 예제 본문

Python/Deep Learning

여러 클래스로 분류하는 모델링, 액티베이션 함수 softmax, 예제

mscha 2022. 6. 13. 15:19

Softmax

입력받은 값을 출력으로 0~1사이의 값으로 모두 정규화하며 출력 값들의 총합은 항상 1이 되는 특성을 가진 함수이다.

분류의 문제를 위한 모델링을 할 때 아웃풋 노드의 액티베이션함수(activation function)를  softmax로 사용하면

학습할 때 가장 큰 값을 가진 수를 1, 나머지를 0으로 본후 1의 위치와 label 데이터의 값을 비교하여 accuracy를

평가한다.

이미지 분류 모델을 생성할 때 Flatten 라이브러리 사용하는 이유

예를 들어 28 X 28 크기의 GrayScale 인 이미지가 있다고 하자.

이 이미지의 카테고리를 분류하는 모델을 만들려고 하면 인풋레이어에 

28 X 28 개 즉 784개 의 노드가 필요하다. 그러므로 28개의 행, 28개의 열로 되어있는 모양을

Flatten 라이브러리를 통해 784개의 열로 되어있는 형태로 바꿔야 한다.

 

소프트맥스로 나온 결과를, 레이블 인코딩으로 바꾸는 방법

예측한 값에 .argmax()를 하여 최대값의 위치를 추출한다.

 

분류의 문제에서 loss 셋팅하는 방법

2개 분류의 문제일 때는, 로스 펑션 : binary_crossentropy

3개 이상의 분류의 문제일 때는? 

- y의 값이 레이블 인코딩으로 되어있는 경우 : sparse_categorical_crossentropy

- y의 값이 원 핫 인코딩으로 되어있는 경우 : categorical_crossentropy

 

이미지 분류 모델 생성 예제

텐서플로우에서 제공하는 fashion_minst 데이터 세트

mnist = tf.keras.datasets.fashion_mnist

트레이닝과 테스트 세트 가져오기

(training_images, training_labels),(test_images, test_labels) = mnist.load_data()

이미지는 0 - 255의 정수로 되어있다.

 

>>> training_images.shape
(60000, 28, 28)
>>> training_labels.shape
(60000,)

>>> test_images.shape
(10000, 28, 28)
test_labels.shape
(10000,)

0과 1사이의 값으로 노멀라이징 한다.

training_images = training_images / 255.0
test_images = test_images / 255.0
# 트레이닝 이미지의 shape은  (28,28) 이다.
>>> training_images[0].shape
(28, 28)
import tensorflow as tf

# 빈 틀을 만든다.
model = tf.keras.models.Sequential()
# 인풋으로 들어오는 데이터를 flatten (1차원으로 변경)해준다.
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128, 'relu'))
# 3개 이상의 분류 문제 Output Layer activation func -> softmax
model.add(tf.keras.layers.Dense(10, 'softmax'))

# 2개 분류의 문제일 때는, 로스 펑션을 binary_crossentropy
# 3개 이상의 분류의 문제일 때는? 2가지 경우가 있다.
# 첫번째 경우, y의 값이 레이블 인코딩으로 되어있는 경우 : sparse_categorical_crossentropy
# 두번째 경우, y의 값이 원 핫 인코딩으로 되어있는 경우 : categorical_crossentropy
model.compile(optimizer = 'adam', loss = 'sparse_categorical_crossentropy', 
				metrics = ['accuracy'])

모델 학습하기

model.fit(training_images, training_labels, epochs = 5)

학습한 모델을 테스트 데이터로 평가하기

model.evaluate(test_images, test_labels)

테스트 이미지를 예측하기

y_pred = model.predict(test_images)
>>> test_images.shape
(10000, 28, 28)

실제 테스트 이미지 100번의 정답

>>> test_labels[100]
3

내가 예측한 테스트 이미지 100번의 정답

y_pred[100]

위의 값은 테스트 이미지의 정답인 0-9의 수가 있는데 각각이 될 확률을 0~1의 값으로 나타낸 것이다.

그러므로 우리가 원하는 예측 값은 y_pred[100] 의 값들 중 최대값의 위치이다.

이를 코드로 표현하면 아래와 같다.

>>> y_pred[100].argmax()
3

그럼 모든 테스트 이미지를 우리가 원하는 예측 값으로 바꾸면 아래와 같다.

y_pred = y_pred.argmax(axis=1)

이를 컨퓨전 매트릭스(confusion matrix)로 나타내보자.

from sklearn.metrics import confusion_matrix
import seaborn as sns
cm = confusion_matrix(test_labels, y_pred)
# 행 - test, 열 - pred
sns.heatmap(cm, annot= True, fmt='.0f', cmap = 'RdPu')
plt.show()