LoginSignup
5
4

More than 5 years have passed since last update.

Keresメモ:Kerasにperplexityがなかったので書いてみる

Last updated at Posted at 2017-10-09

動機

初めはTensorflowでseq2seqをやろうとしていて、サンプルコードを見ながら学習し、近頃Kerasに移行してみました。backendはそのままTenforflowです。

Tensorflowのチュートリアルで提供されているサンプルコードでは、perplexityという指標が学習中にログとして表示されるようになっていて、これがモデルの性能を評価する上での一つの指標となっています。

これをKerasでも利用しようと思ったのですが、KerasのMetricsにはperplexityがなかったので自分で書いてみました。

正確には、自分で書いた後おかしなエラーが出たので他にやっている人がいないか調べたら、すでに議論している方々がいたので、素直にその方々の話の流れに乗っかりました。
(ちなみに上記エラーは、perplexityとは全く関係ありませんでした。)

perplexityとは

perplexityを自ら説明する自信はないので、勉強の際にお世話になったページをリンクで貼っておきます。

トピックモデルの評価指標 Perplexity とは何なのか? - SlideShare

seq2seqにおいては、encoderから出力された固定長ベクトルとdecoder自身の過去の出力をもとに、decoderが次の単語を予測していきます。

簡単に言うと、「次の単語は○○である」の予測確率が0.01だとしたら、それは同程度の確からしさを持った100単語の中から1単語を選ぶ、と捉えることができます。

Tensorflowのサンプル:translate.pyには、218行目にさらっと登場しています。
1バッチ1ステップとして、100ステップ学習した後にバッチ毎のlossの平均を取り、


perplexity = \mathrm{e}^{loss}

としています。
このperplexity、2のloss乗となっている場合もあるのですが、どのような差なのでしょう。lossを計算するときにlogの底を何にしたかで変わる、という認識で良いのでしょうか。

実装

Kerasでperplexityを使いたい人たちが、ここで議論をしていました。
私もたまたま同じようなエラーが出たので投稿してみたのですが、後日全く関係ないミスから生じたものだとわかり、自分で訂正するという醜態をさらしています。

from keras.losses import categorical_crossentropy
from keras import backend as K
import math

def ppx(y_true, y_pred):
     loss = categorical_crossentropy(y_true, y_pred)
     perplexity = K.cast(K.pow(math.e, K.mean(loss, axis=-1)), K.floatx())
     return perplexity

Tensorflowでは先述の式の通りネーピア数を使っていましたし、KerasはTensorflowをbackendにしているので、そのままネーピア数を用いています。

型をfloatxにキャストしたり、などというのはKerasに始めから用意されているlossやmetricsがやっている事を真似しています。

次にやりたいこと

語彙すべてを対象にしてsoftmaxをやっていては遅すぎるので、Tensorflowのチュートリアルでも紹介されているsampled softmaxをやりたい。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4