본문 바로가기
프로그램/SKT FLY AI

SKT FLY AI : 6일차 - ML(2)

by hsloth 2023. 7. 4.

ML구조의 의미

Data

  • 학습시키기 위한 데이터. 이 데이터가 모델에 들어가서 Feature들을 뽑아내고, 이 Feature들을 기반으로 result를 뽑아낸다.
  • 데이터가 생성되고, 데이터에 Transform 변형을 준다거나 모델에 들어가기 전에 데이터 전처리가 들어감
  • 이 때 들어갈 때는 Batch로 만들어서 Model에 넣어줌

Model

  • LeNet, AlexNet, VGG나 ResNet 등 다양하게 설계된 모델
  • Convolution Layer, Pooling등 다양한 Layer층들로 구성
  • 이 모델안에 학습 파라미터가 있고, 이 모델이 학습하는 대상

Prediction / Logit

  • [0.15, 0.3, 0.2, 0.25, 0.1]
  • 각 class 별로 예측한 값
  • 여기서 가장 높은 값이 모델이 예상하는 class또는 정답
  • [0.0, 0.0, 0.0, 1.0, 0.0]
  • 위의 숫자가 정답이라고 할 때, 얼마나 틀렸는지 얼마나 맞았는지 확인 가능

Loss / Cost

  • 예측한 값과 정답을 비교해서 얼마나 틀렸는지를 확인
  • Cross Entropy 등 다양한 Loss Function들이 있음
  • 이 때, 계산을 통해 나오는 값이 Loss(Cost, Cost Value 등)라고 불림
  • 이 Loss는 얼마나 틀렸는지를 말하며 이 값을 최대한 줄이는 것이 학습의 과정

Optimization

  • 앞에서 얻은 Loss값을 최소화하기 위해 기울기를 받아 최적화된 Variable 값들로 반환
  • 이 반환된 값이 적용된 모델은 바로 전에 돌렸을 때의 결과보다 더 나아지게 됨
  • 이 때 바로 최적화된 값만큼 바로 움직이는 것이 아닌 Learning Rate만큼 움직인 값이 적용된다.

Result

  • 평가할 때 또는 예측된 결과를 확인할 때는 예측된 값에서 argmax를 통해 가장 높은 값을 예측한 class라고 둠
  • [0.15, 0.3, 0.2, 0.25, 0.1]
  • 위의 예측값에서는 0.3가 제일 높은 값이므로 클래스 2가 가장 높다고 봄(파이썬에서는 0으로 시작)

용어정리

  • Activation Function : 은닉층을 활성화시키기 위한 함수. 가중치와 bias를 갱신하는데 사용된다.

    • 입력신호의 총합을 출력신호로 변환하는 함수. 입력신호의 총합이 활성화를 일으킬지 결정하는 함수.
  • loss function : 실제값과 예측한 값의 차이를 비교하기 위한 함수. 손실함수의 종류에 따라 차이가 나는 정도를 다르게 판단함.

    • 회귀 예측 : MSE
    • 이진 분리 : 이진 교차 엔트로피
    • 다중 분류 : 범주형 교차 엔트로피
  • Learning Rate

  • Batch Size : 전체 트레이닝 데이터 셋을 여러 작은 그룹을 나누었을 때 batch size는 하나의 소그룹에 속하는 데이터 수를 의미

    • 전체 트레이닝 셋을 작게 나누는 이유 : 트레이닝 데이터를 통째로 신경망에 넣으면 비효율적인 리소스 사용으로 학습시간이 오래 걸리기 때문
  • epoch : 전체 트레이닝 셋이 신경망을 통과한 횟수를 의미

    • 1-epoch는 전체 트레이닝 셋이 하나의 신경망에 적용되어 순전파와 역전파를 통해 신경망을 한 번 통과했다는 것
  • Data set을 Train set과 Test set으로 나누고, 거기서 Train set을 Train set과 Validation set으로 나눈다.

    • Training을 한 후에 모델의 성능을 평가하기 위해서 Validation set이 사용된다.
    • Test set은 최종 평가를 위해서 사용되는 데이터. Validation set은 중간 평가(모델 수정)를 위해서 사용되는 데이터. 라고 생각하면 될듯.

