『Python数値計算ノート』ではアフィリエイトプログラムを利用して商品を紹介しています。

交差エントロピー誤差関数

対数尤度と交差エントロピー誤差関数

前回記事では、ある気温 $x$ が与えられたとき、目標変数 $y$ が $1$ をとる(すなわち雨に分類される)確率 $P(t=1|x)$ は ロジスティック関数
 \[L(x)=\frac{1}{1+\exp\{-(ax+b)\}}\]
によって与えられると仮定しました。今回は手持ちの実測データ
 \[\boldsymbol{\mathrm{X}}=\begin{bmatrix}x_0 \\ x_1 \\ \vdots \\ x_{N-1}
\end{bmatrix},\quad \boldsymbol{\mathrm{T}}=\begin{bmatrix}t_0 \\ t_1 \\ \vdots \\ t_{N-1}\end{bmatrix}\]
を用いて、パラメータベクトル
 \[\boldsymbol{q}=\begin{bmatrix}a \\ b\end{bmatrix}\]
を最適化することを考えます(今回は $p$ を使うと紛らわしいので、パラメータベクトルは $\boldsymbol{q}$ で表すことにします)。ここで、$P(t=1|x)=L$ とおくと、$P(t=0|x)=1-L$ なので、気温 $x$ が与えられたとき、目標変数が $t$ をとる確率(尤度)は
 \[P(t|x)=L^t(1-L)^{1-t}\]
と表すことができます。念のために確認しておくと、$t=1$ のときは
 \[P(t=1|x)=L^1(1-L)^0=L\]
となり、$t=0$ のときは
 \[P(t|x)=L^0(1-L)^{1}=1-L\]
となります。確率の乗法定理によって、データセット $P(\boldsymbol{\mathrm{T}}|\boldsymbol{\mathrm{X}})$ が得られる確率は
 \[P(\boldsymbol{\mathrm{T}}|\boldsymbol{\mathrm{X}})=P(t_0|x_0)P(t_1|x_1)P(t_2|x_2)\cdots P(t_{N-1}|x_{N-1})\]
のように計算できます。総積記号 $\prod$ を使うと、
 \[P(\boldsymbol{\mathrm{T}}|\boldsymbol{\mathrm{X}})=\prod_{k=0}^{N-1}P(t_k|x_k)\]
と簡潔に表すことができます。ここで $L_k=L(x_k)$ とおいて、上式に代入すると、
 \[P(\boldsymbol{\mathrm{T}}|\boldsymbol{\mathrm{X}})=\prod_{k=0}^{N-1}L_k^{t_k}(1-L_k)^{1-t_k}\]
となります。この式が最大値をとるようにパラメータベクトル $\boldsymbol{q}$ を決定すればよいことになります。両辺の対数をとると総積は総和の形になります。
 \[\log P(\boldsymbol{\mathrm{T}}|\boldsymbol{\mathrm{X}})=\sum_{k=0}^{N-1}\{t_k\log L_k+(1-t_k)\log (1-L_k)\}\]
これを 対数尤度 とよびます。さらに対数尤度の符号を変えて最小値を探す問題に変えます。このとき、
 \[-\log P(\boldsymbol{\mathrm{T}}|\boldsymbol{\mathrm{X}})\]
のことを 交差エントロピー誤差関数 (cross entropy error function) とよびます。さらにデータ数の異なる場合でも比較できるように、データ数 $N$ で割っておくことにします。
 \[E(\boldsymbol{q})=-\frac{1}{N}\log P(\boldsymbol{\mathrm{T}}|\boldsymbol{\mathrm{X}})
=\frac{1}{N}\sum_{k=0}^{N-1}\{-t_k\log L_k-(1-t_k)\log (1-L_k)\}\]
分類問題はこの 平均交差エントロピー誤差関数 $E(\boldsymbol{q})$ を最小化する問題に帰着しました。後の流れは以前に扱った非線形回帰分析と同じようになります。今回は scipy.optimize.minimize() で共役勾配法 (CG) を指定するので、引数として必要になる関数の勾配 (gradient) を求めておきます。$E(\boldsymbol{q})$ の総和記号 $\sum$ の中身を
 \[E_k=-t_k\log L_k-(1-t_k)\log (1-L_k)\]
とおくと、$E_k$ の $a$ による偏微分は連鎖律を使って
 \[\frac{\partial E}{\partial a}=\frac{\partial E_k}{\partial L_k} \frac{\partial L_k}{\partial a}\]
で計算できます。

$\cfrac{\partial E_k}{\partial L_k}$ と $\cfrac{\partial L_k}{\partial a}$ をそれぞれ計算すると、
 \[\begin{align*}\cfrac{\partial E_k}{\partial L_k}&=-\cfrac{t_k}{L_k}+\cfrac{1-t_k}{1-L_k}\\[6pt]
\cfrac{\partial L_k}{\partial a}&=x_kL_k(1-L_k)\end{align*}\]
となるので、
 \[\frac{\partial E_k}{\partial a}=(L_k-t_k)x_k\]
が得られます。したがって、
 \[\frac{\partial E}{\partial a}=\frac{1}{N}\sum_{k=0}^{N-1}(L_k-t_k)x_k\]
