본문 바로가기

데이터/딥러닝

Chapter 07-1 인공신경망

<해당 글은 혼자 공부하는 머신러닝+딥러닝을 공부하고 정리한 내용입니다.>

1. 패션 MNIST

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

 

  • 훈련 데이터를 불러와 몇 개의 샘플을 출력하여 확인
  • 패션 MNIST의 타깃은 0~9까지의 숫자 레이블로 구성

 

 

2. 로지스틱 회귀로 패션 아이템 분류하기

  • 이 훈련 샘플은 60,000개나 되기 때문에 전체 데이터를 한꺼번에 사용하여 모델을 훈련하는 것보다 샘플을 하나씩 꺼내서 모델을 훈련하는 방법이 더 효율적인데, 이런 상황에 잘 맞는 방법이 확률적 경사 하강법이다. 왜냐하면 특성마다 값의 범위가 많이 다르면 올바르게 손실 함수의 경사를 내려올 수 없는데, 패션 MNIST는 각 픽셀이 0~255의 정수값을 가져 범위가 같고 0~1사이의 값으로 정규화 가능하기 때문이다.
train_scaled = train_input / 255.0

#reshape()메서드를 사용해 2차원 배열인 각 샘플을 1차원 배열로 펼침
#28*28 이미지 크기에 맞게 지정
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=5, random_state=42)

scores = cross_validate(sc, train_scaled, train_target, n_jobs=-1)
print(np.mean(scores['test_score']))

 

 

3. 인공 신경망

  • 클래스를 예측하는 마지막 layer를 출력층(output layer)라고 부르고, z값을 계산하는 단위를 뉴런이라고 부른다.
  • 딥러닝(인공 신경망)은 군집알고리즘이나 앙상블과 같이 새로운 종류의 머신러닝 알고리즘이다.
  • SGDClassifier(확률적 경사 하강법)에는 없는 기능을 제공하는 인공 신경망 모델로는 텐서플로가 있다.
  • 텐서플로는 구글이 오픈소스로 공개한 딥러닝 라이브러리로, 케라스라는 고수준 API가 있다. 케라스도 딥러닝 라이브러리이다.
  • 딥러닝 라이브러리가 다른 머신러닝 라이브러리와 다른 점 중 하나는 그래픽 처리 장치인 GPU를 사용하여 인공 신경망을 훈련한다는 것이다. GPU는 벡터와 행렬 연산에 매우 최적화되어 있기 때문에 곱셈과 덧셈이 많이 수행되는 인공 신경망에 큰 도움이 된다.
  • 쉽게 import해서 사용 가능하다.
import tensorflow as tf
from tensorflow import keras

 

 

4. 인공 신경망으로 모델 만들기

  • 딥러닝 분야의 데이터셋은 충분히 커서 검증 점수가 안정적이고, 교차 검증을 수행하기에는 훈련 시간이 너무 오래 걸리므로 인공 신경망에서는 교차 검증을 잘 사용하지 않고 검증 세트를 별도로 덜어내어 사용한다.
  • 밀집층(완전 연결층) : 양쪽의 뉴런이 모두 연결하고 있다.
  • Dense 클래스 : Dense(뉴런의 개수, 뉴런의 출력에 적용할 함수, 입력의 크기)
# 검증세트 나누기
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)
    
# 밀집층 만들기
# 만약 이진 분류면 activation='sigmoid'로 설정
dense = keras.layers.Dense(10, activation='softmax', input_shape=(784,))

# 밀집층을 가진 신경망 모델 만들기
model = keras.Sequential(dense)

 

  • 활성화 함수 : 소프트맥스와 같이 뉴런의 선형 방정식 계산 결과에 적용되는 함수

 

 

5. 인공 신경망으로 패션 아이템 분류하기

  • 케라스 모델은 훈련하기 전에 설정 단계가 있는데 이런 설정을 model 객체의 compile() 메서드에서 수행한다. 손실 함수의 종류(필수)와 훈련 과정에서 계산하고 싶은 측정 값을 지정한다.
  • 다중 분류에서는 크로스 엔트로피 손실함수를 사용한다. categorical_crossentropy
  • 이진 분류의 출력 뉴런은 양성 클래스에 대한 확률만 출력하여 음성 클래스는 1-양성으로 구할 수 있어 하나의 뉴런만으로 양성과 음성 클래스에 대한 크로스 엔트로피 손실을 모두 계산할 수 있다.
  • 다중 분류는 이진 분류와 달리 각 클래스에 대한 확률이 모두 출력되기 때문에 타깃에 해당하는 확률만 남겨 놓기 위해서 나머지 확률에는 모두 0을 곱한다.
  • 예를 들어 샘플이 티셔츠일 경우 첫번째 뉴런의 활성화 함수 출력인 a1에 크로스 엔트로피 손실 함수를 적용하고 나머지 활성화 함수 출력 a2~a10까지는 모두 0으로 만드는데, 이렇게 하기 위해 티셔츠 샘플의 타깃값은 첫 번째 원소만 1이고 나머지는 모두 0인 배열로 만들 수 있다. [a1, a2, ..., a10]×[1, 0, 0, 0, 0, ..., 0] 결국 신경망은 티셔츠 샘플에서 손실을 낮추려면 첫 번째 뉴런의 활성화 출력 a1의 값을 가능한 1에 가깝게 만들어야 한다.
  • 이처럼 타깃값을 해당 클래스만 1이고 나머지는 모두 0인 배열로 만드는 것을 원-핫 인코딩이라고 부른다.
  • 케라스는 모델이 훈련할 때 기본으로 에포크마다 손실 값을 출력해주는데 정확도도 확인하기 위해 accuracy 지정
model.compile(loss='sparse_categorical_crossentropy', metrics='accuracy')

#패션 MNIST 데이터의 타깃값 확인
print(train_target[:10])

 

model.fit(train_scaled, train_target, epochs=5)

 

  • 모델의 성능 평가
model.evaluate(val_scaled, val_target)

 

 

6. 인공 신경망 모델로 성능 향상

  • 로지스틱 손실 함수를 사용한 SGDClassifier 모델을 만들어 교차 검증 점수를 확인
  • 텐서플로와 케라스 API를 소개하고 케라스를 사용해 간단한 이공 신경망 모델을 만들어 분류
  • 인공 신경망 모델을 만들며 로지스틱 손실 함수와 크로스 엔트로피 손실 함수를 다시 확인
  • 이 과정에서 원-핫 인코딩 학습