텐서플로우 튜토리얼 – 2

이 글은 Illia Polosukhin 가 쓴 TensorFlow Tutorial – Part 2 을 번역한 글 입니다. (update: 2016-04-19) 텐서플로우 0.8 버전에 맞추어 코드를 수정하였고 번역을 다듬었습니다. 아래 예제를 쥬피터 노트북으로 작성하여 깃허브에 올려 놓았습니다.

이전 튜토리얼 – 1 에서 텐서플로우(TensorFlow)와 사이킷플로우(Scikit Flow)를 소개하고 타이타닉 데이터셋을 이용하여 간단한 로지스틱 회귀분석(Logistic Regression)의 예를 보였습니다.

여기에서는 사이킷플로우를 이용하여 컨볼루션 네트워크(convolutional networks, 합성곱신경망 또는 CNN)를 만드는 여러개의 레이어(multi-layer)가 완전히 연결된(fully connected) 뉴럴 네트워크를 만들어 보겠습니다.

다층 완전연결 신경망(Multi-layer fully connected neural network)

당연히 텐서플로우가 또 다른 선형 회귀분석(Linear Regression)나 로지스틱 회귀분석(Logistic Regression) 프레임워크라면 큰 의미가 없습니다. 텐서플로우의 이면에 있는 아이디어는 미분 가능한 모델들을 연결하여 하나의 코스트 함수(cost function or loss function)를 이용하여 최적화할 수 있는 것입니다.

사이킷플로우(Scikit Flow)는 완전히 연결된(fully connected) 다층 네트워크(many layers)를 만드는 텐서플로우(TensorFlow) API 의 래퍼(wrapper)를 이미 제공하고 있어서 이전 튜토리얼의 모델(classifier)을 TensorFlowDNNClassifier 로 교체하고 레이어(layer)에 할당할 히든 유닛을 지정하는 것으로 간단히 딥러닝 모델을 만들 수 있습니다.

>>> from tensorflow.contrib import skflow
>>> classifier = skflow.TensorFlowDNNClassifier(
...     hidden_units=[10, 20, 10],
...     n_classes=2,
...     batch_size=128,
...     steps=500,
...     learning_rate=0.05)
>>> classifier.fit(X_train, y_train)
>>> print(accuracy_score(classifier.predict(X_test), y_test))
0.664804469274

(역주: 텐서플로우 0.6 버전에서는 accuracy score 가 0.659로 감소되었다가 0.8버전에서 다시 조금 상승했습니다.)

이 코드는 10개, 20개, 10개의 히든 유닛을 가지는 완전히 연결(fully connected)된 세개의 레이어를 생성합니다. 디폴트 활성화(activation) 함수는 렐루(ReLU, rectified linear unit) 함수입니다. 이 설정은 다음번에 조정할 수 있습니다.

모델에 사용된 파라메타에 대해 – 여기에서 지정한 값은 예를 위한 것입니다. 모델을 훈련시킬 때 학습속도(learning rate), 옵티마이저(optimizer), 스텝(step) 수에 따라 큰 차이가 발생합니다. 일반적으로 실제 상황에서는 코스트(cost)를 최적화하고 정확도를 높이기 위해 밸리데이션 셋(validation set)에서 최적의 하이퍼파라메타(hyper-parameter)를 찾습니다.

tanh 활성화(activation) 함수를 이용한 다층 레이어(multi-layer)

위의 테스트에서 하이퍼 파라메타가 최적은 아니지만 이 DNN 모델은 로지스틱 회귀분석(logistic regression)에 비해 좋지 않은 결과를 보여줍니다. 이 부분은 오버피팅(overfitting)과 언더피팅(under-fitting)에 관한 것으로 별도의 글에서 살펴보겠습니다.

위 예를 위해서 커스텀 모델을 이용해서 어떻게 조절할 수 있는지를 보게습니다.

>>> def dnn_tanh(X, y):
...    layers = skflow.ops.dnn(X, [10, 20, 10], tf.tanh)
...    return skflow.models.logistic_regression(layers, y)

>>> classifier = skflow.TensorFlowEstimator(
...    model_fn=dnn_tanh,
...    n_classes=2,
...    batch_size=128,
...    steps=500,
...    learning_rate=0.05)
>>> classifier.fit(X_train, y_train)
>>> print(accuracy_score(classifier.predict(X_test), y_test))
0.698324022346

