tf.contrib.learn 시작하기

(v1.0)

텐서플로우의 고수준 머신러닝 API(tf.contrib.learn)는 다양한 머신러닝 모델을 쉽게 설정하고, 훈련하고, 평가할 수 있도록 해줍니다. 이 튜토리얼에서는 tf.contrib.learn 을 사용하여 신경망 분류기를 만들고, Iris 데이터셋에 있는 꽃받침과 꽃잎의 정보를 이용하여 꽃의 종류를 예측할 수 있도록 분류기를 훈련시킬 것입니다. 코드는 다음의 다섯 단계로 수행됩니다:

  1. Iris 훈련/테스트 데이터를 담은 CSV 파일을 텐서플로우 Dataset으로 불러옵니다.
  2. 신경망 분류기를 만듭니다.
  3. 훈련 데이터를 이용하여 모델을 훈련 시킵니다.
  4. 모델의 정확도를 평가합니다.
  5. 새로운 표본을 분류합니다.

참고: 이 튜토리얼을 시작하기 전에 텐서플로우를 설치해야 합니다.

시작하기

다음은 이 신경망 분류기의 전체 코드입니다:

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf
import numpy as np

# 데이터셋
IRIS_TRAINING = "iris_training.csv"
IRIS_TEST = "iris_test.csv"

# 데이터셋을 불러옵니다.
training_set = tf.contrib.learn.datasets.base.load_csv_with_header(
    filename=IRIS_TRAINING,
    target_dtype=np.int,
    features_dtype=np.float32)
test_set = tf.contrib.learn.datasets.base.load_csv_with_header(
    filename=IRIS_TEST,
    target_dtype=np.int,
    features_dtype=np.float32)

# 모든 특성이 실수값을 가지고 있다고 지정합니다
feature_columns = [tf.contrib.layers.real_valued_column("", dimension=4)]

# 10, 20, 10개의 유닛을 가진 3층 DNN를 만듭니다
classifier = tf.contrib.learn.DNNClassifier(feature_columns=feature_columns,
                                            hidden_units=[10, 20, 10],
                                            n_classes=3,
                                            model_dir="/tmp/iris_model")

# 모델을 학습시킵니다.
classifier.fit(x=training_set.data,
               y=training_set.target,
               steps=2000)

# 정확도를 평가합니다.
accuracy_score = classifier.evaluate(x=test_set.data,
                                     y=test_set.target)["accuracy"]
print('정확도: {0:f}'.format(accuracy_score))

# 새로운 두 개의 꽃 표본을 분류합니다.
new_samples = np.array(
    [[6.4, 3.2, 4.5, 1.5], [5.8, 3.1, 5.0, 1.7]], dtype=float)
y = list(classifier.predict(new_samples, as_iterable=True))
print ('예측: {}'.format(str(y)))

다음에서 이 코드를 자세하게 살펴 보겠습니다.

Iris CSV 데이터를 텐서플로우로 불러오기

Iris 데이터셋은 Iris 품종인 Iris setosa, Iris virginica, Iris versicolor가 각각 50개씩의 표본으로 구성된 150개의 행을 가진 데이터입니다.

Petal geometry compared for three iris species: Iris setosa, Iris virginica,
and Iris versicolor 왼쪽에서 오른쪽으로, Iris setosa (Radomil, CC BY-SA 3.0), Iris versicolor (Dlanglois, CC BY-SA 3.0), and Iris virginica (Frank Mayfield, CC BY-SA 2.0).

각각의 행은 각 꽃의 표본에 대한 다음의 정보를 담고 있습니다 : 꽃받침 길이, 꽃받침 너비, 꽃잎 길이, 꽃잎 너비, 그리고 꽃의 종류. 꽃의 종류는 정수로 표현되어 있으며, 0은 Iris setosa, 1은 Iris versicolor, 그리고 2는 Iris virginica를 나타냅니다.

