본문 바로가기

AI

5. 딥러닝(Keras)

Keras는 머신러닝 라이브러리 Theano와 TensorFlow를 래핑한 라이브러리이다.

 

1. 데이터셋 만들기

import tensorflow as tf
import pandas as pd, numpy as np
from tensorflow import keras

#BMI 데이터를 읽기
df = pd.read_csv("colors.csv", names = ["llc","lleb","lle"....,"colors"])

#정규화

#레이블
dataset = df.values
X = dataset[:,0:18].astype(float)
Y_obj = dataset[:,18] #마지막 19번째 칼럼 "colors"

#레이블 변환
e = LabelEncoder()
e.fit(Y_obj)
Y = e.transform(Y_obj)
Y_encoded = tf.keras.utils.to_categorical(Y)

#테스트/훈련 데이터 분리 (학습셋 70%, 테스트셋30%)
X_train, X_test, Y_train, Y_test = train_test_split(X, Y_encoded, test_size=0.1, random_state=seed)

여기까지는 이전 머신러닝과 동일하다.

 

 

2. 모델구조 정의

#모델 구조 정의
model = keras.Sequential([
    keras.layers.Dense(512, activation=tf.nn.relu),
    keras.layers.Dropout(0.25),

    keras.layers.Dense(512, activation=tf.nn.relu),
    keras.layers.Dropout(0.1),

    keras.layers.Dense(4, activation=tf.nn.softmax)
])

딥러닝의 층을 넣으며 딥러닝 모델을 만드는 코드이다.

 

Dense는 입출력을 연결해주는 층이다.

앞의 2개는 입력층이고 마지막은 출력층이다.

마지막 출력층의 경우 결과가 4가지(Spring, Summer, Fall, Winter)이므로 Dense의 unit이 4인 것이다.

 

Dense에는 활성화함수 옵션을 줄 수 있다.

활성화 함수란 어떤 값이 들어왔을 때 그 값이 어떤 임계치를 넘었는지 아닌지 판별하여 값을 다음층으로 보낼지 결정짓는 함수이다. 위에서는 ReLU와 SoftMax를 사용했다.

 

ReLu함수는 입력이 0이하면 0이고, 초과이면 입력과 동일한 함수(y=x)이다.

 

SoftMax는 큰 값은 더 크게 작은 값은 더 작게 보정하는 하여 최종 값들의 합이 1이되게 만든다. 최종 합이 1이 되서 마치 확률처럼 보이므로 출력층에 넣고 결과를 활용해서 학습에 적용한다. 

식은 e^a(k)/sigma(e^a(i)). (i=1~n) 인데 코드로 표현하면 아래와 같다

### softmax 함수
def softmax(X):
  X = X.T - np.max(X.T, axis = 0)
  return (np.exp(X)/np.sum(np.exp(X), axis=0)).T

 

학습을 하다보면 너무 훈련 데이터에 딱 맞게 학습이 되어서 테스트를 했을 때 오히려 정확도가 떨어지는 경우가 있다. 이러한 경우를 과적합이라 한다. 과적합을 막기위한 방법중 하나가 Dropout이다.

Dropout이란 훈련할 때 무작위로 몇 개의 뉴런을 사용하지 않는 방식이다. 테스트할 때는 모두 사용한다. 위 코드의 경우 1번층에서는 25%, 2번층에서는 10%의 뉴런을 사용하지 않았다.

 

 

3. 모델구축하기

#모델 구축하기
model.compile(
    loss='categorical_crossentropy',
    optimizer="rmsprop",
    metrics=['accuracy']
)

학습 결과에서 정확도가 0.55인 것과 0.99인 것은 동일하다. 왜냐하면 확률의 총합은 1이기 때문이다. 따라서 정확도로 성능을 평가하는 것은 문제가 있으므로 손실함수를 사용한다.

loss는 손실함수로 실제값과 예측값의 차이를 수치화한다. 값이 클 수록 오차가 큰 것이다.