심층 신경망(Deep Neural Network)

  • 입력층과 출력층 사이에 여러 개의 은닉층들로 이루어진 인공신경망
  • 복잡한 비선형 관계들을 모델링
  • Input layer : 네트워크의 입력 부분으로, 학습시키고 싶은 x값
  • Hidden layers : 입력층과 출력층을 제외한 중간층, 은닉층은 완전연결 계층(Fully connected layer = Dense layer)
  • Output layer : 네트워크의 출력 부분으로, 예측한 값, 즉 y값
  • 과적합(Overfitting) : 학습데이터에 맞춰 최적화되어 전체 특성에서 벗어나는 문제
  • 오차 역전파 : 순전파와는 반대로 출력층에서 입력층 방향으로 계산하면서 가중치를 업데이트
  • 경사하강법 : 함수의 기울기를 구하여 기울기가 낮은 쪽으로 계속 이동시켜서 극값에 이를 때까지 반복 시키는 것
  • 손실함수 : 가중치에 따라 오차가 얼마나 커지거나 작아지는지를 평가
    • 평균 제곱오차(MSE)
    • 교차 엔트로피 함수
  • 경사도 소실 문제 : 여러 은닉 계층으로 구성되어 활성화 함수에 따라 경사도 소실이 발생할 수 있음
    • 실제 값과 추정 값과의 차이를 나타내며 회귀 문제에 사용됨

DNN 구현 단계

  • DNN 구현 단계 -> Dense Module -> Dropout

DNN 구현 단계

  1. 기본 파리미터 설정
  2. 분류, 회귀 DNN 모델 구현
  3. 데이터 준비
  4. DNN 학습 및 평가

Dense Module

  1. Neural Network를 구성하는 LAyer를 생성할 때 사용
    • model.add(Dense(1, input_di=3, activation='relu'))
    • 첫번째 인자 : 출력 노드의 수 (1)
    • input_dim : 입력 노드의 수(입력의 차원)
    • activation : 활성화 함수

Dropout

  1. 일부의 노드를 생략한 후에 학습을 진행

1. ANN

  • 분류 ANN : 입력 정보를 클래스 별로 분류하는 방식
  • 회귀 ANN : 입력 정보로 다른 값을 예측하는 방식

분류 ANN

  • 입력 정보를 바탕으로 해당 입력이 어느 클래스에 속하는 지를 결정
  • 판별은 두 출력 노드의 값을 비교하여 더 큰 쪽을 선택하도록 구현
  • 가중치의 학습은 예측값의 목표값에 대한 오차를 역방향으로 되돌리면서 이루어지기 때문에 오차역전파
    • 오차역전파 : 오차를 줄이는 경사 하강법에서 유도된 방법
    • 겅사 하강법 : 가중치에 대한 손실 함수를 미분하고, 그 미분 값의 방향과 크기를 활용해 가중치를 보상하는 방법
  • 손실함수 : 가중치에 따라 오차가 얼마나 커지거나 작아지는 지를 평가
  • 손실함수로 교차 엔트로피를 주로 사용 -> 이를 적용하려면 출력 노드의 결과를 확률값으로 바꿔야 함
  • 확률값은 출력 노드 값을 소프트맥스 연산으로 구함

회귀 ANN

  • 입력 값으로부터 출력 값을 직접 예측하는 방법
  • 실제 데이터의 규칙을 잘 표현하는 함수를 찾는 것이 회귀
  • 오차역전파 방법으로 학습시키려면 주로 MSE를 손실함수로 주로 사용
  • 학습에 의한 최적화 방법으로 확률적 경사 하강법을 많이 사용했으나 최근에는 더 발전된 방법인 Adam, Adagard, RMSprop등과 같은 방법을 사용
    • Adam : 경사의 분산과 평균으로부터 파라미터를 업데이트하는 적응 알고리즘
    • Adagrad : 밀집되지 않은 데이터에 적합하도록 경사 제곱을 통해 시간에 따라 학습률을 조정하는 적응 알고리즘
    • RMSprop : 학습률이 급격히 떨어지지 않게 감쇠 항(=정규항인듯?)을 추가한 적응 알고리즘

