머신러닝 + 딥러닝

머신러닝 | 딥러닝

2022. 7. 6. 18:17
728x90

패션 MNIST

운동화, 셔츠, 샌들과 같은 작은 이미지들의 모음이며 28*28 픽셀의 이미지 7만개로 이루어져 있다.

 

텐서플로의 케라스(Keras) 패키지를 임포트하고 패션 MNIST 데이터를 다운로드한다.

from tensorflow import keras
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()

keras.datasets.fashion_mnist 모듈 아래 load_data() 함수는 훈련 데이터의 입력과 타깃의 쌍, 테스트 데이터의 입력과 타깃 쌍을 반환해준다.

 

더보기

만약, 시험을 보기 전에 출제될 시험 문제와 정답을 미리 알려주고 시험을 본다면 어떻게 될까?

누구나 시험 문제와 정답을 외운다면 당연히 100점을 맞을 것이다

-

머신러닝도 이와 마찬가지로 같은 데이터로 훈련하고 같은 데이터로 테스트한다면 모두 맞히는 것이 당연하다

머신러닝 알고리즘의 '성능'을 제대로 평가하려면 훈련 데이터와 평가에 사용할 데이터가 각각 달라야한다

-

이렇게 하기 위해서는 평가를 위해 또다른 데이터를 준비하거나, 이미 준비된 데이터 중에서 일부를 떼어내어 활용하는 방법이 있다

주로 후자의 방법을 많이 쓴다

-

그래서 평가에 사용되는 데이터를 테스트 세트(test set)라고 하고 훈련에 사용되는 데이터를 훈련 세트(train set)라고 한다

-

하지만 여기에도 문제가 있다

-

훈련 세트에서 모델을 훈련하고 테스트 세트에서 모델을 평가하는데, 테스트 세트에서 얻은 점수를 보고 '이 모델을 실전에 투입하면 이만큼의 성능을 기대할 수 있겠다'라고 할 수 있다. 일반화 성능을 가늠해 볼 수 있는데, 테스트 세트를 사용해 자꾸 성능을 확인하다보면 점점 테스트 세트에 맞추게 되는 셈이다

-

즉, 테스트 세트의 점수가 안 좋아서 테스트 세트의 점수를 높이기 위해 변수를 바꾸는 등의 행동은 결국 공부를 하지 않고 시험을 여러 번 응시해서 시험 문제를 외우는 것과 다름이 없어진다

-

테스트 세트로 인반화 성능을 올바르게 예측하려면 가능한 한 테스트 세트를 사용하지 말아야한다. 모델을 만들고 나서 마지막에 딱 한 번만 사용하는 것이 좋다

-

그래서 우리는 훈련세트를 한 번 더 나누어 검증 세트(validation set)를 만들어내야 한다

전체 데이터 중 20%를 떼어 내어 테스트 세트로 만들고 나머지 80%를 훈련 세트로 만든다. 그리고 이 훈련세트 중에서 20%를 떼어 내어 검증 세트로 만들면 된다.

 

데이터의 크기를 확인해보면,

print(train_input.shape, train_target.shape)

훈련 데이터는 60000개의 이미지로 크기는 28 x 28으로 3차원배열이고, 타깃도 60000개의 원소가 있는 1차원 배열이다.

(60000, 28, 28) (60000,)

 

테스트 세트의 크기를 확인해보면,

print(test_input.shape, test_target.shape)

훈련 데이터의 이미지 크기와 같고 10000개로 이루어져 있다.

(10000, 28, 28) (10000,)

 

입력과 타깃 샘플

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()

 

처음 10개 샘플의 타깃값을 리스트로 만들고 출력을 해본다.

print([train_target[i] for i in range(10)])

타깃 데이터는 0에서부터 9까지 있다.

[9, 0, 0, 3, 0, 2, 7, 2, 5, 5]

 

unique 함수로 레이블 당 샘플 개수를 확인해본다.

