Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/ko/hub/tutorials/tf2_text_classification.ipynb
25118 views
Kernel: Python 3

Licensed under the Apache License, Version 2.0 (the "License");

# Copyright 2019 The TensorFlow Hub Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ==============================================================================
#@title MIT License # # Copyright (c) 2017 François Chollet # IGNORE_COPYRIGHT: cleared by OSS licensing # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE.

영화 리뷰에서 텍스트 분류

이 노트북은 리뷰의 텍스트를 사용하여 영화 리뷰를 긍정적 또는 부정적으로 분류합니다. 이진 또는 2-클래스 분류인 이 예는 광범위하게 적용할 수 있는 중요한 머신러닝의 응용 사례입니다.

인터넷 영화 데이터베이스에서 가져온 50,000개의 영화 리뷰 텍스트를 포함한 IMDB 데이터세트를 사용합니다. 이 데이터세트는 훈련을 위한 25,000개 리뷰와 테스트를 위한 25,000개 리뷰로 나뉩니다. 훈련 및 테스트 세트는 균형적으로, 긍정적 리뷰와 부정적 리뷰의 수가 동일하게 포함되어 있습니다.

이 노트북은 높은 수준의 API인 tf.keras를 사용하여 TensorFlow에서 모델을 빌드 및 훈련하고, 전이 학습을 위한 라이브러리 및 플랫폼인 TensorFlow Hub를 사용합니다. tf.keras를 사용하는 한 단계 더 나아간 텍스트 분류 튜토리얼은 MLCC 텍스트 분류 가이드를 참조하세요.

더 많은 모델

여기에서 텍스트 임베딩을 생성하는 데 사용할 수 있는 보다 표현력이 있거나 성능이 뛰어난 모델을 찾을 수 있습니다.

!pip install -U tf-hub-nightly
import tensorflow_hub as hub

from tensorflow.keras import layers

import numpy as np import tensorflow as tf import tensorflow_hub as hub import tensorflow_datasets as tfds import matplotlib.pyplot as plt print("Version: ", tf.__version__) print("Eager mode: ", tf.executing_eagerly()) print("Hub version: ", hub.__version__) print("GPU is", "available" if tf.config.list_physical_devices('GPU') else "NOT AVAILABLE")

IMDb 데이터세트 다운로드하기

IMDB 데이터세트는 TensorFlow 데이터세트에서 사용할 수 있습니다. 다음 코드를 이용해 IMDB 데이터세트를 사용자 머신(또는 colab 런타임)으로 다운로드합니다.

train_data, test_data = tfds.load(name="imdb_reviews", split=["train", "test"], batch_size=-1, as_supervised=True) train_examples, train_labels = tfds.as_numpy(train_data) test_examples, test_labels = tfds.as_numpy(test_data)

데이터 살펴보기

잠시 데이터 형식에 대해 알아보겠습니다. 각 예는 영화 리뷰와 해당 레이블을 나타내는 문장입니다. 문장은 어떤 식으로든 전처리되지 않습니다. 레이블은 0 또는 1의 정수 값입니다. 여기서 0은 부정적인 리뷰이고 1은 긍정적인 리뷰입니다.

print("Training entries: {}, test entries: {}".format(len(train_examples), len(test_examples)))

처음 10개의 예를 인쇄하겠습니다.

train_examples[:10]

처음 10개의 레이블도 인쇄하겠습니다.

train_labels[:10]

모델 구성하기

신경망은 레이어를 쌓아서 생성됩니다. 이를 위해서는 세 가지 주요 아키텍처 결정이 필요합니다.

  • 텍스트를 표현하는 방법은?

  • 모델에서 사용할 레이어의 수는?

  • 각 레이어에 사용할 숨겨진 단위는 몇 개입니까?

이 예에서 입력 데이터는 문장으로 구성됩니다. 예측할 레이블은 0 또는 1입니다.

