이제 생선에서 벗어나 패션 아이템이라는 새로운 데이터 셋을 사용하게 됐다.
아이템 분류 문제를 기존 로지스틱 회귀로도 다시 해보고 이번 챕터에서 새로 배울 인공 신경망을 통해서도 분류를 한다음 성능을 비교해보자.
우선 데이터를 로딩하는데 패션 MNIST 데이터는 워낙 유명하기 때문에 딥러닝 라이브러리에서 이 데이터를 바로 로딩해서 쓸수 있다.
라이브러리는 텐서플로라는 아주 유명한 라이브러리를 사용했고 로딩한 데이터를 출력해보고 샘플의 타깃값 10개와 레이블당 샘플수까지 확인해봤다.
이 훈련 샘플은 60,000개나 되기 때문에 전체 데이터를 한꺼번에 사용하여 모델을 훈련하는 것보다 샘플을 하나씩 꺼내서 훈련하는 방법이 더 효율적으로 보인다. 확률적 경사 하강법이다.
훈련전에 2차원인 샘플들을 1차원으로 펼쳐서 전처리를 해야 한다. SGDClassifier 클래스와 cross_validate 함수를 사용해 이 데이터에서 교차 검증으로 성능을 확인해보자.
반복횟수를 20번으로 지정한 값이 0.843 정도로 그렇게 크지 않다.
인공신경망
우선 위 문제를 인공 신경망으로 처리해보자.
패션 데이터를 훈련세트와 검증세트로 나누고 훈련세트와 검증세트의 크기를 알아보면 60,000개의 데이터중에 12,000개가 검증세트로 분리되었다.
인공신경망 처리과정을 그림을 보면 왼쪽에서 오른쪽으로 진행이 되는데 각 단계별로 층으로 나눠서 논리적으로 처리하고 있다.
맨 왼쪽 레이어는 그림의 각 특성(784개)이 입력되는 층 그리고 각 가중치등의 계산을 통해 맨 오른쪽에는 10개의 분류가 되어 있는 출력층이 존재한다.
이걸 합쳐서 밀집층, 영어로 dense layer 이라고 한다. 또 이런 층을 양쪽의 뉴런이 모두 연결하고 있기 때문에 완전 연결층이라고도 부른다. 케라스에는 아래처럼 표현하고 있다.
이렇게 만든 레이어로 모델을 구성하는데 그걸 위의 Sequential 클래스로 처리하고 있다. 위 소스의 model 객체가 바로 신경망 모델이다. 이렇게 모델을 만들었다면 데이터를 입력해서 훈련을 해보자.
손실함수는 4장의 이진분류에서 sparse_categorical_crossentropy 이진 크로스 엔트로피를 지정하고 에폭은 5번만 지정하고 훈련해서 평가를 했는데 정확도가 위의 0.843보다 높은 0.854가 나온걸 알수있다. 검증 세트도 0.85정도로 높은 정확도가 나왔다.
참고 코드
from tensorflow import keras
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
print(train_input.shape, train_target.shape)
import matplotlib.pyplot as plt
fig, axs = plt.subplots(1, 10, figsize=(10,10))
for i in range(10):
axs[i].imshow(train_input[i], cmap='gray_r')
axs[i].axis('off')
plt.show()
print([train_target[i] for i in range(10)])
import numpy as np
print(np.unique(train_target, return_counts=True))
train_scaled = train_input / 255.0
train_scaled = train_scaled.reshape(-1, 28 * 28)
print(train_scaled.shape)
from sklearn.model_selection import cross_validate
from sklearn.linear_model import SGDClassifier
sc = SGDClassifier(loss='log', max_iter=20, random_state=42)
scores = cross_validate(sc, train_scaled, train_target, n_jobs=-1)
print(np.mean(scores['test_score']))
## 인공신경망
import tensorflow as tf
#print(tf.__version__)
from tensorflow import keras
#print(keras.__version__)
from sklearn.model_selection import train_test_split
train_scaled, val_scaled, train_target, val_target = train_test_split(
train_scaled, train_target, test_size=0.2, random_state=42 )
print(train_scaled.shape, train_target.shape)
print(val_scaled.shape, val_target.shape)
dense = keras.layers.Dense(10, activation='softmax', input_shape=(784, ))
model = keras.Sequential(dense)
## 인공 신경망으로 패션 아이템 분류하기
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
print(train_target[:10])
model.fit(train_scaled, train_target, epochs=5)
model.evaluate(val_scaled, val_target)
확인문제
문제 1. 어떤 인공 신경망의 입력 특성이 100개이고 밀집층에 있는 뉴런 개수가 10개일 때 필요한 모델 파라미터 개수는 몇 개인가요?
1-1. 1000개
1-2. 1001개
1-3. 1010개
1-4. 1100개
풀이 100 x 10 + 10
맨 뒤에 10은 뉴런마다 1개의 절편이 있으므로 총 1010개의 모델 파라미터가 있음. 답 3번
문제 2. 케라스의 Dense 클래스를 사용해 신경망의 출력층을 만들려고 합니다. 이 신경망이 이진 분류 모델이라면 activation 매개변수에 어떤 활성화 함수를 지정해야 하나요?
2-1. 'binary'
2-2. 'sigmoid'
2-3. 'softmax'
2-4. 'relu'
풀이 1번은 없는 활성화 함수, 3번은 다중 분류에서 출력층에 사용, 4번은 이미지 분류시 좋음
답 2번
문제 3. 케라스 모델에서 손실 함수와 측정 지표 등을 지정하는 매서드는 무엇인가요?
3-1. configure()
3-2. fit()
3-3. set()
3-4. compile()
풀이 1번과 3번은 없는 메서드 2번은 훈련시 사용하는 메서드
답 4번
문제 4. 정수 레이블을 타깃으로 가지는 다중 분류 문제일 때 케라스 모델의 compile() 메서드에 지정할 손실 함수로 적절한 것은 무엇인가요?
4-1. 'sparse_categorical_crossentropy'
4-2. 'categorical_crossentropy'
4-3. 'binary_crossentropy'
4-4. 'mean_square_error'
풀이 2번은 타깃값이 원-핫 인코딩된 경우 사용, 3번은 이진분류시 사용하는 손실 함수, 4번은 회귀 문제에 사용하는 손실함수
답 1번