TensorFlow-2.x-02-线性回归的简洁实现

        这里我们实现的是接上一篇的从0开始的线性回归,TF-2.x中有比较简洁的实现方式。mxnet中也有对应章节:MXNET深度学习框架-04-使用gluon实现线性回归

1、生成数据集

num_inputs = 2
num_examples = 1000
true_w = [2, -3.4] #真实权重
true_b = 4.2 # 真实偏置值
features = tf.random.normal((num_examples, num_inputs),stddev =1)
labels = true_w[0] * features[:,0] + true_w[1] * features[:,1] + true_b
labels += tf.random.normal(labels.shape,stddev=0.01)

2、读取数据集

batch_size = 10
# 将训练数据的特征和标签组合
dataset = tfdata.Dataset.from_tensor_slices((features, labels))
# 随机读取小批量
dataset = dataset.shuffle(buffer_size=num_examples) #shuffle 的 buffer_size 参数应大于等于样本数,相当于开辟一个存储数据的空间,batch 可以指定 batch_size 的分割大小。
dataset = dataset.batch(batch_size) #取数据

for batch_x, batch_y in dataset :
    print(batch_x, batch_y)
    break

结果:
在这里插入图片描述

3、定义模型和初始化参数

def linreg():
    model=tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(1,kernel_initializer=tf.random_normal_initializer(stddev=0.01)))
    return model

4、定义损失函数

loss = tf.losses.MeanSquaredError()

5、定义优化器

trainer = tf.keras.optimizers.SGD(learning_rate=0.03)

6、训练

num_epochs = 10
for epoch in range(1, num_epochs + 1):
    train_loss, num_count = 0, 0
    for X, y in dataset:
        num_count+=1
        with tf.GradientTape() as tape:
            l = loss(net(X, training=True), y)
        grads = tape.gradient(l, net.trainable_variables) #通过 model.trainable_variables 找到需要更新的变量
        trainer.apply_gradients(zip(grads, net.trainable_variables))#使用 trainer.apply_gradients 更新权重
        train_loss += tf.reduce_sum(l).numpy()
    print('epoch %d, loss: %f' % (epoch, train_loss/num_count))

结果:
在这里插入图片描述

7、预测结果

print(true_w, net.get_weights()[0])
print(true_b,net.get_weights()[1])

结果:
在这里插入图片描述
        可以看到,上节我们使用了整整50个epoch才将loss训练到比较小的地步,而使用高阶API,训练速度还加快了。

下面附上所有代码:

import tensorflow as tf

from tensorflow import data as tfdata

#1、生成数据集
tf.random.set_seed(99)
num_inputs = 2
num_examples = 1000
true_w = [2, -3.4] #真实权重
true_b = 4.2 # 真实偏置值
features = tf.random.normal((num_examples, num_inputs),stddev =1)
labels = true_w[0] * features[:,0] + true_w[1] * features[:,1] + true_b
labels += tf.random.normal(labels.shape,stddev=0.01)

#2、读取数据
batch_size = 10
# 将训练数据的特征和标签组合
dataset = tfdata.Dataset.from_tensor_slices((features, labels))
# 随机读取小批量
dataset = dataset.shuffle(buffer_size=num_examples) #shuffle 的 buffer_size 参数应大于等于样本数,相当于开辟一个存储数据的空间,batch 可以指定 batch_size 的分割大小。
dataset = dataset.batch(batch_size) #取数据

for batch_x, batch_y in dataset:
    print(batch_x, batch_y)
    break

#3、定义模型和初始化参数
def linreg():
    model=tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(1,kernel_initializer=tf.random_normal_initializer(stddev=0.01)))
    return model

net=linreg()

#4、定义损失函数
loss = tf.losses.MeanSquaredError()

#5、定义优化器
trainer = tf.keras.optimizers.SGD(learning_rate=0.03)

#6、训练
'''
通过调用tf.GradientTape记录动态图梯度,执行tape.gradient获得动态图中各变量梯度。
通过 model.trainable_variables 找到需要更新的变量,并用 trainer.apply_gradients 更新权重,
完成一步训练。
'''
num_epochs = 10
for epoch in range(1, num_epochs + 1):
    train_loss, num_count = 0, 0
    for X, y in dataset:
        num_count+=1
        with tf.GradientTape() as tape:
            l = loss(net(X, training=True), y)
        grads = tape.gradient(l, net.trainable_variables) #通过 model.trainable_variables 找到需要更新的变量
        trainer.apply_gradients(zip(grads, net.trainable_variables))#使用 trainer.apply_gradients 更新权重
        train_loss += tf.reduce_sum(l).numpy()
    print('epoch %d, loss: %f' % (epoch, train_loss/num_count))

#7、预测结果
print(true_w, net.get_weights()[0])
print(true_b,net.get_weights()[1])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章