代码:
import tensorflow as tf
import numpy as np
# 前期准备---数据处理:归一化
x_row = np.array([2013, 2014, 2015, 2016, 2017], dtype=np.float32)
y_row = np.array([12000, 14000, 15000, 16500, 17500], dtype=np.float32)
# 数据归一化需要用np容器类型的数据,因为TensorFlow没有x.min和x.max操作
x = (x_row - x_row.min()) / (x_row.max() - x_row.min())
y = (y_row - y_row.min()) / (y_row.max() - y_row.min())
# 利用TensorFlow2.0来线性回归
X = tf.constant(x)
Y = tf.constant(y) # 数据类型转换:因为使用到了TensorFlow的库,所以在这里所有变量都需要时Tensor类型了
a = tf.Variable(initial_value=0.)
b = tf.Variable(initial_value=0.)
variable = [a, b]
epoch = 30000
optimizer = tf.keras.optimizers.SGD(learning_rate=0.00001)
for i in range(epoch):
with tf.GradientTape() as tape:
Y_predict = a * X + b
loss = tf.reduce_sum(tf.square(Y_predict - Y))
grad = tape.gradient(loss, variable)
print('gradient', grad)
optimizer.apply_gradients(grads_and_vars=zip(grad, variable))
print('a', a, 'b', b)
代码解析:
1.第15-16行
a = tf.Variable(initial_value=0.)
b = tf.Variable(initial_value=0.) # 定义Tensor的变量要对变量进行初始化
但是如果改成下面这样,则会报错:
a = tf.Variable(initial_value=0)
b = tf.Variable(initial_value=0)
因为tf.Variable默认整数为int32,注意Numpy默认的浮点数类型是float64,前面的x y定义为类型:dtype=np.float32
如果想和Numpy数据进行对比或者一起参与求导运算,则需要修改与numpy一致。
2.第19行
optimizer = tf.keras.optimizers.SGD(learning_rate=0.00001)
设置了优化器选用SGD优化器(SGD梯度下降算法),梯度下降的优化器有很多种,还有adam等。其含义是利用什么样的算法来进行梯度的更新从而实现梯度下降(减小)。梯度更新换句话说就是利用什么方式来进行梯度的减小。
3.第27行
注意:每运行一次优化器optimizer.apply_gradients(grads_and_vars=zip(grad, variable))只会进行一次移动(梯度下降更新),因此optimizer.apply_gradients(grads_and_vars=zip(grad, variable))需要写进for循环内,经过epoch次的下降更新
4.第26和28行
print('gradient', grad)
print('a', a, 'b', b)
这两行可以随时知道for循环中每一次epoc梯度的信息,从而根据梯度是否减小到近似0来判断是否要增加epoch或者修改learning_rate