tensorflow线性回归实现----学习笔记(六)

生成数据

python 复制代码
import numpy as np
import tensorflow as tf


def synthetic_data(w, b, num_examples):  #@save
    """生成y=Xw+b+噪声"""
    X = np.random.normal(0, 1, (num_examples, len(w)))
    y = np.dot(X, w) + b
    y += np.random.normal(0, 0.01, y.shape)
    return X, y.reshape((-1, 1))
    
true_w = np.array([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)
print(features, labels)
"""
[[-0.72829442  0.28627095]
 [ 0.36255666 -0.02462779]
 [ 0.36165113  1.40668422]
 ...
 [-0.29412206  1.65748974]
 [-0.22146256 -0.21816244]
 [-0.72305393 -1.61769361]]
[[ 9.59143174e+00]
 [ 8.05332137e+00]
 [-1.57522899e+00]
 [ 1.24086539e+00]
 [ 6.02113875e+00]
 ........
 [ 1.27598160e+01]
[ 1.11763989e+01]]
"""

读取数据集

我们可以调用框架中现有的API来读取数据。 我们将features和labels作为API的参数传递,并通过数据迭代器指定batch_size。 此外,布尔值is_train表示是否希望数据迭代器对象在每个迭代周期内打乱数据。

python 复制代码
def load_array(data_arrays, batch_size, is_train=True):  #@save
    """构造一个TensorFlow数据迭代器"""
    dataset = tf.data.Dataset.from_tensor_slices(data_arrays)
    if is_train:
        dataset = dataset.shuffle(buffer_size=1000)
    dataset = dataset.batch(batch_size)
    return dataset

batch_size = 10
data_iter = load_array((features, labels), batch_size)
print(data_iter)
"""
<BatchDataset element_spec=(TensorSpec(shape=(None, 2), dtype=tf.float64, name=None), TensorSpec(shape=(None, 1), dtype=tf.float64, name=None))>
"""

定义模型

对于标准深度学习模型,我们可以使用框架的预定义好的层。这使我们只需关注使用哪些层来构造模型,而不必关注层的实现细节。 我们首先定义一个模型变量net,它是一个Sequential类的实例。 Sequential类将多个层串联在一起。 当给定输入数据时,Sequential实例将数据传入到第一层, 然后将第一层的输出作为第二层的输入,以此类推。

在Keras中,全连接层在Dense类中定义。 由于我们只想得到一个标量输出,所以我们将该数字设置为1。

值得注意的是,为了方便使用,Keras不要求我们为每个层指定输入形状。 所以在这里,我们不需要告诉Keras有多少输入进入这一层。 当我们第一次尝试通过我们的模型传递数据时,例如,当后面执行net(X)时, Keras会自动推断每个层输入的形状。

python 复制代码
initializer = tf.initializers.RandomNormal(stddev=0.01)
net = tf.keras.Sequential()
net.add(tf.keras.layers.Dense(1, kernel_initializer=initializer))

在执行时,初始化实际上是推迟(deferred)执行的。 只有在我们第一次尝试通过网络传递数据时才会进行真正的初始化。 因为参数还没有初始化,所以我们不能访问或操作它们。

定义损失函数

计算均方误差使用的是MeanSquaredError类,也称为平方 L 2 L_2 L2范数。 默认情况下,它返回所有样本损失的平均值。

python 复制代码
loss = tf.keras.losses.MeanSquaredError()

定义优化算法

小批量随机梯度下降算法是一种优化神经网络的标准工具, Keras在optimizers模块中实现了该算法的许多变种。 小批量随机梯度下降只需要设置learning_rate值,这里设置为0.03。

python 复制代码
trainer = tf.keras.optimizers.SGD(learning_rate=0.03)

训练

通过深度学习框架的高级API来实现我们的模型只需要相对较少的代码。 我们不必单独分配参数、不必定义我们的损失函数,也不必手动实现小批量随机梯度下降。 当我们需要更复杂的模型时,高级API的优势将大大增加。

在每个迭代周期里,我们将完整遍历一次数据集(train_data), 不停地从中获取一个小批量的输入和相应的标签。 对于每一个小批量,我们会进行以下步骤:

  • 通过调用net(X)生成预测并计算损失l(前向传播)。
  • 通过进行反向传播来计算梯度。
  • 通过调用优化器来更新模型参数。

为了更好的衡量训练效果,我们计算每个迭代周期后的损失,并打印它来监控训练过程。

python 复制代码
num_epochs = 3
for epoch in range(num_epochs):
    for X, y in data_iter:
        with tf.GradientTape() as tape:
            l = loss(net(X, training=True), y)
        grads = tape.gradient(l, net.trainable_variables)
        trainer.apply_gradients(zip(grads, net.trainable_variables))
    l = loss(net(features), labels)
    print(f'epoch {epoch + 1}, loss {l:f}')
"""
epoch 1, loss 0.000248
epoch 2, loss 0.000100
epoch 3, loss 0.000100
"""

下面我们比较生成数据集的真实参数和通过有限数据训练获得的模型参数。 要访问参数,我们首先从net访问所需的层,然后读取该层的权重和偏置。 正如在从零开始实现中一样,我们估计得到的参数与生成数据的真实参数非常接近。

python 复制代码
w = net.get_weights()[0]
print('w的估计误差:', true_w - tf.reshape(w, true_w.shape))
b = net.get_weights()[1]
print('b的估计误差:', true_b - b)
"""
w的估计误差: tf.Tensor([ 6.8998337e-04 -4.7445297e-05], shape=(2,), dtype=float32)
b的估计误差: [0.00044203]
"""
相关推荐
知识分享小能手1 小时前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
茯苓gao4 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾4 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
DKPT5 小时前
Java内存区域与内存溢出
java·开发语言·jvm·笔记·学习
aaaweiaaaaaa5 小时前
HTML和CSS学习
前端·css·学习·html
看海天一色听风起雨落6 小时前
Python学习之装饰器
开发语言·python·学习
speop7 小时前
llm的一点学习笔记
笔记·学习
非凡ghost7 小时前
FxSound:提升音频体验,让音乐更动听
前端·学习·音视频·生活·软件需求
ue星空7 小时前
月2期学习笔记
学习·游戏·ue5
萧邀人8 小时前
第二课、熟悉Cocos Creator 编辑器界面
学习