TensorFlowでランダムフォレスト

ランダムフォレストなどの機械学習アルゴリズムはScikit-learnなどのライブラリを使うと、すごく手軽に使うことができます。私も普段はScikit-learnを使っています。

ただ今回は練習のために、TensorFlowでランダムフォレストを使ってみました。対象はMNISTです。ランダムフォレスト自体の解説はWeb上にも溢れているのでそちらに譲ります。

ただ個人的には、Webで頑張ってわかりやすい記事を探すよりも、本を買うことで時間を節約したほうがいいんじゃないかなと思ってます。なので参考図書を載せておきます。

プログラム全体

今回使用したプログラム全体を載せます。

from keras.datasets import mnist

from tensorflow.examples.tutorials.mnist import input_data
from tensorflow.contrib.tensor_forest.python import tensor_forest
from tensorflow.contrib.tensor_forest.client import random_forest
from tensorflow.contrib.learn.python.learn.estimators import estimator
from tensorflow.contrib.learn.python.learn import metric_spec
from tensorflow.contrib.tensor_forest.client import eval_metrics

def rf_train(x_train, y_train, x_test, y_test):
    params = tensor_forest.ForestHParams(
        num_classes=10,
        num_features=784,
        num_trees=100,
        max_nodes=10000
    )

    graph_builder_class = tensor_forest.TrainingLossForest
    
    est = estimator.SKCompat(
        random_forest.TensorForestEstimator(
            params,
            graph_builder_class=graph_builder_class,
            model_dir="./models"
        )
    )

    est.fit(x=x_train, y=y_train, batch_size=128)

    metric_name = "accuracy"
    metric = {
        metric_name:metric_spec.MetricSpec(
            eval_metrics.get_metric(metric_name),
            prediction_key=eval_metrics.get_prediction_key(metric_name)
        )
    }

    results = est.score(x=x_test, y=y_test, batch_size=128, metrics=metric)

    for key in sorted(results):
        print("%s: %s" % (key, results[key]))

def get_data():
    (x_train, y_train), (x_test, y_test) = mnist.load_data()
    x_train = x_train.astype("float32")
    x_test = x_test.astype("float32")
    x_train = x_train.reshape(len(x_train), 784)
    x_test = x_test.reshape(len(x_test), 784)
    return x_train, y_train, x_test, y_test

if __name__ == "__main__":
    x_train, y_train, x_test, y_test  = get_data()
    rf_train(x_train, y_train, x_test, y_test)

学習データの取得や前処理を行うget_data関数と、学習を行うrf_train関数に分かれていますが、別にここを一つにしても問題はありません。

get_data関数ではMNISTデータセットを呼び出して整形していますが、今回はKerasの標準データセットを使っています。TensorFlowでのデータ取得がなぜかうまくいかなかったためです。

その他にget_data関数に変わったところはないので、rf_train関数の解説を行います。

学習部分

モデルの構築は以下のようにして行なっています。

est = estimator.SKCompat(
        random_forest.TensorForestEstimator(
            params,
            graph_builder_class=graph_builder_class,
            model_dir="./models"
        )
    )

公式のリファレンスにも詳しいことが載っていなかったので、あまり詳しいことは私にもわかりません…

学習結果

学習モデルを検証用の画像で評価すると次のような結果になりました。

accuracy: 0.913
global_step: 931
loss: 0.000825727

ろくにパラメーターを検討せずに使っているので、精度はひどいものですねScikit-learnでランダムフォレストを使った時はもう少し良かったような…

まだ未検証ですが、ランダムフォレストをニューラルネットの中に入れた構造なども作れるのかもしれません。他にも、ランダムフォレストをたくさん組み合わせたDeep-Forestなどを再現できないか挑戦してみます。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする