Tensorflow學習筆記:基礎篇(2)——多項式迴歸
— 前文學習筆記(1)中說到線性迴歸並不能很好的擬合正弦的問題,loss函數值不甚理想,本文將在上文的Tensorflow程序中進行修改,框架結構不變,數據集也不變,僅把線性迴歸修改爲多項式迴歸,看看最終效果如何~~
—廢話少說,直接進入正題
計算流程
1、數據準備
2、準備好placeholder
3、初始化參數/權重
4、計算預測結果
5、計算損失值
6、初始化optimizer
7、指定迭代次數,並在session執行graph
代碼示例
1、數據準備
與上文相同未做修改,在【-3,3】內生成100個點,使用正弦函數上加上了隨機噪聲
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
n_observations = 100
xs = np.linspace(-3, 3, n_observations)
ys = np.sin(xs) + np.random.uniform(-0.5, 0.5, n_observations)
plt.scatter(xs, ys)
plt.show()
2、準備好placeholder
X = tf.placeholder(tf.float32, name='X')
Y = tf.placeholder(tf.float32, name='Y')
3、初始化參數/權重
多項式迴歸問題,此處使用 y = w3 x^3 + w2 x^2 + w1 x + b進行擬合,此處構造四個變量 w1、w2、w3 與 b,比前文多了兩個高次項權重
W = tf.Variable(tf.random_normal([1]), name='weight')
B = tf.Variable(tf.random_normal([1]), name='bias')
W_2 = tf.Variable(tf.random_normal([1]), name='weight_2')
W_3 = tf.Variable(tf.random_normal([1]), name='weight_3')
4、計算預測結果
y = w3 x^3 + w2 x^2 + w1 x + b
其中tf.pow()函數即爲指數運算,例如:tf.pow(X, 2) 表示爲x的2次方
Y_pred = tf.add(tf.multiply(X, W), B)
Y_pred = tf.add(tf.multiply(tf.pow(X, 2), W_2), Y_pred)
Y_pred = tf.add(tf.multiply(tf.pow(X, 3), W_3), Y_pred)
5、計算損失值
此次損失函數,我使用均值平方根,當然你也可以選用其他統計量作爲損失函數值的評價方法
loss = tf.reduce_sum(tf.pow(Y_pred - Y, 2)) / sample_num
6、初始化optimizer
梯度下降函數保持不變,使得loss函數的值取到極小值
learning_rate = 0.01
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
7、指定迭代次數,並在session執行graph
init = tf.global_variables_initializer()
sess.run(init)
再次強調!!!此處兩句極其重要,需要先初始化變量,才能進行讀取和寫入(賦值)操作
n_sample = xs.shape[0]
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
for i in range(1000):
total_loss = 0
for x, y in zip(xs, ys):
__, l = sess.run([optimizer, loss], feed_dict={X: x, Y: y})
total_loss += l
if i % 20 == 0:
print('Epoch{0}:{1}'.format(i, total_loss/n_sample))
W, W_2, W_3, B = sess.run([W, W_2, W_3, B])
plt.scatter(xs, ys)
plt.plot(xs, xs**3*W_3 + xs**2*W_2 + xs*W + B)
plt.show()
運行結果
迭代計算500次,可以發現loss值較前文的線性迴歸已經有了明顯改善,這是因爲用多項式擬合正弦函數,可以理解爲正弦函數的泰勒級數展開,如果感興趣可以嘗試將多項式最高次數繼續提高,再比較loss函數值的變化。
大家是不是已經大概熟悉這個框架了呢,其實就是一個套路~~~
完整代碼
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
#數據準備
n_observations = 100
xs = np.linspace(-3, 3, n_observations)
ys = np.sin(xs) + np.random.uniform(-0.5, 0.5, n_observations)
#plt.scatter(xs, ys)
#plt.show()
#準備好placeholder
X = tf.placeholder(tf.float32, name='X')
Y = tf.placeholder(tf.float32, name='Y')
#初始化參數/權重
W = tf.Variable(tf.random_normal([1]), name='weight')
B = tf.Variable(tf.random_normal([1]), name='bias')
W_2 = tf.Variable(tf.random_normal([1]), name='weight_2')
W_3 = tf.Variable(tf.random_normal([1]), name='weight_3')
#計算預測結果
Y_pred = tf.add(tf.multiply(X, W), B)
Y_pred = tf.add(tf.multiply(tf.pow(X, 2), W_2), Y_pred)
Y_pred = tf.add(tf.multiply(tf.pow(X, 3), W_3), Y_pred)
#計算損失值
sample_num = xs.shape[0]
loss = tf.reduce_sum(tf.pow(Y_pred - Y, 2)) / sample_num
#初始化optimizer
learning_rate = 0.01
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
#指定迭代次數,並在session執行graph
n_sample = xs.shape[0]
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
writer = tf.summary.FileWriter('./graphs/polynomial_reg', sess.graph)
for i in range(600):
total_loss = 0
for x, y in zip(xs, ys):
__, l = sess.run([optimizer, loss], feed_dict={X: x, Y: y})
total_loss += l
if i % 100 == 0:
print('Epoch{0}:{1}'.format(i, total_loss/n_sample))
writer.close()
W, W_2, W_3, B = sess.run([W, W_2, W_3, B])
plt.scatter(xs, ys)
plt.plot(xs, xs**3*W_3 + xs**2*W_2 + xs*W + B, 'r')
plt.show()