코딩뚠뚠

[머신러닝 공부] K-Fold Cross Validation 이란 본문

공부/ML&DL

[머신러닝 공부] K-Fold Cross Validation 이란

로디네로 2021. 4. 18. 01:23
반응형

 

 

개요 : 

 

딥러닝 모델을 Training 할 때 Train Data를 Train set 과 Validation set 으로 나눠줄 필요가 있다.

 

Keras를 이용할 때에는 validation_split 으로 나눠줄 수 있었다.

 

keras.preprocessing.image.ImageDataGenerator (validation_split=0.7, .... etc ....)

 

하지만 augmentation을 하더라도 기본 데이터가 다소 적을 때 validation_split은 Train Data 전부를 사용하지 못했다.

Keras의 validation_split은 random으로 선택하지 않는 단점도 있다.

sklearn의 train_test_split() 은 random으로 validation set을 선택하지만 이또한 validation에 사용하는 데이터를 train에 사용할 수는 없다는 단점이 존재했다 (trainDB가 적을경우)

sklearn의 train_test_split에서 train, validation 나누기

 

이에 K-Fold Cross Validation을 사용하면 이의 단점을 해결할 수 있다는 것을 알게되었다.

 

 

 


 

K-Fold Cross Validation

 

정의 :

K 개의 Fold를 만들어 진행하는 교차검증

 

 

의의 : 

DB 갯수가 적을 시 정확도 향상 가능 (위에 언급한 방법들과 비교하여)

 

 

과정 : 

  1. Training set과 Test set을 나눈다.
  2. Training set에 대해 이를 K개의 Fold로 나눈다. 위의 그림에서는 5개로 나누었다.
  3. 한 Fold의 데이터들을 다시 K개로 쪼갠 뒤 K-1개는 Training Data, 1개는 Validation Data로 지정한다.
  4. 모델을 생성후 prediction을 진행하여 에러값을 추출한다.
  5. 다음 Fold에서는 Validation Data를 바꾸어 진행한다.
  6. 이를 모든 Fold에 대해 진행한다.
  7. 추출한 에러값을 바탕으로 최적의 모델을 찾는다.
  8. 해당 조건을 바탕으로 전체 Training set의 학습을 진행한다.
  9. 해당 조건의 Test set으로 평가한다.

 


 

Tensorflow+Keras 이용한 예시코드 : 

codes from : www.machinecurve.com/index.php/2020/02/18/how-to-use-k-fold-cross-validation-with-keras/?

from tensorflow.keras.datasets import cifar10
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, Conv2D, MaxPooling2D
from tensorflow.keras.losses import sparse_categorical_crossentropy
from tensorflow.keras.optimizers import Adam
from sklearn.model_selection import KFold
import numpy as np

# Merge inputs and targets
inputs = np.concatenate((input_train, input_test), axis=0)
targets = np.concatenate((target_train, target_test), axis=0)

# Define the K-fold Cross Validator
kfold = KFold(n_splits=num_folds, shuffle=True)

# K-fold Cross Validation model evaluation
fold_no = 1

# 아래 부분에서 kfold가 아니라면 for문이 돌아갈필요가 없을것이다.

for train, test in kfold.split(inputs, targets):

  # Define the model architecture
  model = Sequential()
  model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))
  model.add(MaxPooling2D(pool_size=(2, 2)))
  model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
  model.add(MaxPooling2D(pool_size=(2, 2)))
  model.add(Flatten())
  model.add(Dense(256, activation='relu'))
  model.add(Dense(128, activation='relu'))
  model.add(Dense(no_classes, activation='softmax'))

  # Compile the model
  model.compile(loss=loss_function,
                optimizer=optimizer,
                metrics=['accuracy'])


  # Generate a print
  print('------------------------------------------------------------------------')
  print(f'Training for fold {fold_no} ...')

  # Fit data to model
  history = model.fit(inputs[train], targets[train],
              batch_size=batch_size,
              epochs=no_epochs,
              verbose=verbosity)

  # Generate generalization metrics
  scores = model.evaluate(inputs[test], targets[test], verbose=0)
  print(f'Score for fold {fold_no}: {model.metrics_names[0]} of {scores[0]}; {model.metrics_names[1]} of {scores[1]*100}%')
  acc_per_fold.append(scores[1] * 100)
  loss_per_fold.append(scores[0])

  # Increase fold number
  fold_no = fold_no + 1

 

 

 

 

 

 

반응형