과제
(9월 1일 금요일 17:50)추후에 공지해 주신다고 하셨다.
(9월 2일 토요일 18:05) 과제를 공지해주시지 않으셨다.
(9월 2일 토요일 18:10) 과제를 받았다.
- 패션 인공지능 실습 과제입니다. 한번 따라서 코딩 해보기 바랍니다.
패션 인공지능
한번 쭉 살펴보았을때, 교수님께서 제공해 주신 코드는 패션 분류 모델을 만들기 위한 코드로 보였다. 패션을 분류하는 모델을 만들기 위하여 데이터를 로드하고 환경 설정을 진행하였다.
설정
import tensorflow as tf
from tensorflow import keras
# 재현성을 위한 난수 시드 설정
tf.keras.utils.set_random_seed(42)
# 연산 결정론적 모드 활성화
tf.config.experimental.enable_op_determinism()
# Fashion MNIST 데이터셋 로드
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
코드를 시작하기에 필요한 모듈을 불러오고, 모델을 다시 실행할 때마다 동일한 결과를 얻기 위해 난수 시드를 42로 설정하고, 연산 결정론적 모드를 활성화했다. 많은 수강생들이 동일한 모델 실행 결과를 얻고자 난수 시드를 설정한 것으로 이해하였다. 난수 시드를 설정하면 모델 실행 결과를 항상 재현할 수 있어 디버깅과 실험의 일관성을 유지할 있기 때문이다.
keras.datasets.fashion_mnist.load_data() 함수를 사용하여 Fashion MNIST 데이터셋을 로드하였다. 이 데이터셋은 훈련 데이터와 테스트 데이터로 구성되어 있으며, 각각의 데이터는 입력 이미지와 해당 이미지에 대한 타깃(레이블)으로 구성되었다. 훈련 데이터셋은 모델을 훈련하는 데 사용되고, 테스트 데이터셋은 모델의 성능을 평가하는 데 사용한다.
데이터 형태 확인
print(train_input.shape, train_target.shape)
print(test_input.shape, test_target.shape)
# (60000, 28, 28) (60000,)
# (10000, 28, 28) (10000,)
train_input과 test_input 데이터의 형태를 확인하였다. 이 두 변수는 각각 훈련 데이터와 테스트 데이터의 입력 이미지를 저장하고 있으며, train_input의 형태는 (60000, 28, 28)로, 60000개의 이미지가 있고 각 이미지는 크기는 28x28 이다. train_target과 test_target은 각각 훈련 데이터와 테스트 데이터의 레이블을 저장하며, 레이블의 형태는 (60000,)와 (10000,)으로 훈련 데이터와 테스트 데이터의 샘플 수와 일치하는 것을 볼 수 있다.
시각화
import matplotlib.pyplot as plt
# 처음 10개의 이미지를 출력하기 위한 서브플롯 생성
fig, axs = plt.subplots(1, 10, figsize=(10, 10))
# 처음 10개 이미지를 반복하면서 출력
for i in range(10):
axs[i].imshow(train_input[i], cmap='gray_r')
axs[i].axis('off')
# 이미지 출력
plt.show()
처음 10개의 데이터를 Matplotlib을 이용하여 출력해보았다. 데이터를 시각화하고 확인함으로써 데이터가 올바르게 불러왔는지를 확인할 수 있다.
분포 확인
import numpy as np
print(np.unique(train_target, return_counts=True))
# (array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=uint8), array([6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000]))
각 레이블 값의 고유한 값과 등장 횟수를 출력하여 데이터의 클래스 분포를 확인했다. Fashion MNIST 데이터셋의 경우, 10개의 고유한 클래스가 있으며 각 클래스는 6,000개의 샘플로 구성되어 있음을 확인할 수 있었다.
로지스틱회귀
데이터 크기 조정
train_scaled = train_input / 255.0 # 입력 데이터 스케일 조정
train_scaled = train_scaled.reshape(-1, 28*28) # 데이터 형태 재구성
print(train_scaled.shape)
우선, 입력 데이터를 모델이 이해하기 쉽도록 0과 1 사이의 값으로 스케일 조정한다. 이는 모델의 학습을 더 잘 수행하도록 만들어 준다. 여기서, train_input은 이미지 픽셀 값으로 구성된 입력 데이터로, 0에서 255 사이의 값을 가지며, 이를 0과 1 사이의 값으로 스케일을 조정하고, 데이터의 형태를 2차원에서 1차원으로 재구성한다.
모델 구축 및 평가
로지스틱 회귀 모델을 생성하고 데이터를 활용하여 모델의 성능을 평가해보았다.
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']))
# 0.8196000000000001
여기서 사용한 cross_validate 함수는 교차 검증을 수행하는데, 이를 통해 모델의 성능을 평가하고 일반화 성능을 신뢰성 있게 확인할 수 있다. 위 코드 결과를 통해 모델의 성능을 나타내는 평균 정확도를 얻을 수 있으며, 이번 경우에는 약 81%의 정확도를 확인할 수 있다.
인공신경망
인공 신경망을 구축하여 모델을 훈련하고 평가하기 위해 sklearn 라이브러리를 활용한다.
import tensorflow as tf
from tensorflow import keras
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)
# (48000, 784) (48000,)
print(val_scaled.shape, val_target.shape)
# (12000, 784) (12000,)
위 코드에서는 train_test_split 함수를 사용하여 훈련 데이터를 훈련과 검증 데이터로 나누는 작업을 수행하며, 이를 통해 모델의 훈련 과정 중 검증 데이터를 사용하여 모델의 성능을 평가할 수 있게 된다.
모델 생성
dense = keras.layers.Dense(10, activation='softmax', input_shape=(784,))
model = keras.Sequential(dense)
keras.layers.Dense를 사용하여 10개의 클래스를 분류하기 위한 출력 레이어를 생성한다. 활성화 함수로는 softmax 를 이 사용한다. 또한, 입력 데이터의 형태를 지정하기 위해 input_shape 매개변수에 (784,)를 설정한다.
매개변수
784를 지정하는 이유는 입력 데이터의 특성 개수입니다. Fashion MNIST 데이터셋은 각 이미지가 28x28 크기의 픽셀로 구성되어 있으며, 이를 인공 신경망 모델에 입력으로 사용하기 위해서는 이미지의 픽셀을 평평하게 펼쳐서 1차원 벡터로 변환해야 합니다.
28x28 크기의 이미지를 1차원 벡터로 변환하면 각 이미지에는 총 784개의 특성(픽셀)이 있게 됩니다. 따라서 input_shape=(784,)와 같이 입력 레이어에 784를 지정해주는 것은 각 이미지가 784개의 픽셀로 이루어져 있음을 모델에 알려주는 역할을 합니다.
모델 평가
모델을 평가하기 위해 compile 메서드를 사용하고 훈련 데이터의 일부를 출력한다.
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')
# 훈련 데이터의 일부 출력
print(train_target[:10])
# [7 3 5 8 6 9 3 3 9 9]
model.compile 메서드는 모델을 컴파일하고 손실 함수(loss)와 평가 지표(metrics)를 설정한다. 여기서는 손실 함수로 'sparse_categorical_crossentropy'를 사용하고, 정확도(accuracy)를 평가 지표로 설정하였다.
# 모델 훈련
model.fit(train_scaled, train_target, epochs=5)
# 모델 평가
evaluation = model.evaluate(val_scaled, val_target)
# [0.45262545347213745, 0.8464999794960022]
모델을 훈련하기 위해 model.fit 메서드를 사용하여 훈련 데이터로 모델을 5 에포크 동안 훈련하였고, model.evaluate 메서드를 사용하여 검증 데이터로 모델을 평가하고, 검증 데이터의 손실과 정확도를 출력하였다.
검증데이터의 손실과 정확도
검증 데이터 손실(evaluation[0]): 이 값은 모델이 검증 데이터를 얼마나 잘 예측했는지를 나타냅니다. 낮은 값일수록 모델의 예측이 정확하다는 것을 의미합니다. 따라서 손실이 낮을수록 좋은 모델입니다.
검증 데이터 정확도(evaluation[1]): 이 값은 모델이 검증 데이터에서 얼마나 정확하게 분류했는지를 나타냅니다. 높은 값일수록 모델의 예측이 정확하다는 것을 의미합니다. 따라서 정확도가 높을수록 좋은 모델입니다.
결론
모델 평가 점수가 얼마나 나와야 좋은 모델인지에 대해 아직 잘 모르겠고, 이후 다양한 모델과 방법을 배우면 해당 모델을 다른 방법으로 학습시키고 테스트를 해볼 수 있지 않을까 란 생각을 해본다.
본 후기는 정보통신산업진흥원(NIPA)에서 주관하는 <AI 서비스 완성! AI+웹개발 취업캠프 - 프론트엔드&백엔드> 과정 학습/프로젝트/과제 기록으로 작성되었습니다.