end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

tensorflowによる勾配降下法 ( deep learning & python )

github.com

↑こちらの Chapter1の写経。

前準備 - 使用する関係式

STEP1 : 予測式 - 1~12月の気温を予測

 \displaystyle
y = w_0 x^{0} + w_1 x^{1} + w_2 x^{2} + w_3 x^{3} + w_4 x^{4}
y = w x

 \displaystyle
y = X w

 \displaystyle
y = \left(
    \begin{array}{c}
      y_1 \\
      y_2 \\
      \vdots \\
      y_{12}
    \end{array}
  \right)

 \displaystyle
X = \left(
    \begin{array}{cccc}
      1^{0}  &   1^{1} &  \ldots &  1^{4} \\\
      2^{0}  &   2^{1} &  \ldots &  2^{4} \\\
      \vdots &  \vdots &  \ddots & \vdots \\\
      12^{0} &  12^{1} &  \ldots & 12^{4}
    \end{array}
  \right)

 \displaystyle
w = \left(
    \begin{array}{c}
      w_0 \\
      w_1 \\
      \vdots \\
      w_{4}
    \end{array}
  \right)

STEP2 : 誤差関数

 \displaystyle
E = \frac{1}{2}\sum_{n=1}^{12} (y_n - t_n)

最小二乗法や、ニュートン・ラフソン法を思い出します。

で、実装

#!/usr/local/bin/python
# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

def main():
    #予測関数
    x = tf.placeholder(tf.float32, [None, 5])
    w = tf.Variable(tf.zeros([5, 1]))
    y = tf.matmul(x, w)
    #実測値が入る行列
    t = tf.placeholder(tf.float32, [None, 1])
    #誤差関数
    loss = tf.reduce_sum(tf.square(y-t))
    #勾配降下法によるトレーニングアルゴリズム
    train_step = tf.train.AdamOptimizer().minimize(loss)

    sess = tf.Session()
    sess.run(tf.initialize_all_variables())

    #トレーニングデータ
    train_t = np.array([5.2, 5.7, 8.6, 14.9, 18.2, 20.4,
                        25.5, 26.4, 22.8, 17.5, 11.1, 6.6])
    train_t = train_t.reshape([12,1])
    train_x = np.zeros([12, 5])
    for row, month in enumerate(range(1, 13)):
       for col, n in enumerate(range(0, 5)):
            train_x[row][col] = month**n

    #勾配降下法によるの最適化の繰り返し
    i = 0
    for _ in range(1000000):
        i += 1
        sess.run(train_step, feed_dict={x:train_x, t:train_t})
        if i % 10000 == 0:
            loss_val = sess.run(loss, feed_dict={x:train_x, t:train_t})
            print ('Step: %d, Loss: %f' % (i, loss_val))

    #トレーニング後のパラメーターの値を確認
    w_val = sess.run(w)
    print w_val

#トレーニング後のパラメーターを用いて、予測気温を計算する関数を定義
def predict(x):
    result = 0.0
    for n in range(0, 5):
        result += w_val[n][0] * x**n
    return result


if __name__ == '__main__':
    main()

↑こう書くと↓こう表示されます

[endo@cent7 TENSORFLOW]$ ./foo.py 
Step: 10000, Loss: 31.012341
Step: 20000, Loss: 29.450821
  :
Step: 970000, Loss: 12.155926
Step: 980000, Loss: 34.782570
Step: 990000, Loss: 12.154196
Step: 1000000, Loss: 12.153559
[[ 10.88772202]
 [ -9.05010319]
 [  3.99193835]
 [ -0.44603682]
 [  0.01444708]]