페이지

2022년 7월 23일 토요일

3.4.4 훈련 검증

 훈련하는 동안 처음 데이터에 대한 모델의 정확도를 측정하기 위해서는 원본 훈련 데이터에서 10,000의 샘플을 떼어 검증 세트를 만들어야 합니다.

    x_val = x_train[:10000]

    partial_x_train = x_train[10000:]

    y_val = y_train[:10000]

    partial_y_train = y_train[10000:]

이제 모델을 512개의 샘플씩 미니 배치를 만들어 20번의 에포크 동안 훈련시킵니다(x_train과 y_train 텐서에 있는 모든 샘플에 대해 20번 반복합니다). 동시에 따로 떼어 놓은 1만 개의 샘플에서 손실과 정확도를 측정할 것입니다. 이렇게 하려면 validation_data 매개변수에 검증 데이터를 전달해야 합니다.

    modle.compile(optimizer='rmsprop',

                        loss='binary_crossentropy',

                        metrics=['acc'])

    history = model.fit(partial_x_train,

                            partial_y_train,

                            epochs=20,

                            batch_size=512,

                            validation_data=(x_val, y_val))

CPU를 사용해도 에포크마다 2초가 걸리지 않습니다. 전체 훈련은 20초 이상 걸립니다. 에포크가 끝날 때마다 1만 갱의 검증 샘플 데이터에서 손실과 정확도를 계산하기 때문에 약간씩 지연됩니다.

model.fit() 메서드는 History 객첼르 반환합니다. 이 객체는 훈련하는 동안 발생한 모든 정보를 담고 있는 딕셔너리인 history 속성을 가지고 있습니다. 한번 확인해 보죠.

>>> history_dict = history.history

>>> history_dict_.keys()

[u'acc', u'loss', u'val_acc', u'val_loss']

이 딕션너리는 훈련과 검증하는 동안 모니터링할 측정 지표당 하나씩 모두 4개의 항목을 담고 있습니다. 이어지는 두 목록에서 맷플롯립을 사용하여 훈련과 검증 데이터에 대한 손실과 정확도를 그리겠습니다. 신경망의 무작위한 초기화 때문에 독자들의 결과와 조금 다를 수 있습니다.

    import matplotlib.pyplot as plt

    history_dict = history.history

    loss = history_dict['loss']

    val_loss = history_dict['val_loss']


    epochs = range(1, len(loss) + 1)


    plt.plot(epochs, loss, 'bo', label='Training loss' ) ........ 'bo'는 파란색 점을 의미합니다.

    plt.plot(epochs, val_loss, 'b', label='Validation loss') ..... 'b'는 파란색 실선을 의미합니다.

    plt.title('Training and validation loss')

    plt.xlabel('Epochs')

    plt.ylabel('Loss')

    plt.legend()

    

    plt.show()



    plt.clf() ..............그래프를 초기화 합니다.

    acc = history_dict['acc']

    val_acc = history_dict['val_acc']

    

    plt.plot(epochs, acc, 'bo', label='Training acc')

    plt.plot(epochs, val_acc, 'b', label='Validation acc')

    plt.title('Training and validation accuracy')
    plt.xlabel('Epochs')

    plt.ylabel('Accuracy')

    plt.legend()

    plt.show()

여기에서 볼 수 있듯이 훈련 손실이 에포크마다 감소하고 훈련 정확도는 에포크마다 증가합니다. 경사 하강법 최적화를 사용했을 때 반복마다 최소화되는 것이 손실이므로 개대했던 대로 입니다. 검증 손실과 정확도는 이와 같지 않습니다. 네 번째 에포크에서 그래프가 역전되는것 같습니다. 이것이 훈련 세트에서 잘 작동하는 모델이 처음 보는 데이터에서는 잘 작동하지 않을 수 있다고 앞서 언급한 경고의 한 사례입니다. 정확한 용어로 말하면 과대적합(overfitting) 되었다고 합니다. 두 번째 에포크 이후부터 훈련 데어터에 과도하게 최적화되어 훈련 데이터에 특화된 표현을 학습하므로 훈련 세트 이외의 데이터에는 일반화되지 못합니다.

이런 경우에 과대적합을 방지하기 위해서 세 번째 에포크 이후에 훈련을 중지할 수 있ㅅ브니다. 일반적으로 4장에서 보게 될 과대적합을 완화학는 다양한 종류의 기술을 사용할 수 있습니다.

처음부터 다시 새로운 신경망을 네 번의 에포크 동안만 훈련하고 다시 테스트 데이터에서 평가해 보겠습니다.


    model = model.Sequential()

    model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))

    model.add(layers.Dense(16, activation='relu'))

    model.add(layers.Dense(1, activation='sigmoid'))

    

    model.compile(optimizer='rmsprop',

                    loss='binary_crossentropy'

                    metrics=['accuracy'])

    model.fit(x_train, y_train, epochs=4, batch_size=512)

    results = model.evaluate(x_test, y_test)

최종 결과는 다음과 같습니다.

>>> results

[0.332315458699, 0.87348]

아주 단순한 방식으로도 87%의 정확도를 달성했습니다. 최고 수준의 깁법을 사용하면 95%에 가까운 성능을 얻을 수 있습니다.

    

댓글 없음: