adish intelligence

アディッシュ株式会社のエンジニアブログです。

~3分でわかる~ TensorFlowで評価アルゴリズムを書いてみた

こんにちは、アディッシュ株式会社(以下adish)・ALICEチーム*1の岩渕です。こちらはGaiax Advent Calender 11日目の記事です。

現在adishでは、深層学習を用いたサービスの開発を行っています。開発にあたって、pythonを利用していることもあり、本日は深層学習ライブラリであるTensorFlowの簡単な説明と、評価アルゴリズムの正解率(accuracy),F値(f-value)の実装例を紹介します。

F値などの評価アルゴリズムについては、過去に白木さんが説明した記事がありますので、こちらを御覧ください

過誤(分割表)と二値分類の性能評価について - adish intelligence

TensorFlow

普段、pythonのような動的プログラムを使っていることで、型宣言を全然しなくなった!なんてことはありませんか?僕は型宣言しない楽な世界にどっぷりハマっていたことも有り、TensorFlowを触り始めた当初は、型が違うと怒られることが多々ありました。 以下は、今回利用したTensorFlowのpython用APIの一部です。

値の扱い

  • 定数: tf.constant()
  • 変数: tf.Variable(): 今回は利用しません。
  • データ格納予定場所: tf.placeholder()

わかりやすい解説記事がこちら

TensorFlowを算数で理解する - Qiita

演算

  • 足し算: tf.add()
  • 引き算: tf.sub()
  • 掛け算: tf.scalar_mul()
    • スカラー値を掛け算するため
  • 割り算: tf.truediv()
    • floatの結果を返す
    • python2系の // に相当、python3系なら /

日本語で演算のAPIを解説されている記事がこちら

評価コード

今回はTensorFlowを用いて、評価アルゴリズムを簡単に実装してみた場合を紹介したいと思います。コードは以下のようになります。

import tensorflow as tf

def accuracy(result):
  """
      return : (True-positive + True-negative) / (all-data-size)
  """
  size = tf.add(result[0], result[2])
  correct = tf.add(result[1], result[3])
  ac = tf.truediv(correct, size)

  return ac

def recall(result):
  """
      return : True-positive / (all-positive-data-size)
  """

  size = result[0]
  TP = result[1]
  rec = tf.truediv(TP, size)

  return rec

def precision(result):
  """
     return : True-positive / (True-positive +  False - Negative)
  """

  TP = result[1]
  size = tf.add(result[1], tf.sub(result[2],result[3]))
  prec = tf.truediv(TP, size)

  return prec

def f_value(result):
  """
    return : 2*precision*recall / (precision + recall)
  """

  prec = precision(result)
  rec = recall(result)

  n = tf.scalar_mul(2,tf.scalar_mul(prec,rec))
  d = tf.add(prec, rec)

  F = tf.truediv(n,d)

  return F


if __name__ == '__main__':
    # 100個ずつデータがあると仮定
    positive_datas = tf.constant([100], tf.int64)
    negative_datas = tf.constant([100], tf.int64)

    # True positive,True negativeの数は引数
    tp = tf.placeholder(tf.int64)
    tn = tf.placeholder(tf.int64)

    # 判定結果とデータサイズを結合
    positive = tf.concat(0, [positive_datas, tp])
    negative = tf.concat(0, [negative_datas, tn])

    # [positive_datas, tp, negative_datas, tn] が作られる
    result = tf.concat(0, [positive, negative])

    # initialize
    sess = tf.Session()
    init = tf.initialize_all_variables()
    sess.run(init)

    # モデル定義
    ac_ = accuracy(result)
    F_ = f_value(result)

    # 実行
    ac, F = sess.run([ac_, F_] feed_dict={tp:[80], tn:[100]})
    
    print("Accuracy: %.3f  | F value :  %.3f  " % (ac, F))

以前の記事を参考に作成すると、以上のようなコードになるかと思います。TensorFlowでは、contribにあるmetricsに、性能評価のアルゴリズムが書かれてあります。今回はtf.contrib.metrics.accuracy()のみ紹介し、それ以外のtf.contrib.metricsについては追って記事を作成できればと思います。

tf.contrib.metrisの利用

もし、以下のように、あるバッチサイズ分の二値出力を行ったとします。

predictions

# shape = (batch_size, 2)
[[0.4, 0.6], [0.2,0.8] ... [0.1, 0.9]]

labels

# shape = (batch_size,)
[0, 1, 0, 1,... 1]

predictionsとlabelsのshapeをあわせます。

predictions = tf.argmax(predictions, dimension=1) 

最後に、それらを用いることで使用することができます。

accuracy = tf.contrib.metrics.accuracy(predictions, labels)

まとめ

今回は簡単にですが、TensorFlowでの使用例を載せてみました。わかっているつもりを無くしていく作業は大事だと思っているので、是非ご自身の手で書いてみましょう!

*1:adishの機械学習に関する開発を行っているチームです