- unique() 함수 : 데이터에 고유값들이 어떠한 종류들이 있는지 알고 싶을 때 사용

import numpy as np
print(np.unique(train_target, return_counts=True))

0~9까지 레이블마다 6000개의 샘플이 들어있음을 알 수 있다.

(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=uint8), array([6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000]))

 

 

로지스틱 회귀

회귀를 사용하여 데이터가 어떤 범주에 속할 확률을 0에서 1사이의 값으로 예측하고 그 확률에 따라 가능성이 더 높은 범주에 속하는 것으로 분류해주는 지도 학습 알고리즘

 

회귀(regression) : 여러 개의 독립변수와 한 개의 종속변수 간의 상관관계를 모델링하는 기법을 통칭

ex) 아파트 방 개수, 아파트 크기, 주변 학군 등 여러 개의 독립변수에 따라 아파트 가격이라는 종속변수가 어떤 관계를 나타내는지 모델링하고 예측하는 방법

 

이미지 데이터를 다룰 때 표준화를 하지 않고 픽셀값 0~255를 255로 나누어서 0~1 사이의 값으로 한다!

train_scaled = train_input / 255.0

 

2차원 배열을 1차원 배열로 만들기 위해 reshape로 변환한다.

train_scaled = train_scaled.reshape(-1, 28*28)

첫번째 차원인 샘플 개수는 변하지 않고 원본 데이터의 높이와 너비를 곱해서 하나의 차원으로 만들어서 각 샘플이 하나의 배열이 되도록 변환한다.

 

변환된 train_scaled를 확인해보면

print(train_scaled.shape)

784개의 픽셀로 이루어진 60000개의 샘플로 되었음을 볼 수 있다.

(60000, 784)

 

SGDClassifer 클래스와 cross_validate 함수를 사용해 교차 검증으로 성능을 확인한다.

 

SGDClassifer : 계산값을 기반으로 계산값이 0보다 작으면 -1, 0보다 크면 1로 분류한다

SGDClassifier(alpha, average, class_weight, epsilon, eta0, fit_intercept, l1_ratio, learning_rat, 
loss, max_iter, n_iter, n_jobs, penalty, power_t, random_state, shuffle, tol, verbose, warm_start)

 

손실함수 : 측정한 데이터를 토대로 산출한 모델의 예측값과 실제값의 차이를 표현하는 지표

- 모델이 데이터를 얼마나 잘 표현하지 못하는가를 나타내는 지표

- 회귀 모델에는 MSE, MAE 등, 분류 모델에는 이진 크로스엔트로피, categorical cross-entropy 등이 있다

 

에포크 : 딥러닝에서는 학습의 횟수를 의미, 데이터 샘플이 총 5번씩 사용되는 것

 

교차검증(cross validation) : 검증 세트를 떼어 내어 평가하는 과정을 여러 번 반복하고 이 점수를 평균하여 최종 검증 점수를 얻는다

하는 이유 ) 보통 많은 데이터를 훈련에 사용할수록 좋은 모델이 만들어진다. 하지만 검증세트를 너무 조금 떼어놓으면 검증 점수가 들쭉날쭉하고 불안정해질 것이다. 그래서 이럴 때 교차 검증을 사용하여 안정적인 검증 점수를 얻고 훈련에 더 많은 데이터를 사용할 수 있다

from sklearn.model_selection import cross_validate
from sklearn.linear_model import SGDClassifier
sc = SGDClassifier(loss='log', max_iter=5, random_state=42)
scores = cross_validate(sc, train_scaled, train_target, n_jobs=-1)
print(np.mean(scores['test_score']))

- loss : 손실함수의 종류를 지정 -> 'log'로 지정하여 로지스틱 손실 함수를 지정

- max_iter : 수행할 에포크 횟수를 지정 -> 전체 훈련 세트를 5회 반복(*반복 횟수를 늘려도 성능이 크게 향상되지 않는다*)

 

약 82%의 정확도를 얻을 수 있다

0.8195666666666668

 

 

728x90