上一节:线性回归的从零开始 用tensorflow2.0推荐的keras接口实现线性回归的训练。
1. 生成数据集
使用与上一节中相同的数据集。其中features
是训练数据特征,labels
是标签。
import tensorflow as tf
num_inputs = 2
num_examples = 1000
true_w = [2, -3.4]
true_b = 4.2
features = tf.random.normal(shape=(num_examples, num_inputs), stddev=1)
labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b
labels += tf.random.normal(shape=(labels.shape), stddev=0.01)
2. 读取数据
使用tensorflow中的data模块读取数据
from tensorflow import data as tfdata
batch_size = 10
#将训练数据的特征和标签组合
dataset = tfdata.Dataset.from_tensor_slices((features, labels))
#随机读取小批量
dataset = dataset.shuffle(buffer_size=num_examples)
dataset = dataset.batch(batch_size)
data_iter = iter(dataset)
shuffle
的buffer_size
参数应大于样本数,batch
可以指定batch_size
的分割大小。
for X, y in data_iter:
print(X, y)
break
3 定义模型和初始化参数
使用keras
定义网络,先定义一个模型变量model
,它是一个Sequential
实例。在Keras
中,Sequential
实例可以看作一个串联各个层的容器。
在构造模型时,我们在该容器中依次添加层。当给定输入数据时,容器中的每一层将依次推断下一层的输入尺寸。重要的一点是,在keras
中,我们无需指定每一层输入的形状。线性回归,输入层与输出层等效为一层全连接层keras.layers.Dense()
。
keras
中初始化参数由kernel_initializer
和bias_initializer
选项分别设置权重和偏置的初始化方式。我们从tensorflow
导入initializers
模块,指定权重参数每个元素将在初始化时随机采样于均值为0、标准差为0.01的正态分布。偏差参数默认会初始化为0。RandomNormal(stddev=0.01)
指定权重参数每个元素将在初始化时随机采样于均值为0、标准差为0.01的正态分布。偏差参数默认会初始化为0。
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow import initializers as init
model = keras.Sequential()
model.add(layers.Dense(1, kernel_initializer=init.RandomNormal(stddev=0.01)))
4 定义损失函数
Tensorflow
在losses
模块中提供了各种损失函数和自定义损失函数的基类,并直接使用它的均方误差损失作为模型的损失函数。
from tensorflow import losses
loss = losses.MeanSqyaredError()
5 定义优化算法
tensorflow.keras.optimizers
模块提供了很多常用的优化算法比如SGD、Adam和RMSProp等。下面创建一个用于优化model所有参数的优化器实例,并指定学习率为0.03的小批量随机梯度下降(SGD)为优化算法。
6 训练模型
在使用Tensorflow
训练模型时,我们通过调用tensorflow.GradientTape
记录动态图梯度。通过model.trainable_variables
找到需要更新的变量,并用trainer.apply_gradients
更新权重,完成一步训练。
num_epochs = 3
for epoch in range(1, num_epochs + 1):
for (batch, (X, y)) in enumrate(dataset):
with tf.GradientTape() as tape:
l = loss(model(X, training=True), y)
grads = tape.gradient(l, model.trainable_variables)
trainer.apply_gradients(zip(grads, model.trainable_variables))
l = loss(model(features), labels)
print('epoch %d, loss: %f' % (epoch, l))
输出:
epoch 1, loss: 0.519287
epoch 2, loss: 0.008997
epoch 3, loss: 0.000261
比较学习得到的模型参数和真实的模型参数。
使用model的get_weights()
来获得其权重(weights
)和偏差(bias
)。
true_w, model.get_weights()[0]
true_b, model.get_weights()[1]
输出:
([2, -3.4], array([[ 1.9930198],
[-3.3977082]], dtype=float32))
(4.2, array([4.1895046], dtype=float32))