tensorflowで三角関数近似

 

周期1年のサイン関数で近似してみました。作成にあたっては以下の文献を参考にさせていただきました。

中井悦司著「Tensorflowで学ぶディープラーニング入門」ISBN978-4-8399-6088-9

 


 

モジュールをインポートします。

In [1]:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
 

Placeholder x を定義します。

In [2]:
x = tf.placeholder(tf.float32, [None, 3])
 

Variable w を定義します。

In [3]:
w = tf.Variable(tf.zeros([3, 1]))
 

計算式 y を定義します。

In [4]:
y = tf.matmul(x, w)
 

Placeholder t を定義します。

In [5]:
t = tf.placeholder(tf.float32, [None, 1])
 

誤差関数 loss を定義します。

In [6]:
loss = tf.reduce_sum(tf.square(y-t))
 

トレーニングアルゴリズム train_step を定義します。

In [7]:
train_step = tf.train.AdamOptimizer().minimize(loss)
 

セッションを用意して、Variableを初期化します。

In [8]:
sess = tf.Session()
sess.run(tf.initialize_all_variables())
 

トレーニングセットのデータを用意します。(実測値)

In [9]:
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])
 

トレーニングセットのデータを用意します。(モデル)

In [10]:
# (温度)=sin(30度*month+位相)+定数 でモデル化
train_x = np.zeros([12, 3])
cur=np.zeros([12,1])
for month in [1,2,3,4,5,6,7,8,9,10,11,12]:
    train_x[month-1][0]=1 # 定数
    train_x[month-1][1]=np.sin(30*month*3.141592/180) #  周期1年のSIN関数
    train_x[month-1][2]=np.cos(30*month*3.141592/180) #  周期1年のCOS関数
 

勾配降下法によるパラメーターの最適化を25000回繰り返します。

In [11]:
i = 0
sess.run(tf.initialize_all_variables())
for _ in range(25000):
    i += 1
    sess.run(train_step, feed_dict={x:train_x, t:train_t})
    if i % 1000 == 0:
        loss_val = sess.run(loss, feed_dict={x:train_x, t:train_t})
        print ('Step: %d, Loss: %f' % (i, loss_val))
print sess.run(w)
 
Step: 1000, Loss: 2935.489990
Step: 2000, Loss: 2488.358643
Step: 3000, Loss: 2093.184082
Step: 4000, Loss: 1744.432251
Step: 5000, Loss: 1438.418945
Step: 6000, Loss: 1172.378418
Step: 7000, Loss: 943.706543
Step: 8000, Loss: 749.378540
Step: 9000, Loss: 585.566284
Step: 10000, Loss: 447.873596
Step: 11000, Loss: 332.510803
Step: 12000, Loss: 237.278015
Step: 13000, Loss: 161.087250
Step: 14000, Loss: 102.957718
Step: 15000, Loss: 61.575798
Step: 16000, Loss: 35.087509
Step: 17000, Loss: 20.843044
Step: 18000, Loss: 15.194585
Step: 19000, Loss: 13.906918
Step: 20000, Loss: 13.797448
Step: 21000, Loss: 13.795701
Step: 22000, Loss: 13.795698
Step: 23000, Loss: 13.795697
Step: 24000, Loss: 13.795696
Step: 25000, Loss: 13.795695
[[ 15.24164963]
 [ -6.8297267 ]
 [ -7.76318884]]
 

トレーニング後のパラメーターを用いて、予測気温を計算する関数を定義します。

In [12]:
def predict(x):
    result = w[0] + w[1]*np.sin(30*x*3.141592/180) \
    + w[2]*np.cos(30*x*3.141592/180)
    return result
 

予測気温のグラフを描きます。

In [13]:
fig = plt.figure()
subplot = fig.add_subplot(1,1,1)
subplot.set_xlim(1,12)
subplot.scatter(range(1,13), train_t)
linex = np.linspace(1,12,100)
liney = sess.run(predict(linex))
subplot.plot(linex, liney)
Out[13]:
[<matplotlib.lines.Line2D at 0x6d7d1d0>]