这里我们实现的是接上一篇的从0开始的线性回归,TF-2.x中有比较简洁的实现方式。mxnet中也有对应章节:MXNET深度学习框架-04-使用gluon实现线性回归
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)
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
def linreg():
model=tf.keras.Sequential()
model.add(tf.keras.layers.Dense(1,kernel_initializer=tf.random_normal_initializer(stddev=0.01)))
return model
loss = tf.losses.MeanSquaredError()
trainer = tf.keras.optimizers.SGD(learning_rate=0.03)
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))
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])