"""Simple tutorial for using TensorFlow to compute a linear regression.
Parag K. Mital, Jan. 2016"""
# %% imports
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
- 创建toy数据,xs,ys均为一维向量。
- 用plt.ion()和plt.draw()实现不中断程序的可视化。
- plt.draw():Redraw the current figure.
- fig.show()和plt.draw()都去掉也可以,why added?
# %% Let's create some toy data
plt.ion()
n_observations = 100
fig, ax = plt.subplots(1, 1)
xs = np.linspace(-3, 3, n_observations)
ys = np.sin(xs) + np.random.uniform(-0.5, 0.5, n_observations)
ax.scatter(xs, ys)
fig.show()
plt.draw()
- 原理: argmin ( w , b ) ∣ ∣ ( X ∗ w + b ) − y ∣ ∣ 2 \underset{(w,b)}{\operatorname{argmin}}||(X * w + b) - y || ^ 2 (w,b)argmin∣∣(X∗w+b)−y∣∣2
- tf.placeholder()用于网络的输入和输出。占位符是我们准备计算图形时需要填写的变量。
- tf.Variable()构造函数需要给变量提供初始值,它可以是任何类型和形状的“Tensor”。初始值定义了变量的类型和形状,定义后变量的类型和形状是不变的,通过赋值可以改变变量的值。
- 损失函数 cost 将衡量观测值与预测值之间的差距,并取平均值。
- tf.reduce_sum() 压缩求和(全部求和、按维度求和)
- tf.random_normal()或tf.random.normal()函数用于从服从指定正太分布的数值中取出指定个数的值。
tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)
- tf.truncated_normal()截断的正态分布函数。生成的值遵循一个正态分布,但不会大于平均值2个标准差。
# %% tf.placeholders for the input and output of the network. Placeholders are
# variables which we need to fill in when we are ready to compute the graph.
X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)
# %% We will try to optimize min_(W,b) ||(X*w + b) - y||^2
# The `Variable()` constructor requires an initial value for the variable,
# which can be a `Tensor` of any type and shape. The initial value defines the
# type and shape of the variable. After construction, the type and shape of
# the variable are fixed. The value can be changed using one of the assign
# methods.
W = tf.Variable(tf.random_normal([1]), name='weight')
b = tf.Variable(tf.random_normal([1]), name='bias')
Y_pred = tf.add(tf.multiply(X, W), b)
# %% Loss function will measure the distance between our observations
# and predictions and average over them.
cost = tf.reduce_sum(tf.pow(Y_pred - Y, 2)) / (n_observations - 1)
- 如果我们想添加正则化,我们可以在成本函数中添加其他术语,例如:岭回归可以看作是线性回归的一种增强版,实现的时候加入一个二范数正则化项,但是应当注意,这里只对于权重进行惩罚,偏置项是不加入正则化的。
- tf.global_norm() 计算多个张量的全局范数.
- tf.mul tf.sub tf.neg 已经废弃,分别可用tf.multiply tf.subtract tf.negative替代.
# %% if we wanted to add regularization, we could add other terms to the cost,
# e.g. ridge regression has a parameter controlling the amount of shrinkage
# over the norm of activations. the larger the shrinkage, the more robust
# to collinearity.
# cost = tf.add(cost, tf.mul(1e-6, tf.global_norm([W])))
- 使用梯度下降来优化w,b,通过负梯度执行单个步骤。
- with tf.Session() as sess:创建一个session来使用图graph。
- sess.run(tf.global_variables_initializer())告诉tensorflow我们想要初始化图中的所有变量,以便我们可以使用它们。
- alpha表示透明度,取值0到1之间,1表示不透明。
# %% Use gradient descent to optimize W,b
# Performs a single step in the negative gradient
learning_rate = 0.01
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
# %% We create a session to use the graph
n_epochs = 1000
with tf.Session() as sess:
# Here we tell tensorflow that we want to initialize all
# the variables in the graph so we can use them
sess.run(tf.global_variables_initializer())
# Fit all training data
prev_training_cost = 0.0
for epoch_i in range(n_epochs):
for (x, y) in zip(xs, ys):
sess.run(optimizer, feed_dict={X: x, Y: y})
training_cost = sess.run(cost, feed_dict={X: xs, Y: ys})
print(training_cost)
if epoch_i % 20 == 0:
ax.plot(xs,
Y_pred.eval(feed_dict={X: xs}, session=sess),
'k',
alpha=epoch_i / n_epochs)
fig.show()
plt.draw()
# Allow the training to quit if we've reached a minimum
if np.abs(prev_training_cost - training_cost) < 0.000001:
break
prev_training_cost = training_cost
fig.show()
plt.waitforbuttonpress()
# 控制台
...
0.25716764
0.2571666
0.25716555
0.25716457
plt.waitforbuttonpress()会使图片无法截图,一按快捷键或鼠标就消失了。采用
plt.ioff()
plt.show()
代替最后两行代码即可。