动手学深度学习(PyTorch版)- 【读书活动-心得分享】Linear regression的实现
[复制链接]
简介
本章节将按照书上提供的教程实现线性回归, 实现对数据的训练, 并且保存模型数据, 当使用的时候加载模型进行数据预测
线形回归通常来将,当数据如果符合高斯分布的话, 可以使用X 的输入来预测Y的输出, 如下图所示, 数据的分布呈现线形关系.
在线形回归中有一个重要的公式, 即下图所示.
Y 则为你需要预测的数值, X为输入, W为X的权重, B则为, W为0的时候Y的值.
在书中实现的线形回归还提供了一个噪声的概念. 如下图所示
那么既然要训练我们需要一个数据集来提供训练的数据. 并且我们还需要从数据集中抽出来一部分来作为测试数据用于使用Square error 来评估模型的精确度.
def synthetic_data(w, b, num_examples): #[url=home.php?mod=space&uid=472666]@save[/url] """⽣成y=Xw+b+噪声"""
X = torch.normal(0, 1, (num_examples, len(w)))
y = torch.matmul(X, w) + b
y += torch.normal(0, 0.01, y.shape)
return X, y.reshape((-1, 1))
上述代码用于生成 X 的输入向量以及 Y的输出标量.
之后定义X的权重,以及 偏差值B, 用于生成数据.
true_w = torch.tensor([2, -3.4]) # 权重
true_b = 4.2 # 偏差值
features, labels = synthetic_data(true_w, true_b, 1000) # 根据权重和偏差值生成1000个数据
根据书上的代码,上述一共生成来1000个数据.
生成的数据格式为下图所示(可以观测到, X是向量, Y为标量)
至此我们的原始数据已经准备好了, 即训练数据,但是我们目前还需要从训练数据中取出来一部分作为测试数据.用于优化我们训练的模型.
def data_iter(batch_size, features, labels):
num_examples = len(features)
# print('长度', num_examples)
indices = list(range(num_examples))
# 这些样本是随机读取的,没有特定的顺序
random.shuffle(indices)
# print(indices)
for i in range(0, num_examples, batch_size):
batch_indices = torch.tensor(
indices[i: min(i + batch_size, num_examples)])
# print('batch_indices',batch_indices)
yield features[batch_indices], labels[batch_indices]
我之前学习Machine learing 的时候都是取20% 作为测试数据. 上述代码主要是用于生成小批量数据,用于优化我们的模型. 上述的代码 到for 之前我都可以看懂, 到for 之后我就看不懂了. 我只知道这个函数可以将数据集的一部分随机打乱然后分割出来一部分作为测试数据.
之后,我们便创建一个权重和偏差值B 用于模型的初始化加载. 并且定义 squared error 作为损失函数用来评估模型的精度. 以及模型模型 linreg()
def sgd(params, lr, batch_size): #@save
"""⼩批量随机梯度下降"""
with torch.no_grad():
for param in params:
param -= lr * param.grad / batch_size
param.grad.zero_()
定义梯度下降的方法用于动态的更新 W 和 B 从而优化模型.
lr = 0.03
num_epochs = 1000
net = linreg
loss = squared_loss
for epoch in range(num_epochs):
for X, y in data_iter(batch_size, features, labels):
l = loss(net(X, w, b), y) # X和y的⼩批量损失
# 因为l形状是(batch_size,1),⽽不是⼀个标量。l中的所有元素被加到⼀起,
# 并以此计算关于[w,b]的梯度
l.sum().backward()
sgd([w, b], lr, batch_size) # 使⽤参数的梯度更新参数
with torch.no_grad():
train_l = loss(net(features, w, b), labels)
print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}')
print(f'w的估计误差: {true_w - w.reshape(true_w.shape)}')
print(f'b的估计误差: {true_b - b}')
torch.save({'weights': w, 'bias': b}, 'linear_regression_model.pth')
通过上述代码对模型进行1000遍梯度下降来优化模型的W和B从而来找到一个最佳的拟合直线来适应我们的model.
我们可以通过上文观测到, 在下降了一千次后, 损失函数已经变得越来越小. w 和 b的精度也在提高. 我们可以将训练的模型数据保存下来. 然后在其他的程序中调用我们这个模型.,
我们新建一个Jupyter 文件, 用于加载模型,并且对数据进行预测
我们可以观测到在上述的输入X向量为 1.4627, 0.1506 的时候输出Y为6.6109
我们用上述的数据和原本的数据进行对比.
可以看到数据基本上满足我们的需求.
|