御坂10032号 发表于 2024-10-29 15:56

动手学深度学习(PyTorch版)- 【读书活动-心得分享】Linear regression的实现

<p><strong><span style="font-size:22px;">简介</span></strong></p>

<p>&nbsp;</p>

<p>本章节将按照书上提供的教程实现线性回归, 实现对数据的训练, 并且保存模型数据, 当使用的时候加载模型进行数据预测</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>线形回归通常来将,当数据如果符合高斯分布的话, 可以使用X 的输入来预测Y的输出, 如下图所示, 数据的分布呈现线形关系.</p>

<p></p>

<p>&nbsp;</p>

<p>在线形回归中有一个重要的公式, 即下图所示.</p>

<p>&nbsp;</p>

<p></p>

<p>&nbsp;</p>

<p>Y 则为你需要预测的数值, X为输入, W为X的权重, B则为, W为0的时候Y的值.</p>

<p>&nbsp;</p>

<p>在书中实现的线形回归还提供了一个噪声的概念. 如下图所示<br />
<br />
</p>

<p>那么既然要训练我们需要一个数据集来提供训练的数据. 并且我们还需要从数据集中抽出来一部分来作为测试数据用于使用Square error 来评估模型的精确度.</p>

<p>&nbsp;</p>

<pre>
<code class="language-python">def synthetic_data(w, b, num_examples):#@save """⽣成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))</code></pre>

<p>&nbsp;&nbsp;&nbsp;</p>

<p>上述代码用于生成 X 的输入向量以及 Y的输出标量.</p>

<p>&nbsp;</p>

<p>之后定义X的权重,以及 偏差值B, 用于生成数据.</p>

<p>&nbsp;</p>

<pre>
<code class="language-python">true_w = torch.tensor()# 权重
true_b = 4.2# 偏差值

features, labels = synthetic_data(true_w, true_b, 1000)# 根据权重和偏差值生成1000个数据</code></pre>

<p>&nbsp;</p>

<p>根据书上的代码,上述一共生成来1000个数据.&nbsp;</p>

<p>&nbsp;</p>

<p>生成的数据格式为下图所示(可以观测到, X是向量, Y为标量)</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>至此我们的原始数据已经准备好了, 即训练数据,但是我们目前还需要从训练数据中取出来一部分作为测试数据.用于优化我们训练的模型.</p>

<p>&nbsp;</p>

<pre>
<code class="language-python">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)
      # print('batch_indices',batch_indices)
    yield features, labels</code></pre>

<p>我之前学习Machine learing 的时候都是取20% 作为测试数据. 上述代码主要是用于生成小批量数据,用于优化我们的模型.&nbsp; 上述的代码 到for 之前我都可以看懂, 到for 之后我就看不懂了. 我只知道这个函数可以将数据集的一部分随机打乱然后分割出来一部分作为测试数据.</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>之后,我们便创建一个权重和偏差值B 用于模型的初始化加载. 并且定义 squared error 作为损失函数用来评估模型的精度. 以及模型模型 linreg()</p>

<p>&nbsp;</p>

<pre>
<code class="language-python">def sgd(params, lr, batch_size): #@save
    """⼩批量随机梯度下降"""
    with torch.no_grad():
      for param in params:
            param -= lr * param.grad / batch_size
            param.grad.zero_()</code></pre>

<p>&nbsp;</p>

<p>定义梯度下降的方法用于动态的更新 W 和 B 从而优化模型.</p>

<p>&nbsp;</p>

<pre>
<code class="language-python">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中的所有元素被加到⼀起,
      # 并以此计算关于的梯度
      l.sum().backward()
      sgd(, 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')
</code></pre>

<p>&nbsp;</p>

<p>通过上述代码对模型进行1000遍梯度下降来优化模型的W和B从而来找到一个最佳的拟合直线来适应我们的model.</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>我们可以通过上文观测到, 在下降了一千次后, 损失函数已经变得越来越小. w 和 b的精度也在提高. 我们可以将训练的模型数据保存下来.&nbsp; 然后在其他的程序中调用我们这个模型.,</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>我们新建一个Jupyter 文件, 用于加载模型,并且对数据进行预测</p>

<p><br />
&nbsp;</p>

<p>&nbsp; 我们可以观测到在上述的输入X向量为 1.4627, 0.1506 的时候输出Y为6.6109&nbsp;<br />
&nbsp;</p>

<p>&nbsp;我们用上述的数据和原本的数据进行对比.</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>可以看到数据基本上满足我们的需求.</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<div></div>

wangerxian 发表于 2024-10-29 19:11

<p>线性回归一般适用于什么样的数据?</p>

御坂10032号 发表于 2024-10-29 19:51

wangerxian 发表于 2024-10-29 19:11
线性回归一般适用于什么样的数据?

<p>符合高斯分布,方差较小, 有线形关系.&nbsp; 自变量因变量联系较强的数据</p>

wangerxian 发表于 2024-10-30 09:24

御坂10032号 发表于 2024-10-29 19:51
符合高斯分布,方差较小, 有线形关系.&nbsp; 自变量因变量联系较强的数据

<p>明白了,感谢科普。</p>

ljg2np 发表于 2024-10-31 21:12

<p></p>


<p>如果机子没有配置GPU,假设误差符合高斯分布,能用pyTorch进行线性回归吗?如果可以,在时间上的开销大不大?可不可以处理分类情况?</p>

御坂10032号 发表于 2024-10-31 23:59

ljg2np 发表于 2024-10-31 21:12
如果机子没有配置GPU,假设误差符合高斯分布,能用pyTorch进行线性回归吗?如果可以,在时间上的开销大 ...

<p>现在上述的代码都是使用的CPU跑的, 我的那个MAC book pro GPU垃圾的很, 1.5GB的核心显卡.&nbsp; 分类的话要用softmx这两天正在学习. 有点难懂数学. 我现在学这个和看书算是知道了. 看明白咋回事 知道咋用就行了. 要是去看数学, 半年我感觉都学不会 数学基础太薄弱了. 你可以看下B站上有视频的</p>

ljg2np 发表于 2024-11-1 05:16

<div class='shownolgin' data-isdigest='no'>御坂10032号 发表于 2024-10-31 23:59
现在上述的代码都是使用的CPU跑的, 我的那个MAC book pro GPU垃圾的很, 1.5GB的核心显卡.&nbsp; 分类的话 ...

<p>也能够使用CPU来跑,太好了,这么看来pyTorch还是很亲民的。{:1_138:}</p>
</div><script>showreplylogin();</script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>
页: [1]
查看完整版本: 动手学深度学习(PyTorch版)- 【读书活动-心得分享】Linear regression的实现