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]
"""
相关推荐
丢爸2 小时前
网络学习-eNSP配置NAT
linux·网络·学习
YHPsophie2 小时前
AT3340-6T杭州中科微BDS定位授时板卡性能指标
经验分享·笔记·学习·车载系统·信息与通信
6230_3 小时前
关于HTTP通讯流程知识点补充—常见状态码及常见请求方式
前端·javascript·网络·网络协议·学习·http·html
日记成书4 小时前
【无线通信发展史⑨】1791年路易吉·伽伐尼-关于动物电的研究与1800年亚历山大·伏打伯爵-电池:伏打电池
网络·人工智能·学习·职场和发展·信息与通信
贾saisai4 小时前
Xilinx系FPGA学习笔记(四)VIO、ISSP(Altera)及串口学习
笔记·学习·fpga开发
月夕花晨3744 小时前
C++学习笔记(13)
c++·笔记·学习
probably1215 小时前
学习记录之Java学习笔记3
java·笔记·学习
东华果汁哥5 小时前
【深度学习 CV方向】图像算法工程师 职业发展路线,以及学习路线
深度学习·学习·算法
Alan-Xia6 小时前
Vue响应式进阶常用API之effectScope、getCurrentScope、onScopeDispose学习
前端·vue.js·学习
Milo_K6 小时前
java学习笔记-IO流(韩顺平)
java·笔记·学习