꽃받침 길이 꽃받침 너비 꽃잎 길이 꽃잎 너비
5.1 3.5 1.4 0.2 0
4.9 3.0 1.4 0.2 0
4.7 3.2 1.3 0.2 0
7.0 3.2 4.7 1.4 1
6.4 3.2 4.5 1.5 1
6.9 3.1 4.9 1.5 1
6.5 3.0 5.2 2.0 2
6.2 3.4 5.4 2.3 2
5.9 3.0 5.1 1.8 2

이 튜토리얼을 위해서 Iris data를 랜덤하게 섞은 후에, 두 개의 CSV 파일로 나누어 놓았습니다:

이 두 CSV 파일을 파이썬 코드와 같은 디렉토리에 놓습니다.

시작하려면, 먼저 텐서플로우와 numpy를 임포트합니다:

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf
import numpy as np

그 다음, learn.datasets.base에 있는 load_csv_with_header() 함수를 이용하여 훈련 셋과 테스트 셋을 Dataset으로 불러옵니다. load_csv_with_header() 함수는 세 개의 인자를 요구합니다:

여기에서 타깃 값(모델을 훈련시켜 예측하려고 하는 값)은 0–2의 정수로 구성된 꽃의 종입니다. 따라서, 적절한 numpy 데이터형은 np.int입니다:

# 데이터셋
IRIS_TRAINING = "iris_training.csv"
IRIS_TEST = "iris_test.csv"

# 데이터셋을 불러옵니다.
training_set = tf.contrib.learn.datasets.base.load_csv_with_header(
    filename=IRIS_TRAINING,
    target_dtype=np.int,
    features_dtype=np.float32)
test_set = tf.contrib.learn.datasets.base.load_csv_with_header(
    filename=IRIS_TEST,
    target_dtype=np.int,
    features_dtype=np.float32)

tf.contrib.learn의 Dataset은 파이썬의 네임드 튜플이며, datatarget 필드를(역주 : namedtuple의 field_name을 말합니다) 이용해 특성 데이터와 타깃 값에 접근할 수 있습니다. training_set.datatraining_set.target은 각각 훈련 셋의 특성 데이터와 타깃 값을 가지고 있고, test_set.datatest_set.target은 테스트 셋의 특성 데이터와 타깃 값을 가지고 있습니다.

나중에 "Iris 훈련 데이터로 DNNClassifier 훈련시키기"에서, training_set.datatraining_set.target을 이용하여 모델을 훈련시키고, "모델 정확도 평가하기"에서는 test_set.datatest_set.target를 이용할 것입니다. 그전에 먼저, 다음 섹션에서 모델을 구성해 보겠습니다.

딥 신경망 분류기 만들기

tf.contrib.learn은 데이터를 가지고 훈련과 평가를 위해 곧장 사용할 수 있는 Estimator라 불리는 여러 가지의 미리 정의된 모델을 제공합니다. 여기에서는 Iris data를 학습시키기 위해 딥 신경망 모델을 구성하겠습니다. tf.contrib.learn을 이용하면, DNNClassifier의 객체를 몇 줄의 코드로 간단히 만들 수 있습니다:

# 모든 특성이 실수값을 가지고 있다고 지정합니다
feature_columns = [tf.contrib.layers.real_valued_column("", dimension=4)]

# 10, 20, 10개의 유닛을 가진 3층 DNN를 만듭니다
classifier = tf.contrib.learn.DNNClassifier(feature_columns=feature_columns,
                                            hidden_units=[10, 20, 10],
                                            n_classes=3,
                                            model_dir="/tmp/iris_model")

위 코드는 먼저 데이터 셋에 있는 특성의 데이터 타입을 지정하기 위해 모델의 특성 열(feature_columns)을 정의합니다. 모든 특성이 연속적인 값이므로 tf.contrib.layers.real_valued_column가 특성 열을 구성하는 데 사용하기 적합한 함수입니다. 이 데이터 셋에는 네 개의 특성(꽃받침 너비, 꽃받침 길이 꽃잎 너비, 꽃잎 길이)이 있으므로 모두 포함시키기 위해 dimensions4로 지정합니다.

