「深層学習」読書会 〜第2章〜

2016/04/16 機械学習 名古屋 第3回勉強会

第2章 順伝播型ネットワーク

2.1 ユニットの出力

図2.2:

In [3]:
fig_2_2
Out[3]:
fig_2_2 x3 x3 u1z1 u1 z1 x3->u1z1 u2z2 u2 z2 x3->u2z2 u3z3 u3 z3 x3->u3z3 x4 x4 x4->u1z1 x4->u2z2 x4->u3z3 x1 x1 x1->u1z1 x1->u2z2 x1->u3z3 x2 x2 x2->u1z1 x2->u2z2 x2->u3z3 z1 z1 u1z1->z1 z2 z2 u2z2->z2 z3 z3 u3z3->z3

式2.1〜2.3:

$$ \begin{eqnarray*} \left[\begin{array}{cc} u_1 \\ u_2 \\ u_3 \end{array}\right] &=& \left[\begin{array}{cc} w_{1,1} & w_{1,2} & w_{1,3} & w_{1,4} \\ w_{2,1} & w_{2,2} & w_{2,3} & w_{2,4} \\ w_{3,1} & w_{3,2} & w_{3,3} & w_{3,4} \end{array}\right] \cdot \left[\begin{array}{cc} x_1 \\ x_2 \\ x_3 \\ x_4 \end{array}\right] + \left[\begin{array}{cc} b_1 \\ b_2 \\ b_3 \end{array}\right] \\ \left[\begin{array}{cc} z_1 \\ z_2 \\ z_3 \end{array}\right] &=& \left[\begin{array}{cc} f(u_1) \\ f(u_2) \\ f(u_3) \end{array}\right] \end{eqnarray*} $$
$$ \Downarrow $$
$$ \begin{eqnarray*} {\bf u} &=& {\bf Wx} + {\bf b} \\ {\bf z} &=& {\bf f}({\bf u}) \end{eqnarray*} $$

TensorFlow の書き方で書くと以下のような感じ:

入力 ${\bf x} = {}^t[x_1, x_2, \dots , x_I]$:

  • tf.placeholder() を利用(訓練データを入れるプレースホルダ)
    • 第1引数は数値の型(例:tf.float32
    • 第2引数は [None, 《要素数》]
In [5]:
x = tf.placeholder(tf.float32, [None, 4])

重み ${\bf W} = 《行列》$:

  • tf.Variable() を利用(学習パラメータ=変数)
  • 値は、tf.random_normal()(または tf.zeros())で初期化する。
    • (第1)引数は [《入力の要素数》, 《出力の要素数=ユニット数》]
In [6]:
W = tf.Variable(tf.random_normal([4, 3], mean=0.0, stddev=0.05))
# または
# W = tf.Variable(tf.zeros([4, 3]))

バイアス ${\bf b} = {}^t[b_1, b_2, \dots , b_J]$:

  • tf.Variable() を利用(学習パラメータ=変数)
  • 値は、tf.zeros()(または tf.random_normal())で初期化する。
    • (第1)引数は [《出力の要素数=ユニット数》]
In [7]:
b = tf.Variable(tf.zeros([3]))

ユニットの総入力 ${\bf u} = {}^t[u_1, u_2, \dots , u_J] = {\bf Wx + b}$:

In [8]:
u = tf.matmul(x,  W) + b
# または
# u = tf.add(tf.matmul(x,  W1), b1)

ユニットの出力 ${\bf z} = {}^t[z_1, z_2, \dots , z_J] = {\bf f}({\bf u})$:

In [ ]:
z = f(u)
# ただし f は次節で紹介する「活性化関数」のいずれか。

2.2 活性化関数

ロジスティックシグモイド関数(ロジスティック関数):

$$ \begin{eqnarray*} f(u) &=& {\rm sigmoid}(u)\\ &=& \frac{1}{1 + e^{-u}} \end{eqnarray*} $$
  • tf.sigmoid() という関数が用意されている。
In [ ]:
z = tf.sigmoid(u)

双曲線正接関数:

$$ \begin{eqnarray*} f(u) &=& \tanh(u)\\ &=& \frac{e^u - e^{-u}}{e^u + e^{-u}} \end{eqnarray*} $$
  • tf.tanh() という関数が用意されている。
In [ ]:
z = tf.tanh(u)

正規化線形関数:

$$ f(u) = \max(u, 0) $$
  • tf.nn.relu() という関数が用意されている。
In [ ]:
z = tf.nn.relu(u)

確認:

In [11]:
fig_activation_fns()

参考:TensorFlow に用意されているその他の活性化関数(例)

$$ \begin{eqnarray*} {\rm ReLU_6} &:& \min(\max(u, 0), 6)\\ {\rm ELU} &:& \left \{ \begin{array}{} u &\ (u \ge 0)\\ e^u - 1 &\ (u < 0) \end{array} \right. \\ {\rm softplus} &:& \ln(e^u + 1)\\ {\rm softsign} &:& \frac{u}{|u|+1}\\ \end{eqnarray*} $$
In [13]:
fig_other_activation_fns()

2.3 多層ネットワーク

2層(入力層、隠れ層1、出力層)の例:

$$ \begin{eqnarray*} {\bf u}^{(2)} &=& {\bf W}^{(2)}{\bf x} + {\bf b}^{(2)}\\ {\bf z}^{(2)} &=& {\bf f}^{(2)}({\bf u}^{(2)})\\ & &\\ {\bf u}^{(3)} &=& {\bf W}^{(3)}{\bf z}^{(2)} + {\bf b}^{(3)}\\ {\bf z}^{(3)} &=& {\bf f}^{(3)}({\bf u}^{(3)})\\ \end{eqnarray*} $$

TensorFlow でも、これを丁寧に1つずつコードに落とせばOK。

In [14]:
# 入力層→隠れ層
x = tf.placeholder(tf.float32, [None, 4])
W2 = tf.Variable(tf.zeros([4, 3]))
b2 = tf.Variable(tf.zeros([3]))
u2 = tf.matmul(x,  W2) + b2
z2 = tf.nn.relu(u2)
In [15]:
# 隠れ層→出力層
# z2: ↑の出力
W3 = tf.Variable(tf.zeros([3, 2]))
b3 = tf.Variable(tf.zeros([2]))
u3 = tf.matmul(z2, W3) + b3
z3 = tf.nn.softmax(u3)

最終的な出力 ${\bf y} = {\bf y}({\bf x}; {\bf w})$

In [16]:
y = z3

2.4 出力層の設計と誤差関数

2.4.1 学習の枠組み

表2.1:

問題の種別 出力層の活性化関数 誤差関数
回帰 恒等写像 二乗誤差関数
二値分類 ロジスティック関数 (交差エントロピー関数)
多クラス分類 ソフトマックス関数 交差エントロピー関数

※訓練データ(正解のデータ)${\bf d} = {}^t[y_1, y_2, \dots , y_J]$:

  • 入力データ ${\bf x}$ と同様、tf.placeholder() を利用(訓練データを入れるプレースホルダ)
    • 第1引数は数値の型(例:tf.float32
    • 第2引数は [None, 《要素数》]
In [17]:
d = tf.placeholder(tf.float32, [None, 2])

誤差関数とは、最終的な出力 ${\bf y}$ と、訓練データ(正解データ)${\bf d}$ との「誤差」を測る関数、と言う意味。
※ 誤差関数の値が最小となるようなパラメータ ${\bf w}$(${\bf W}^{(2)}, {\bf b}^{(2)}, \dots , {\bf W}^{(L)}, {\bf b}^{(L)}$)を決めて行くのが「学習」する、ということ。

2.4.2 回帰

出力層で、活性化関数を利用せずに ${\bf u}^L$ の結果をそのまま最終的な出力 ${\bf y}$ として扱えばOK。
誤差関数は二乗誤差関数を利用:

$$ E({\bf w}) = \frac{1}{2} \sum_n \left\| {\bf d}_n - {\bf y}({\bf x}_n; {\bf w}) \right\|^2 $$

例:

In [ ]:
e = tf.reduce_mean(tf.square(d - u3))

※ ↑ $1/2$ を掛けていないが、定数倍なので結果に影響ないため省略している。

2.4.3 二値分類

出力層の活性化関数としては、ロジスティック関数を利用。
誤差関数は(二値の)交差エントロピー:

$$ E({\bf w}) = - \sum_n \left[ d_n \log(y({\bf x}_n; {\bf w})) + (1 - d_n) \log(1 - y({\bf x}_n; {\bf w})) \right] $$

TensorFlow では、この式を直接表せる関数が用意されている:

In [ ]:
x_entropy = tf.nn.sigmoid_cross_entropy_with_logits(u3, d)

※ ↑tf.nn.sigmoid_cross_entropy_with_logits() 関数が内部で tf.sigmoid() 関数を利用するので、z3 = tf.sigmoid(u3) 不要。

2.4.4 多クラス分類

出力層の活性化関数としては、ソフトマックス関数を利用。
誤差関数は交差エントロピー。

ソフトマックス関数
$K$ 個の入力(長さ$K$のベクトル)に対して、$K$ 個の出力(長さ$K$のベクトル)を返す関数。
戻り値のどの要素も値域は $0 \le z_k \le 1$。

$$ \begin{eqnarray*} {\bf f}({\bf u}) &=& {\bf f}({}^t[u_1, u_2, \dots, u_K])\\ &=& {}^t[z_1, z_2, \dots , z_K] \end{eqnarray*} $$

ただし $$ \begin{eqnarray*} z_k &=& \frac{\exp(u_k)}{\sum_{j=1}^{K}\exp(u_j)} \end{eqnarray*} $$

TensorFlow では tf.nn.softmax() という関数が用意されている。

In [ ]:
y = tf.nn.softmax(u3)

交差エントロピー:

$$ E({\bf w}) = - \sum_n \sum_k d_{nk} \log(y_k({\bf x}_n; {\bf w})) $$
In [ ]:
x_entropy = -tf.reduce_sum(d * tf.log(y))
# または
# x_entropy = tf.nn.softmax_cross_entropy_with_logits(u3, d)