텍스트를 표현하는 한 가지 방법은 문장을 임베딩 벡터로 변환하는 것입니다. 사전 훈련된 텍스트 임베딩을 첫 번째 레이어로 사용할 수 있으며, 여기에는 두 가지 이점이 있습니다.

  • 텍스트 전처리에 대해 걱정할 필요가 없습니다.

  • 전이 학습의 이점을 누릴 수 있습니다.

이 예에서는 google/nnlm-en-dim50/2라고 하는 TensorFlow Hub의 모델을 사용합니다.

이 튜토리얼을 위해 테스트할 다른 두 가지 모델이 있습니다.

먼저 TensorFlow Hub 모델을 사용하여 문장을 포함하는 Keras 레이어를 만들고 몇 가지 입력 예에서 사용해 보겠습니다. 생성된 임베딩의 출력 형상은 (num_examples, embedding_dimension)으로 예상됩니다.

model = "https://tfhub.dev/google/nnlm-en-dim50/2" hub_layer = hub.KerasLayer(model, input_shape=[], dtype=tf.string, trainable=True) hub_layer(train_examples[:3])

이제 전체 모델을 빌드하겠습니다.

model = tf.keras.Sequential() model.add(hub_layer) model.add(tf.keras.layers.Dense(16, activation='relu')) model.add(tf.keras.layers.Dense(1)) model.summary()

순서대로 층을 쌓아 분류기를 만듭니다:

  1. 첫 번째 레이어는 TensorFlow Hub 레이어입니다. 이 레이어는 사전 훈련된 저장된 모델을 사용하여 문장을 임베딩 벡터에 매핑합니다. 여기서 사용하는 모델(google/nnlm-en-dim50/2)은 문장을 여러 토큰으로 분할하고 각 토큰을 포함한 다음 임베딩을 결합합니다. 결과적인 차원은 (num_examples, embedding_dimension)입니다.

  2. 이 고정 길이 출력 벡터는 16개의 숨겨진 단위가 있는 완전 연결된(Dense) 레이어를 통해 파이핑됩니다.

  3. 마지막 레이어는 단일 출력 노드와 조밀하게 연결됩니다. 여기서 모델에 따라 실제 클래스의 로그 확률인 로짓이 출력됩니다.

숨겨진 단위

위의 모델에는 입력과 출력 사이에 두 개의 중간 또는 "숨겨진" 레이어가 있습니다. 출력(단위, 노드 또는 뉴런)의 수는 레이어에 대한 표현 공간의 차원입니다. 즉, 내부 표현을 학습할 때 네트워크에서 허용되는 자유의 정도입니다.

모델에 더 많은 숨겨진 단위(고차원 표현 공간) 및/또는 더 많은 레이어가 있는 경우, 네트워크는 더 복잡한 표현을 학습할 수 있습니다. 그러나 이로 인해 계산 측면에서 네트워크의 비용 부담이 증가하고, 원치 않는 패턴(훈련 데이터에서는 성능을 향상하지만 테스트 데이터에서는 그렇지 않은 패턴)을 학습하게 됩니다. 이를 과대적합이라고 하며 나중에 살펴보겠습니다.

손실 기능 및 옵티마이저

모델에는 훈련을 위한 손실 함수와 옵티마이저가 필요합니다. 이진 분류 문제이고 모델이 확률(시그모이드 활성화가 있는 단일 단위 레이어)을 출력하므로 binary_crossentropy 손실 함수를 사용합니다.

손실 함수에 이 선택만 가능한 것은 아닙니다. 예를 들어 mean_squared_error를 선택할 수 있습니다. 그러나 일반적으로 binary_crossentropy가 확률을 처리하기에는 더 적합합니다. 즉, 확률 분포 간 또는 이 경우에는 실제 분포와 예측 간의 "거리"를 측정합니다.

나중에 회귀 문제(예: 주택 가격 예측)를 알아볼 때 평균 제곱 오차라고 하는 또 다른 손실 함수의 사용 방법을 살펴볼 것입니다.

이제 옵티마이저와 손실 함수를 사용하도록 모델을 구성합니다.

