Tensorflow+matplotlib視覺化梯度下降
阿新 • • 發佈:2018-12-24
這篇文章主要是為了展示matplotlib 3D圖視覺化梯度下降路徑的效果。
模型選擇了最簡單的y=w*x+b模型,建立一組資料,迭代訓練500次後,畫出平面曲線圖和原始資料散點圖,看看我們訓練處的模型擬合原始資料的表現如何。再畫一個3D圖,x軸為w,y軸為b,z軸為每次訓練的loss值,看看我們的梯度下降路徑的變化。
程式碼如下:
import tensorflow as tf import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' os.environ["CUDA_VISIBLE_DEVICES"] = '0' lr = 0.1 iteration = 500 # 真正的w和b real_params = [1.2, 2.5] X = tf.placeholder(tf.float32, [None, 1]) Y = tf.placeholder(tf.float32, [None, 1]) # 要訓練的w和b初始化為5和4 weight = tf.Variable(initial_value=[[5]], dtype=tf.float32) bias = tf.Variable(initial_value=[[4]], dtype=tf.float32) y = tf.matmul(X, weight) + bias loss = tf.losses.mean_squared_error(Y, y) train_op = tf.train.GradientDescentOptimizer(lr).minimize(loss) x_data = np.linspace(-1, 1, 200)[:, np.newaxis] noise = np.random.normal(0, 0.1, x_data.shape) y_data = x_data * real_params[0] + real_params[1] + noise with tf.Session() as sess: sess.run(tf.global_variables_initializer()) # 記錄訓練過程中的w、b和loss w_record = [] b_record = [] loss_record = [] for i in range(iteration): w, b, cost, _ = sess.run([weight, bias, loss, train_op], feed_dict={X: x_data, Y: y_data}) w_record.append(w) b_record.append(b) loss_record.append(cost) result = sess.run(y, feed_dict={X: x_data, Y: y_data}) plt.figure(1) plt.scatter(x_data, y_data, s=1, color='r', alpha=0.5) plt.plot(x_data, result, lw=1) plt.show() plt.close() fig = plt.figure(2) ax_3d = Axes3D(fig) w_3d, b_3d = np.meshgrid(np.linspace(-4.2, 6.2, 50), np.linspace(-2.5, 7.5, 50)) loss_3d = np.array( [np.mean(np.square((x_data * w_ + b_) - y_data)) for w_, b_ in zip(w_3d.ravel(), b_3d.ravel())]).reshape(w_3d.shape) ax_3d.plot_surface(w_3d, b_3d, loss_3d, cmap=plt.get_cmap('rainbow')) # .ravel()函式會直接修改原始矩陣,也是將矩陣降成一維 w_record = np.array(w_record).ravel() b_record = np.array(b_record).ravel() # 梯度下降曲線 ax_3d.plot(w_record, b_record, loss_record, lw=6, c='blue') # 起始點 ax_3d.scatter(w_record[0], b_record[0], loss_record[0], s=10, color='black') ax_3d.set_xlabel('w') ax_3d.set_ylabel('b') plt.show() plt.close()
首先將lr=0.1,看看效果如何:
這個時候曲線擬合的很好。
觀察3D圖,可以發現梯度下降直接到了最低的loss點。
現在我們將lr設為1.0,看看效果如何:
可以看到由於學習率過大,這個時候曲線很顯然不能擬合原始資料。
再看3D圖,我們可以發現loss值由於學習率過大,一直在"山谷"兩側震盪,無法到達最低點。