그런 다음 아래 인자를 사용하여 DNNClassifier 모델을 만듭니다:

  • feature_columns=feature_columns. 위에서 만든 특성 열을 지정합니다.
  • hidden_units=[10, 20, 10]. 각각 10, 20, 10 개의 뉴런을 가진 세 개의 히든 레이어.
  • n_classes=3. 세 가지 붓꽃의 품종을 나타내는 타깃 클래스.
  • model_dir=/tmp/iris_model. 모델이 학습하는 동안 체크 포인트를 저장할 디렉토리. 텐서플로우의 로깅과 모니터링에 대해서는 Logging and Monitoring Basics with tf.contrib.learn을 참고하세요.

Iris 훈련 데이터로 DNNClassifier 훈련 시키기

이제 DNN classifier 모델을 설정했으니, fit 메소드를 이용하여 Iris 훈련 데이터에 학습시킬 수 있습니다. 특성 데이터(training_set.data)와 타깃 값(training_set.target), 그리고 훈련할 반복 횟수(여기서는 2000)를 인자로 넘겨줍니다:

# 모델 학습
classifier.fit(x=training_set.data, y=training_set.target, steps=2000)

classifier는 모델의 상태를 저장하고 있습니다. 따라서 원한다면 모델을 반복하여 학습시킬 수 있습니다. 예를 들어서, 위의 한 줄은 다음의 두 줄과 완벽하게 같습니다:

classifier.fit(x=training_set.data, y=training_set.target, steps=1000)
classifier.fit(x=training_set.data, y=training_set.target, steps=1000)

하지만 만약 학습되는 동안에 모델을 추적하고 싶다면, 대신 텐서플로우의 monitor를 사용하여 로그를 남기는 게 낫습니다. 이에 대한 내용은 “Logging and Monitoring Basics with tf.contrib.learn”를 참고하세요.

모델 정확도 평가하기

Iris 테스트 데이터를 사용해 DNNClassifier 모델을 학습시켰습니다. 이제, evaluate 메소드를 이용하여 Iris 테스트 데이터로 모델의 정확도를 확인해 보겠습니다. evaluatefit과 같이 특성 데이터와 타깃 값을 인자로 받고, 평가 결과를 하나의 딕셔너리로 반환합니다. 다음의 코드는 Iris 테스트 데이터—test_set.datatest_set.target—를 전달하고, 결과 값에서 accuracy를 출력합니다:

accuracy_score = classifier.evaluate(x=test_set.data, y=test_set.target)["accuracy"]
print('Accuracy: {0:f}'.format(accuracy_score))

전체 스크립트를 실행하고 정확도 결과를 확인합니다:

Accuracy: 0.966667

결과 값이 조금 다를 수 있지만 90%보다는 높게 나올 것입니다. 비교적 적은 데이터셋 치고는 나쁘지 않습니다!

새로운 표본 분류하기

새로운 표본을 분류하기 위해 모델의 predict() 메소드를 이용합니다. 예를 들어, 다음의 새로운 꽃의 표본이 두 개가 있습니다:

꽃받침 길이 꽃받침 너비 꽃잎 길이 꽃잎 너비
6.4 3.2 4.5 1.5
5.8 3.1 5.0 1.7

다음 코드에서 이 데이터의 종을 예측할 수 있습니다:

# 새로운 두 꽃의 표본을 분류합니다.
new_samples = np.array(
    [[6.4, 3.2, 4.5, 1.5], [5.8, 3.1, 5.0, 1.7]], dtype=float)
y = list(classifier.predict(new_samples, as_iterable=True))
print('Predictions: {}'.format(str(y)))

predict() 메소드는 각 표본의 예측 결과를 표본 마다 하나씩 할당하여 배열로 반환합니다:

Prediction: [1 2]

이 모델은 첫 번째 표본을 Iris versicolor, 두 번째 표본을 Iris virginica로 예측하였습니다.

추가적인 자료

results matching ""

    No results matching ""