model.compile(optimizer='adam', loss=tf.losses.BinaryCrossentropy(from_logits=True), metrics=[tf.metrics.BinaryAccuracy(threshold=0.0, name='accuracy')])

검증 세트 만들기

훈련할 때 이전에 입력된 적이 없는 데이터에 대한 모델의 정확성을 확인하려고 합니다. 원본 훈련 데이터에서 10,000개의 예제를 구분하여 검증 세트를 만듭니다. 왜 지금 테스트 세트를 사용하지 않을까요? 훈련 데이터만 사용하여 모델을 개발하고 조정한 다음 테스트 데이터를 한 번만 사용하여 정확성을 평가하는 것이 목적이기 때문입니다.

x_val = train_examples[:10000] partial_x_train = train_examples[10000:] y_val = train_labels[:10000] partial_y_train = train_labels[10000:]

모델 훈련하기

512개 샘플의 미니 배치에서 40개 epoch 동안 모델을 훈련합니다. 이 동작은 x_trainy_train 텐서의 모든 샘플에 대한 40회 반복에 해당합니다. 훈련하는 동안 검증 세트의 10,000개 샘플에서 모델의 손실과 정확도를 모니터링합니다.

history = model.fit(partial_x_train, partial_y_train, epochs=40, batch_size=512, validation_data=(x_val, y_val), verbose=1)

모델 평가하기

그리고 모델이 어떤 성능을 보이는지 알아보겠습니다. 손실(오류를 나타내는 숫자, 값이 낮을수록 좋음) 및 정확성의 두 가지 값이 반환됩니다.

results = model.evaluate(test_examples, test_labels) print(results)

상당히 단순한 이 접근 방식으로 약 87%의 정확도가 얻어집니다. 더 발전된 방식을 이용하면 모델이 95%에 근접합니다.

시간 경과에 따른 정확도 및 손실 그래프 생성하기

model.fit()History 객체를 반환합니다. 여기에는 훈련하는 동안 일어난 모든 정보가 담긴 딕셔너리(dictionary)가 들어 있습니다:

history_dict = history.history history_dict.keys()

4개의 항목이 있습니다. 훈련 및 검증 중에 모니터링되는 각 메트릭에 대해 하나씩 있습니다. 이들 항목을 사용하여 비교를 위한 훈련 및 검증 손실과 훈련 및 검증 정확성을 플롯할 수 있습니다.

acc = history_dict['accuracy'] val_acc = history_dict['val_accuracy'] loss = history_dict['loss'] val_loss = history_dict['val_loss'] epochs = range(1, len(acc) + 1) # "bo" is for "blue dot" plt.plot(epochs, loss, 'bo', label='Training loss') # b is for "solid blue line" plt.plot(epochs, val_loss, 'b', label='Validation loss') plt.title('Training and validation loss') plt.xlabel('Epochs') plt.ylabel('Loss') plt.legend() plt.show()
plt.clf() # clear figure 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()

이 그래프에서 점선은 훈련 손실과 훈련 정확도를 나타냅니다. 실선은 검증 손실과 검증 정확도입니다.

훈련 손실은 에포크마다 감소하고 훈련 정확도는 증가한다는 것을 주목하세요. 경사 하강법 최적화를 사용할 때 볼 수 있는 현상입니다. 매 반복마다 최적화 대상의 값을 최소화합니다.

약 20개 epoch 후에 최대치에 도달하는 검증 손실 및 정확도의 경우에는 그렇지 않습니다. 이것은 과대적합의 예입니다. 즉, 모델은 이전에 입력된 적이 없는 데이터보다 훈련 데이터에서 더 우수한 성능을 나타냅니다. 이 시점 이후 모델은 테스트 데이터로 일반화되지 않는 훈련 데이터에 특정한 표현을 과도하게 최적화하고 학습합니다.

이 특별한 경우에는 단순히 약 20개 epoch 후에 훈련을 중단함으로써 과대적합을 방지할 수 있습니다. 나중에 콜백을 사용하여 이 작업을 자동으로 수행하는 방법을 살펴보겠습니다.