[SSUDA] 케라스로 다층퍼셉트론 구현하기
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from tensorflow import keras
fashion_mnist = keras.datasets.fashion_mnist
(X_train_full, y_train_full), (X_test, y_test) = fashion_mnist.load_data()
케라스 내 대표적인 예제 데이터인 fashion_mnist 데이터를 사용했습니다.
X_train_full.shape
X_test.shape
데이터는 총 7만개이고, 28행 28열 값 입니다.
X_train_full.dtype
데이터 내 0부터 255까지 픽셀값이 들어가고, 70000 28 28개로 데이터 양이 꽤 많습니다.
그러므로 메모리를 절약하기 위해 uint8 자료형을 사용합니다.
plt.imshow(X_train_full[0], cmap = 'binary')
plt.axis('off')
plt.show()
첫번째 샘플은 부츠인것 같군요.
model = keras.models.Sequential()
# Flatten은 입력데이터의 shape을 일렬로 변경하는 클래스입니다.(reshape(-1,1)과 유사)
model.add(keras.layers.Flatten(input_shape=[28,28]))
# Dence는 이전 뉴런과 완전 연결된 밀집뉴런층을 의미합니다. 뉴런 수와 활성화 함수를 정의합니다.
model.add(keras.layers.Dense(300, activation = 'relu'))
model.add(keras.layers.Dense(100, activation = 'relu'))
model.add(keras.layers.Dense(10, activation = 'softmax'))
딥러닝 모델을 케라스를 통해서 구축합니다.
분류기 모델이기 때문에 마지막 활성화 함수를 소프트멕스로 해서 0~1 사이로 값을 출력하게 합니다.
model.summary()
모델의 정보를 summary 함수를 통해서 출력했습니다.
model.layers[1].get_weights()
각 층의 있는 파라미터 값을 get_weights 함수를 이용해서 출력할 수 있습니다.
model.compile(loss = 'sparse_categorical_crossentropy', # 다중 분류 손실 함수. Y가 원핫인코딩이 아닐때
optimizer = 'sgd', # 확률적 경사 하강법 사용.
metrics = ['accuracy']) # 학습을 진행할 때 마다 출력할 평가방식.
모델을 컴파일합니다. 이때 손실함수, 옵티마이저, 테스트 셋으로 측청하는 것을 입력해줍니다.
X_valid, X_train = X_train_full[:5000] / 255.0, X_train_full[5000:] / 255.0
y_valid, y_train = y_train_full[:5000], y_train_full[5000:]
X_test = X_test/255.0
이후 출처를 밝히겠지만 인터넷 내 블로그 코드를 보고 따라했는데요. 이 부분이 중간에 생략되어있어서 많은 혼란이 있었습니다.
왜냐하면 딥러닝에서 가장 중요한 것은 X 데이터의 스케일링입니다. 한 개의 데이터당 28 * 28 = 786 개의 값이 입력됩니다.
이 786개의 값이 스케일이 물론 같지만, 0~255 값을 가지게 되면 밑에 코드의 학습이 전혀 되지 않습니다.(정확도가 계속 0.1에 머무름)
반드시! 255로 나누어줘서 X 값의 범위를 0~1로 만들어야합니다. 긴 시간 시행착오를 겪었지만 피와 살이 되는 경험이였고 잊지 않을 것 같아요.
# X_train, X_valid, y_train, y_valid = train_test_split(X_train_full, y_train_full, test_size=0.1, random_state=34)
history = model.fit(X_train, y_train, epochs = 30, # 에포크는 학습반복수
validation_data = (X_valid, y_valid))
테스트와 트레인 셋으로 나눈뒤 모델을 학습합니다. 에포크가 지날때 마다 반드시 개선되지는 않습니다.
import pandas as pd
pd.DataFrame(history.history).plot(figsize = (8,5))
plt.grid(True)
plt.gca().set_ylim(0, 1)
plt.show()
학습데이터는 에포크가 지날때마다 계속 개선이 되는것으로 보이나 val 데이터는 개선이 되었다가 감소하는걸 반복합니다.
model.evaluate(X_test, y_test)
테스트 데이터로 모델을 평가했습니다. 과적합 되지 않고 비슷한 성능을 보입니다.
X_new = X_test[:3]
y_proba = model.predict(X_new)
y_proba.round(2)
predict 함수를 이용하면 범주마다의 확률을 예측해줍니다.
y_proba.argmax(axis=-1)
이전에는 predict_classes로 범주를 뽑아낼 수 있었으나 케라스 버전 업그레이드 이후 이 함수가 사라졌습니다.
argmax 함수를 통해 가장 큰 확률을 가진 범주를 추출했습니다.
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
housing = fetch_california_housing()
X_train_full, X_test, y_train_full, y_test = train_test_split(housing.data, housing.target, random_state = 42)
X_train, X_valid, y_train, y_valid = train_test_split(X_train_full, y_train_full, random_state = 42)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_valid = scaler.transform(X_valid)
X_test = scaler.transform(X_test)
california_housing 데이터를 이용해 주택가격을 예측하는 모델을 케라스를 이용해 딥러닝으로 구현해보겠습니다.
우선 딥러닝 모델 적용시 가장 중요한 스케일링을 진행합니다. 이때 데이터 리키지가 일어나는것 항상 조심해야겠죠.
model = keras.models.Sequential([
keras.layers.Dense(30, activation = 'relu', input_shape = X_train.shape[1:]),
keras.layers.Dense(1)
])
model.compile(loss = 'mean_squared_error', optimizer = keras.optimizers.SGD(lr = 1e-3))
history = model.fit(X_train, y_train, epochs = 20, validation_data =(X_valid, y_valid))
우선 회귀모델이니 마지막 층에 소프트맥스 같은 활성화함수는 필요하지 않습니다. 또 손실함수는 MSE를 사용하였네요.
mse_test = model.evaluate(X_test, y_test)
테스트 데이터로 모델을 평가했는데, 로스값이 더 좋은 모습입니다.
X_new = X_test[:3]
model.predict(X_new)
모델을 이용해 새 데이터를 예측했습니다.
plt.plot(pd.DataFrame(history.history))
plt.grid(True)
plt.gca().set_ylim(0,1)
plt.show()
에포크가 진행될수록 트레인 데이터의 mse는 감소합니다. 하지만 valid 데이터는 일정수준이상이 되면 진동합니다.
머신러닝의 다른 모델들과 다르게 신경망은 매우 많은 하이퍼 파라미터가 있습니다.
예시로 배치 사이즈, 옵티마이저, 학습률, 은닉층의 수, 활성화함수, loss, 드롭아웃 등 많습니다.
우선 배치 사이즈의 경우 크면 메모리 문제가 많이 생깁니다. 또 훈련 초기 종종 불안정하기 훈련되기도 합니다.
만약 너무 작으면 학습시간이 오래걸리고 노이즈도 커지는데요. gpu를 사용하기 때문에 2의 제곱수를 많이 사용합니다.(주로 32)
이 부분은 의견이 많이 갈리기도 하는 부분이에요.
다음은 옵티마이저 입니다. 간단하게 사진으로 대체했는데 사실 정확히 이해하기 힘듭니다. 따로 시간내서 공부해야합니다.
일반적으로 Adam이 성능이 좋다고 합니다.
학습률은 디폴트가 0.01으로 크면 발산하고 작으면 지역 최저점에 머물 확률이 높아요. 옵티마이저 내부옵션으로도 사용됩니다.
활성화함수는 은닉층에서 주로 Relu를 주로 사용합니다. 모델에 따라 tanh등을 쓰기도 합니다.
은닉층은 많아지면 학습시간 문제, 과적합 문제가 많이 생깁니다.
이번엔 텐서플로우 내 케라스라는 패키지를 이용해 딥러닝을 간단히 맛보았습니다.
케라스는 고수준 패키지로 쉽게 사용할 수 있으나 세밀한 작업은 하지 못하는데요.
간단한 예제 데이터를 통해 딥러닝이라는 것을 해봤습니다. 오늘 느낀것은 공부할 것이 참 많겠다 생각이 들었어요.
계속 발전하는 분야라서 인터넷 글마다 정보도 다르고 한데, 저도 발전되는 그 곳에 함께하고 싶네요.
더 열의를 다지는 시간이였던것 같아요.