문제 유형에 따라 회귀에서는 평균 제곱 오차(MSE), 분류에서는 크로스 엔트로피를 주로 사용하며, 결과가 이진 분류인 경우 binary_crossentropy, 결과가 여러개인 분류인 경우 categorical_crossentropy를 사용한다.

 

optimizer는 손실함수값을 줄여나가는 방법이다. 결과가 나온 후 학습성능을 올리기 위해 결과에서부터 뉴런들의 가중치를 재조정하는 역전파 과정에서 사용한다.

 

metrics는 최종적인 모델을 평가하기위한 척도이다. 위 코드에서는 정확도를 사용하였다.

 

4. 데이터 훈련

#데이터 훈련
hist = model.fit(
    x_train, y_train,
    batch_size=100,
    epochs=8,
    validation_split=0.1,
    callbacks=[tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=2)],
    verbose=1
)

딥러닝에서도 훈련함수는 fit() 이다.

 

batch_size는 훈련데이터를 나누는 크기  epochs는 학습횟수를 의미한다.

즉, 훈련 데이터들을 100개씩으로 나누고, 총 8회 학습하겠다는 의미이다.

batch_size로 데이터를 나누는 이유는 딥러닝에서 훈련데이터의 크기가 너무 크면 컴퓨터 메모리의 한계와 속도저하 때문에 학습을 하지 못할 수 있기 때문이다.

 

validation_split은 주어진 데이터를 테스트데이터와 훈련데이터를 나누는 비율이다. 0.1이므로 테스트 데이터는 10%, 훈련데이터는 90%로 나눈다.

 

callback에 EarlyStopping을 넣은 것은 과적합을 막기 위함이다. 학습과정을 감시하여 과적합이 발생했을 때 학습을 중단시킨다.

 

varbose는 학습진행상황을 보여줄 것인지 유무이다. 1은 보여준다, 0은 안보여준다 이다.

 

훈련하기

 

5. 테스트

#테스트 데이터로 평가
score = model.evaluate(x_test, y_test)
print("loss=", score[0])
print("accuracy=", score[1])

결과

 

+정규화

데이터를 딥러닝하기 전에는 정규화를 해야한다. 모든 데이터가 동일한 정도의 중요도로 반영되어야하기 때문이다. 정규화 방법은 다음과 같다.

#정규화방법1. 최소최대 정규화: x-min / max-min
df["llc"] = (df["llc"] - min(df["llc"])) / (max(df["llc"]) - min(df["llc"]))
#...생략

#정규화방법2. z점수 정규화: x-평균 / 표준편차
df["llc"] - np.mean(df["llc"]) / np.std(df["llc"])
#...생략

위에는 df["이름"]으로 하나씩 했지만 df를 for문으로 돌려서 하면 하드코딩하지 않고 할 수 있을 것이다.

 

 

 

+EarlyStopping 하면서 모델 저장

#모델 저장 폴더 설정
MODEL_DIR = './model/'
if not os.path.exists(MODEL_DIR):
    os.mkdir(MODEL_DIR)

#모델 저장 조건 설정
modelpath="./model/{epoch:02d}-{val_loss:.4f}.hdf5"
checkpointer = ModelCheckpoint(filepath=modelpath, monitor='val_loss', verbose=1, save_best_only=True) 

#학습 자동 중단 설정
early_stopping_callback = EarlyStopping(monitor='val_loss', patience=10)

#모델실행
model.fit(X_train, Y_train, validation_data=(X_test, Y_test),
          epochs=130, batch_size=5, callbacks=[early_stopping_callback, checkpointer])
          
#모델을 컴퓨터에 저장
model.save('warm.h5')

#테스트를 위해 메모리내의 모델을 삭제
del model

#모델을 새로 불러옴
model = load_model('warm.h5')

'AI' 카테고리의 다른 글

6-2. 자연어분석(베이즈정리)  (0) 2020.09.19
6-1. 자연어분석(NoMLPy, Gensim)  (0) 2020.09.17
4-2. 머신러닝(SVM, Cross Validation, GridSearch)  (0) 2020.09.11
4-1. 머신러닝  (0) 2020.09.10