하나 알아가는 점

  • 데이터 스케일링 시, 정수형 변수는 스케일링이 되지 않는다.
  • 정수형 변수는 범주형 데이터로 보고, 실수형 변수는 연속형 데이터로 본다.
  • 연속형 변수에는 선형회귀를 사용하면 된다. 범주형 변수는 로지스틱 회귀분석을 이용한다.

이진 분류를 해보자.

  • 당뇨 데이터로 당뇨에 걸릴 가능성을 예측해보자.
### 1. 데이터 불러오기
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, precision_score, recall_score, roc_auc_score
from sklearn.metrics import f1_score, confusion_matrix, precision_recall_curve, roc_curve
from sklearn.preprocessing import StandardScaler, Binarizer
from sklearn.linear_model import LogisticRegression

import warnings
warnings.filterwarnings('ignore')

diabetes = pd.read_csv('./diabetes.csv')
print(diabetes['Outcome'].value_counts())
diabetes.head(5)

### 2. 정보확인
diabetes.info()

### 3. 결측치 확인 및 처리
diabetes.isnull().sum()

### 사용할 칼럼 추출
cols = ["Glucose", "BloodPressure", "SkinThickness", "Insulin", "BMI"]
(diabetes[cols]==0).sum(axis=0)

print(diabetes[cols])

### 4. 데이터 시각화
import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize=(8,6))
sns.countplot(x='Outcome', data=diabetes)
plt.show()

### 5. 범주별 데이터 수
diabetes['Outcome'].value_counts()

### 6. 특성과 레이블 분리
X_data = diabetes.drop(['Outcome'], axis=1)
X_data.head()

y_data = diabetes['Outcome']
y_data.head()

### 7. 테스트 데이터 분리
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size=0.2, random_state=42)

print(X_train.shape, X_test.shape)
print(y_train.shape, y_test.shape)

# 이상치 처리
import numpy as np

def impute_zero(data, col):
  df = data.loc[data[col] != 0, col]
  avg = np.sum(df)/len(df)
  k = len(data.loc[data[col] == 0, col])
  data.loc[data[col]==0, col] = avg
  print('%s : fixed %d, mean : %.3f' %(col, k, avg))

for col in cols:
  impute_zero(X_train, col)

# 이상치 확인
(X_train[cols] == 0).sum(axis=0)

# 테스트 데이터의 이상치 처리
for col in cols:
  impute_zero(X_test, col)

### 8. 테스트 정규화
# 표준 정규화
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train)
X_test_s = scaler.transform(X_test)

print(X_train_s[:5])

### 9. 넘파이 배열로 타입 변경
y_train = y_train.values
y_test = y_test.values

print(type(y_train), type(y_test))

### 10. 모델 만들기
from keras.layers.rnn.lstm_v1 import activations

from tensorflow import keras
from tensorflow.keras import layers

# Dense는 layer를 쌓는 것

def build_model():
  model = keras.Sequential()
  model.add(layers.Dense(12, input_dim=8, activation='relu'))
  model.add(layers.Dense(8, activation='relu'))
  model.add(layers.Dense(1, activation='sigmoid'))
  return model

model = build_model()
model.summary()

### 11. 모델 컴파일
model.compile(loss="binary_crossentropy",
              optimizer = 'adam', # adam으로 gradient를 조절하겠다라는 의미
              metrics=['acc'])

### 12. 모델 학습
EPOCHS = 500  # 500개로 실행. 시간상 100으로 했음.
BATCH_SIZE = 16
history = model.fit(X_train_s, y_train, epochs = EPOCHS,
                    batch_size = BATCH_SIZE,
                    validation_split = .2,  # 0.2는 validation set으로 사용
                    verbose = 1)

