(v1.0)
텐서플로우의 고수준 머신러닝 API(tf.contrib.learn)는 다양한 머신러닝 모델을 쉽게 설정하고, 훈련하고, 평가할 수 있도록 해줍니다. 이 튜토리얼에서는 tf.contrib.learn 을 사용하여 신경망 분류기를 만들고, Iris 데이터셋에 있는 꽃받침과 꽃잎의 정보를 이용하여 꽃의 종류를 예측할 수 있도록 분류기를 훈련시킬 것입니다. 코드는 다음의 다섯 단계로 수행됩니다:
- Iris 훈련/테스트 데이터를 담은 CSV 파일을 텐서플로우
Dataset
으로 불러옵니다. - 신경망 분류기를 만듭니다.
- 훈련 데이터를 이용하여 모델을 훈련 시킵니다.
- 모델의 정확도를 평가합니다.
- 새로운 표본을 분류합니다.
참고: 이 튜토리얼을 시작하기 전에 텐서플로우를 설치해야 합니다.
다음은 이 신경망 분류기의 전체 코드입니다:
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 데이터셋은 Iris 품종인 Iris setosa, Iris virginica, Iris versicolor가 각각 50개씩의 표본으로 구성된 150개의 행을 가진 데이터입니다.
왼쪽에서 오른쪽으로, 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 파일로 나누어 놓았습니다:
- 120개의 표본을 갖는 훈련 데이터(iris_training.csv)
- 30개의 표본을 갖는 테스트 데이터(iris_test.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()
함수는 세 개의 인자를 요구합니다:
filename
, CSV 파일의 경로target_dtype
, 데이터셋에 있는 타깃 값의numpy
데이터형features_dtype
, 데이터셋에 있는 특성 값의numpy
데이터형
여기에서 타깃 값(모델을 훈련시켜 예측하려고 하는 값)은 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
은 파이썬의 네임드 튜플이며, data
와 target
필드를*(역주 : namedtuple의 field_name을 말합니다)* 이용해 특성 데이터와 타깃 값에 접근할 수 있습니다. training_set.data
와 training_set.target
은 각각 훈련 셋의 특성 데이터와 타깃 값을 가지고 있고, test_set.data
와 test_set.target
은 테스트 셋의 특성 데이터와 타깃 값을 가지고 있습니다.
나중에 "Iris 훈련 데이터로 DNNClassifier 훈련시키기"에서, training_set.data
와 training_set.target
을 이용하여 모델을 훈련시키고, "모델 정확도 평가하기"에서는 test_set.data
와 test_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
가 특성 열을 구성하는 데 사용하기 적합한 함수입니다. 이 데이터 셋에는 네 개의 특성(꽃받침 너비, 꽃받침 길이 꽃잎 너비, 꽃잎 길이)이 있으므로 모두 포함시키기 위해 dimensions
을 4
로 지정합니다.
그런 다음 아래 인자를 사용하여 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을 참고하세요.
이제 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 테스트 데이터로 모델의 정확도를 확인해 보겠습니다. evaluate
는 fit
과 같이 특성 데이터와 타깃 값을 인자로 받고, 평가 결과를 하나의 딕셔너리로 반환합니다. 다음의 코드는 Iris 테스트 데이터—test_set.data
와 test_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로 예측하였습니다.
-
tf.contrib.learn에 대해 추가적인 참고 자료를 원한다면, 공식적인 API docs를 살펴보세요.
-
tf.contrib.learn을 이용해 선형 모델을 생성하는 방법을 배우려면 Large-scale Linear Models with TensorFlow를 살펴보세요.
-
tf.contrib.learn API를 이용하여 자신만의 Estimator 클래스를 만들고 싶다면 Building Machine Learning Estimator in TensorFlow를 살펴보세요.
-
브라우저에서의 신경망 모델링과 시각화를 체험해 보려면 Deep Playground를 살펴보세요.
-
신경망에 대한 좀 더 심화된 튜토리얼을 원한다면 Convolutional Neural Networks와 Recurrent Neural Networks를 살펴보세요.