实验目的
使用 TensorFlow2 基础类 api 训练一个线性回归模型。
实验步骤
本次实验所使用的环境如下:
import tensorflow as tf
print(tf.__version__)
2.3.0
1. 构造训练数据集
通过如下代码,生成训练数据集:
# 实际的线
TRUE_W = 5.0
TRUE_B = 10.0
NUM_EXAMPLES = 1000
# 随机向量x
x = tf.random.normal(shape=[NUM_EXAMPLES])
# 生成噪声
noise = tf.random.normal(shape=[NUM_EXAMPLES])
# 计算y
y = x * TRUE_W + TRUE_B + noise
绘制训练数据集的图形,如下:
# 绘制所有的数据
import matplotlib.pyplot as plt
plt.scatter(x, y, c="b")
plt.show()
2. 自定义模型
2.1 通过如下代码,构建自定义模型。自定义的模型继承 tf.keras.Model
类。
# 自定义模型
class Mymodel(tf.keras.Model):
def __init__(self):
super().__init__()
self.w = tf.Variable(0.5, name='w')
self.b = tf.Variable(0.0, name='b')
def call(self, x):
return self.w * x + self.b
2.2 实例化自定义模型
#实例化模型
model = Mymodel()
2.3 查看模型的可训练参数
# 查看model中,可训练的参数
print(model.variables)
[<tf.Variable ‘w:0’ shape=() dtype=float32, numpy=0.5>,
<tf.Variable ‘b:0’ shape=() dtype=float32, numpy=0.0>]
3. 定义损失函数
定义损失函数,如下:
def loss(target_y, predict_y):
return tf.reduce_mean(tf.square(target_y - predict_y))
核查损失函数是否正常执行:
print(loss(1,3).numpy())
4
4. 定义循环训练
定义循环训练的函数,参数包括:模型、x、y 和学习率。返回当前 epoch
的损失值。
def train(model, x, y, learning_rate):
# GradientTape 跟踪可训练变量
with tf.GradientTape() as t:
current_loss = loss(y, model(x))
# gradient 计算变量梯度
dw, db = t.gradient(current_loss, [model.w, model.b])
# 减去由学习率缩放的梯度
model.w.assign_sub(learning_rate*dw)
model.b.assign_sub(learning_rate*db)
return current_loss
5. 执行循环训练
# 用于保存训练过程中的参数
Ws = []
bs = []
def train_loops(model, x, y):
epochs = range(15) # 训练10个epoch
for epoch in epochs:
# 学习率设为0.1
current_loss = train(model, x, y, learning_rate=0.1)
Ws.append(model.w.numpy())
bs.append(model.b.numpy())
# 输出训练的中间信息
print('Epoch {}: W={} b={}, loss={}\n'.format(epoch, Ws[-1], bs[-1], current_loss))
训练的中间信息,如下:
Epoch 0: W=1.539263129234314 b=2.064530611038208, loss=128.06124877929688
Epoch 1: W=2.343231678009033 b=3.7026352882385254, loss=80.26222229003906
Epoch 2: W=2.964644193649292 b=5.002660274505615, loss=50.46760177612305
Epoch 3: W=3.4445126056671143 b=6.0345964431762695, loss=31.88780975341797
Epoch 4: W=3.8147130012512207 b=6.853902816772461, loss=20.29638671875
Epoch 5: W=4.100006580352783 b=7.5045318603515625, loss=13.061426162719727
Epoch 6: W=4.31961727142334 b=8.021324157714844, loss=8.543405532836914
Epoch 7: W=4.48845911026001 b=8.431900978088379, loss=5.720578670501709
Epoch 8: W=4.618096351623535 b=8.758166313171387, loss=3.9559485912323
Epoch 9: W=4.717489242553711 b=9.017491340637207, loss=2.8522050380706787
Epoch 10: W=4.79357385635376 b=9.223658561706543, loss=2.161428928375244
Epoch 11: W=4.851716995239258 b=9.387602806091309, loss=1.7288411855697632
Epoch 12: W=4.896065711975098 b=9.518001556396484, loss=1.4577659368515015
Epoch 13: W=4.929823398590088 b=9.621744155883789, loss=1.2877874374389648
Epoch 14: W=4.955461025238037 b=9.704298973083496, loss=1.1811275482177734
训练结果显示,经15个 epoch 后,w值为 4.955, b值为 9.7。 已经非常接近真实值了。
6. 可视化结果
绘制训练后的图形,如下。其中,红色的为模型拟合的函数:
# 可视化训练后的模型如何执行
plt.scatter(x, y, c="b")
plt.scatter(x, model(x), c="r")
plt.show()
参考资料
https://tensorflow.google.cn/guide/basic_training_loops?hl=zh_cn