### 13. 학습곡선
import matplotlib.pyplot as plt

def plot_history(history):
  hist = pd.DataFrame(history.history)
  hist['epoch'] = history.epoch

  plt.figure(figsize=(16,8))
  plt.subplot(1,2,1)
  plt.xlabel('Epoch')
  plt.ylabel('Loss')
  plt.plot(hist['epoch'], hist['loss'], label='Train Loss')
  plt.plot(hist['epoch'], hist['val_loss'], label='Val Loss')
  plt.legend()

  plt.subplot(1,2,2)
  plt.xlabel('Epoch')
  plt.ylabel('Accuracy')
  plt.plot(hist['epoch'], hist['acc'], label='Train Accuracy')
  plt.plot(hist['epoch'], hist['val_acc'], label='Val Accuracy')
  plt.legend()

  plt.show()

plot_history(history)



###############################33
### 1. 모델 생성과 컴파일
from keras.layers.rnn.lstm_v1 import activations

from tensorflow import keras
from tensorflow.keras import layers


# Dense의 첫번째 인자 = 출력 뉴런의 수. input_dim = 입력 뉴런의 수
# Dense레이어는 출력층으로 많이 사용된다.

def build_model():
  model = keras.Sequential()
  model.add(layers.Dense(12, input_dim=8, activation='relu')) # 입력값이 8개, 출력값이 12개인 은닉층으로 사용되는 Dense레이어
  model.add(layers.Dense(8, activation='relu'))
  model.add(layers.Dense(1, activation='sigmoid'))
  return model

model = build_model()
model.compile(loss='binary_crossentropy', # 최적화에 사용되는 목적 함수
              optimizer='adam', # 최적화 알고리즘 설정
              metrics=['acc'])  # 평가지표

# 정보확인. callback함수로 early stop 설정
diabetes.info()
early_stop = keras.callbacks.EarlyStopping(
    monitor='val_loss', patience=10)

# 데이터 스케일링
from sklearn.preprocessing import MinMaxScaler

sc=MinMaxScaler()
X_train_mm = sc.fit_transform(X_train)
X_test_mm = sc.transform(X_test)

print(type(y_train), type(y_test))

# 학습
EPOCHS = 500
BATCH_SIZE=16
history = model.fit(X_train_mm, y_train,
                    epochs=EPOCHS,
                    batch_size=BATCH_SIZE,
                    validation_split=0.2,
                    callbacks=[early_stop],
                    verbose=1)

# 학습 곡선 그리기
import matplotlib.pyplot as plt

def plot_history(history):
  hist = pd.DataFrame(history.history)
  hist['epoch'] = history.epoch

  plt.figure(figsize=(16,8))
  plt.subplot(1,2,1)
  plt.xlabel('Epoch')
  plt.ylabel('Loss')
  plt.plot(hist['epoch'], hist['loss'], label='Train Loss')
  plt.plot(hist['epoch'], hist['val_loss'], label='Val Loss')
  plt.legend()

  plt.subplot(1,2,2)
  plt.xlabel('Epoch')
  plt.ylabel('Accuracy')
  plt.plot(hist['epoch'], hist['acc'], label='Train Accuracy')
  plt.plot(hist['epoch'], hist['val_acc'], label='Val Accuracy')
  plt.legend()

  plt.show()

plot_history(history)

머신러닝 학습 방법

  1. 데이터세트 가져오기
  2. 간단한 선형 모델 구축하기
  3. 모델 훈련하기
  4. 모델의 효과 평가하기
  5. 훈련된 모델을 사용하여 예측하기

'프로그램 > SKT FLY AI' 카테고리의 다른 글

SKT FLY AI : 8일차 - CNN(2)  (0) 2023.07.05
SKT FLY AI : 7일차 - CNN  (0) 2023.07.04
SKT FLY AI - 번외. 첫날~워크샵  (0) 2023.07.01
SKT FLY AI : 5일차 - ML  (0) 2023.06.30
SKT FLY AI : 2일차 - 실습  (0) 2023.06.27