TensorFlowで二次方程式を解く。

今度は二次方程式を同様の方法で解いてみる。

# 方程式の解を求める。
# y = a*x^2+b*x+c において、y=0となるxを求める。
# xをVariableとし学習対象とする。
# 係数a,b,cは定数とする。

import tensorflow as tf


#-------------------------------------------
# モデル定義
a = tf.constant(1.0, name="const_a")
b = tf.constant(-5.0, name="const_b")
c = tf.constant(6.0, name="const_c")
x = tf.Variable(0.0, name="val_x")

y = a * tf.square(x) + b * x + c

# 評価用変数
# 求めたいのはy = 0となる状態であるが、
# minimize(y) とすると、y が0超えて負数をどこまでも降りてしまうため、
# 自乗し、0に収束していくようにする。
loss = tf.square(y)

tf.summary.scalar("x", x)
tf.summary.scalar("y", y)
tf.summary.scalar("loss", loss)

# 訓練
train = tf.train.GradientDescentOptimizer(0.01).minimize(loss)

# 初期化
init = tf.global_variables_initializer()

summary_op = tf.summary.merge_all()

#-------------------------------------------
# 実行

with tf.Session() as sess:
  summary_writer = tf.summary.FileWriter("log", sess.graph)
  sess.run(init)

  for i in range(100):
    sess.run(train)
    print(sess.run(x))
    summary_str = sess.run(summary_op)
    summary_writer.add_summary(summary_str, i)

ここではxの初期値を0.0としている。
この場合、100回実行後のxの値は1.9667124となった。
一方、xの初期値を5.0とした場合は3.033287となった。

y = x^2 -5*x + 6 を解析的に解いた場合はx = 2, 3 と2つの解を持つ。
二次曲線をどちら側から近づいていくかによって、求められる解が変わってくる。

ちなみに初期値を2.5 (2つの解の中間値、二次曲線が極小となるxの値)とすると、
実行結果は2.5のまま変化がなかった。
多分、勾配降下法で勾配(gradient)を取るとx=2.5の点では0ベクトルとなるので
勾配の方向に進むということができなかったのではないかと思われる。