(역주:  logistic_classifier는 skflow가 텐서플로우 코드로 옮겨지면서 logistic_regression 로 바뀌었습니다)

(역주: 텐서플로우 0.6 버전에서는 Accuracy가 0.586로 낮아졌다가 0.8 버전에서 다시 상승되었습니다.)

이 모델은 이전 것과 유사하지만 기본 렐루(ReLU) 함수에서 하이퍼볼릭 탄젠트로 활성화 함수를 바꾸었습니다.(렐루와 하이퍼볼릭 탄젠트 함수는 뉴럴 네트워크 알고리즘에서 가장 널리 쓰이는 활성화 함수입니다.)

위 예에서 볼 수 있듯이 커스텀 모델을 만드는 것은 쉽습니다. X 와 y 를(둘다 텐서입니다) 입력받아 두 텐서(predictions 과 loss)를 리턴하는 함수를 작성하면 됩니다(역주. logistic_regression 함수가 prediction과 loss를 위한 두개의 소프트맥스 함수를 리턴합니다). 서브그래프를 만들기 위해서는 텐서플로우 API 를 배우는 것이 좋은 출발점입니다.

숫자 판별

숫자 판별 예가 빠질 수야 있겠습니까? : )

실수형의 속성(features)을 넘어서 이 예에서는 다른 종류의 데이터와 모델을 어떻게 다룰 수 있는지 보여줍니다. 여기서는 숫자(digits) 데이터 셋을 대상으로 커스텀 모델을 만들겠습니다.

import random
from sklearn import datasets, cross_validation, metrics
import tensorflow as tf

import tensorflow.contrib.learn.python.learn as skflow

random.seed(42)

# Load dataset and split it into train / test subsets

digits = datasets.load_digits()
X = digits.images
y = digits.target

X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, y, test_size=0.2, random_state=42)

# TensorFlow model using Scikit Flow ops

def conv_model(X, y):
    X = tf.expand_dims(X, 3)
    features = tf.reduce_max(skflow.ops.conv2d(X, 12, [3, 3]), [1, 2])
    features = tf.reshape(features, [-1, 12])
    return skflow.models.logistic_regression(features, y)

# Create a classifier, train and predict
classifier = skflow.TensorFlowEstimator(model_fn=conv_model, n_classes=10, steps=500, learning_rate=0.05, batch_size=128)
classifier.fit(X_train, y_train)
print(metrics.accuracy_score(classifier.predict(X_test), y_test))
# 0.747222222222

(역주: 텐서플로우 0.6 버전에서는 Accuracy score 가 0.642로 낮아졌다가 0.8버전에서는 다시 상승했습니다)

주어진 텐서 X, y 를 가지고 최대값을 취하는 맥스 풀링(max-pooling) 방식의 2차원 컨볼루션 레이어(convolutional layer) 를 구성하는 conv_model 함수를 만들었습니다. 소프트맥스(softmax) 함수와 교차 엔트로피 손실함수(cross entropy loss) 를 사용하여 분류를 수행하는 logistic_regression 함수의 피처(features) 로 만들어진 레이어를 넘깁니다.

원하는 만큼 많은 레이어를 넣기 위해서는 코드를 조금만 수정하면 됩니다.(최신의 이미지 판별 모델들은 수백개의 컨볼루션 레이어와 맥스풀링(max pooling), 드롭아웃(dropout) 등으로 이루어져 있습니다.)

다음으로

다음 글은 타이타닉 데이터셋을 가지고 카테고리 변수를 다루는 모델로 확장하여 적용해 보도록 하겠습니다.

기대해 주세요!

텐서플로우 튜토리얼 – 2”에 대한 7개의 생각

  1. 핑백: 텐서플로우 튜토리얼 – 3 | 텐서플로우 코리아

  2. 김태환

    좋은 글 감사합니다. DNN의 weight를 우리가 원하는 특정값들로 초기화 하고 싶은데, 이 경우는 어떻게 할 수 있을까요?

    좋아요

    응답
  3. 초보자

    혹시 이 예제에 텐서 보드까지 실행시킬 수 있는 코드예제까지 포스팅해주실 수 있나요?
    제 욕심인가요… ㅎㅎ

    좋아요

    응답
    1. 로드홈 글의 글쓴이

      아뇨 ^^. 텐서보드 예제를 담아서 포스팅 하겠습니다. 아마 하루이틀 걸릴 것 같아요. 조금만 기다려 주세요. ; )

      좋아요

      응답

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중