となります。同様にして $E$ の $b$ による偏導関数を計算すると
 \[\frac{\partial E}{\partial b}=\frac{1}{N}\sum_{k=0}^{N-1}(L_k-t_k)\]
となります。まとめると、$E(\boldsymbol{q})$ の勾配は
 \[\nabla E(\boldsymbol{q})=\begin{bmatrix}\cfrac{\partial E}{\partial a}\\
\cfrac{\partial E}{\partial b}\end{bmatrix}=\frac{1}{N}\begin{bmatrix}\displaystyle\sum_{k=0}^{N-1}(L_k-t_k)x_k\\
\displaystyle\sum_{k=0}^{N-1}(L_k-t_k)\end{bmatrix}\]
となります。
 
ロジスティック関数と平均交差エントロピー誤差関数、およびその勾配関数を Python で実装しておきます。

# In[3]

# ロジスティック関数
def logistic(x, q):
    f = 1 / (1 + np.exp(-(q[0] * x + q[1])))
    return f

# 平均交差エントロピー誤差関数
def cee_logistic(q, x, t):
    f = logistic(x, q)
    c = - np.sum((t * np.log(f) + (1 - t) * np.log(1 - f)))
    return c / len(f)

# 平均交差エントロピー誤差関数の勾配
def grad_cee_logistic(q, x, t):
    f = logistic(x, q)
    grad = np.zeros(2)
    grad[0] = np.sum((f - t) * x)
    grad[1] = np.sum(f - t)
    return grad / len(f)

次回は平均交差エントロピー誤差関数の最小値を計算してみます。

【書籍紹介】深層強化学習を勉強するための本

近年、アルファ碁や自動運転システムなどで注目を集める深層強化学習 (Deep Q – Network)は、強化学習と ディープラーニングを組合わせた、最先端の人工知能 (AI) を支える開発手法です。この分野を会得するためには、良書を数冊じっくり読み込んで、しっかりとした土台を作っておく必要があります。
 

将棋AIで学ぶディープラーニング

中古価格
¥2,427から
(2020/8/21 12:33時点)


2016 年に DeepMind社によって開発されたアルファ碁が中国で囲碁のトップ棋士を破り、一躍世間の注目を集めましたが、そのアルファ碁を支えているのがディープラーニングとよばれるシステムです。本書『将棋 AI で学ぶディープラーニング』ではこの手法を応用して将棋 AI の開発を行ないながら、ディープラーニングについて学びます。
 

Pythonによる深層強化学習入門 ChainerとOpenAI Gymではじめる強化学習

中古価格
¥1,729から
(2020/8/21 12:35時点)


『Pythonによる深層強化学習入門 ChainerとOpenAI Gymではじめる強化学習』では、Cheiner と OpenAI gym を用いた深層強化学習について入門レベルから実装まで、ソフト・ハード(実環境)の両面から解説しています。
 

つくりながら学ぶ! 深層強化学習 ~PyTorchによる実践プログラミング~

新品価格
¥3,608から
(2020/8/21 12:37時点)


『つくりながら学ぶ! 深層強化学習 ~PyTorchによる実践プログラミング~』は、深層強化学習の基礎を学びながら、Python と PyTorch を用いて「迷路を最短で脱出させるプログラム」、「倒立振子課題」、「ブロック崩し」などを実装していきます。

コメント

  1. サイトウ より:

    すみません、初めまして。
    過去記事から読んできたところなのですが、連鎖率のところの、∂Lk/∂aがよくわかりません
    数学から離れて久しい部分もあり、理解力に乏しく申し訳ありません。
    手元のメモだとa自体はq=[a,b]と置いただけで、どの式に変形、代入し、微分したのか解説していただけると嬉しいです。

    • BlogCat より:

      こちらこそ、説明不足で申し訳ないです。本文ではさらっと一行で書いてありますが、結構長い計算になります。ロジスティック関数の定義により

      \[L_k=\frac{1}{1+\exp\{-(ax_k+b)\}}\]
      ここで、
      \[g(a)=1+\exp\{-(ax_k+b)\}\]
      とおくと、
      \[L_k=\frac{1}{g(a)}\]
      と表せます。合成関数の微分公式より、$L_k$ の $a$ による微分は
      \[\cfrac{\partial L_k}{\partial a}=L_k'(g(a))g'(a)\]
      によって計算できます。$L_k'(g(a))$ と $g'(a)$ はそれぞれ
      \[\begin{align*}&L_k'(g(a))=-\frac{1}{g(a)^2}\\[6pt]
      &g'(a)=-x_k\exp\{-(ax_k+b)\}=-x_k\{g(a)-1\}\end{align*}\]
      となるので、
      \[\cfrac{\partial L_k}{\partial a}=x_k\frac{g(a)-1}{g(a)^2}\]
      さらに、$g(a)=1/L_k$ なので、
      \[\cfrac{\partial L_k}{\partial a}=x_k\frac{1/L_k-1}{1/L_k^2}=x_k L_k(1-L_k)\]
      が得られます。

    • BlogCat より:

       さきほどの返信で数式の一部を間違えていたので、訂正しておきました。
       申し訳ありません。

      • サイトウ より:

        丁寧な回答に感激致しました。ありがとうございました。
        これまで数学的な証明を経ずに分類問題のスクリプトなどを扱っていたため、本サイトの解説に頼りながら理解を深めています。