欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > Python----机器学习(基于PyTorch的线性回归)

Python----机器学习(基于PyTorch的线性回归)

2025/4/3 4:07:20 来源:https://blog.csdn.net/weixin_64110589/article/details/146399669  浏览:    关键词:Python----机器学习(基于PyTorch的线性回归)

一、自求导线性回归与PyTorch的区别

自求导线性回归:

        需要手动定义参数 ww(权重)和 bb(偏置)。

        通过数学公式求导,以便在反向传播中更新参数,通常使用梯度下降法来降低损失值。

PyTorch实现:

        自动处理梯度计算和参数更新。

        使用框架内置的自动微分机制,简化实现过程。

        主要精力放在准备数据、定义模型以及选择损失函数和优化器上。

二、数据准备和模型定义

        在使用PyTorch实现线性回归算法时,我们需要准备好数据集,然后通过框架将前向传播的内容做好,并且“选择”好反向传播过程中所用到的一些参数或者参数更新的方法(如梯度下降)。在选择好输入特征和输出特征后,按照自求导线性回归的思路,我们应该进行 w 和 b 的初始化,给模型一个起始点,使其能够开始学习并逐渐优化参数。而在使用框架实现时,参数的初始化是框架自动处理的(随机值),所以就不用我们再去手动初始化这两个参数了。

三、超参数设置

        损失函数:

                通常选择均方差损失(MSE),这是我们之前一直使用的损失函数。

        优化器:

                使用随机梯度下降(SGD),为参数更新提供依据。

四、梯度下降与随机梯度下降

梯度下降(GD):

        每次迭代计算所有样本的梯度,更新参数。

        适用于小规模数据集,但计算量较大,尤其在大规模数据集上。

随机梯度下降(SGD):

        每次只使用一部分样本来计算梯度,速度更快,适合大规模数据集。

        虽然使用样本梯度来更新参数可能导致更新方向不稳定,从而出现震荡现象并无法收敛到全局最优解,但由于在这里选择全部输入作为样本,所以在实际操作中和梯度下降相似。

五. 迭代过程

        在选择好损失函数及优化器之后,我们就可以进行迭代了。通过不断的迭代更新,使 w 和 b 的值不断更新,从而降低损失函数值,使直线的拟合效果更好。

六、基于PyTorch的线性回归

导入模块

import torch.nn as nn
import numpy as np
import torch
from torch.utils.data import DataLoader, TensorDataset

散点输入

data = np.array([[-0.5, 7.7], [1.8, 98.5], [0.9, 57.8], [0.4, 39.2],[-1.4, -15.7], [-1.4, -37.3], [-1.8, -49.1], [1.5, 75.6],[0.4, 34.0], [0.8, 62.3]
])# 提取x和y并转换为tensor
x_train = torch.tensor(data[:, 0], dtype=torch.float32)
y_train = torch.tensor(data[:, 1], dtype=torch.float32)#*******用于分装张量,组成数据集
dataset=TensorDataset(x_train,y_train)#设置随机数种子
seed=42
torch.manual_seed(seed)
#随机取batch_size个
# dataloader可达代的对象,每次达代会生成一个批次的数,由输入张量和目标张量元组 组成
dataloader=DataLoader(dataset,batch_size=10,shuffle=True)

定义前向模型

1、直接定义

        这种方式直接创建一个线性层模型,输入一个特征,输出一个特征。适合简单的线性回归任务。

line_model=nn.Linear(1,1)#输入特征,输出特征

2、n.Sequential

        nn.Sequential 是一个容器,可以按顺序组合多个层。在这种情况下,它包含一个线性层。适合顺序结构简单的模型。

#nn.Sequential是pytorch的一个模块容器,按顺序组合多个网络层
line_model=nn.Sequential(nn.Linear(1,1))

3、nn.ModuleList

        nn.ModuleList允许将层放在一个列表中,可以灵活管理,更适合需要多个层的模型结构。forward 方法定义了输入如何通过这些层进行前向传播。

# nn.ModuleList
#forward方法会定义模型前向传播的逻辑,给定输入,经过逻辑,得出输出class LinearModel(nn.Module):def __init__(self):super(LinearModel,self).__init__()self.layers=nn.ModuleList([nn.Linear(1,1)])def forward(self,x):for layer in self.layers:x=layer(x)return x
line_model=LinearModel()

4、nn.ModuleDict

        nn.ModuleDict允许为每个层赋予名字,便于管理和访问。特别适合需要命名的复杂模型。

#可以给每个层自定义名字
# nn.ModuleDict
class LinearModel(nn.Module):def __init__(self):super(LinearModel,self).__init__()self.layers=nn.ModuleDict({'liner':nn.Linear(1,1)})def forward(self,x):for layer in self.layers.values():x=layer(x)return x
line_model=LinearModel()

5、高频率使用

        在这种方式中,模型中定义了多个层。self.liner1 和 self.liner2 赋予各层的名称,使得在 forward 方法中容易使用和复用。适用于复杂的模型构建。

class LinearModel(nn.Module):def __init__(self):super(LinearModel,self).__init__()self.liner1=nn.Linear(1,1)self.liner2=nn.Linear(1,1)def forward(self,x):x=self.liner1(x)# x=self.liner2(x)return x
line_model=LinearModel()

总结
        根据模型的复杂程度和需求,可以选择不同的定义方式。简单任务可以用直接定义或 nn.Sequential 进行,而复杂的模型则可以使用 nn.ModuleList 或 nn.ModuleDict 来管理多个层,方便扩展和维护。高频率使用的方式适合在构建需要多个层的网络时使用。

定义损失函数和优化器

#损失函数(均方差损失)
criterion=nn.MSELoss()#优化器
optimzer=torch.optim.SGD(line_model.parameters(),lr=0.01)

迭代拟合显示

for i in range(1,501):total_loss=0for x,y in dataloader:y_hat=line_model(x.unsqueeze(1))#计算损失loss=criterion(y_hat.squeeze(1),y)total_loss+=loss#清空之前存储在优化器中的梯度optimzer.zero_grad()#计算损失函数关于模型参数的梯度loss.backward()#根据优化算法去更新参数optimzer.step()avg_loss=total_loss/len(dataloader)#5.显示if i%10==0 or i==1:print(i,avg_loss.item())# pass
'''
1 2811.569091796875
10 1693.6490478515625
20 976.31298828125
30 573.5284423828125
40 346.38092041015625
50 217.63870239257812
60 144.24981689453125
70 102.14170837402344
80 77.80529022216797
90 63.62700271606445
100 55.29475021362305
110 50.35265350341797
120 47.3928337097168
130 45.602577209472656
140 44.50886154174805
150 43.83409881591797
160 43.413795471191406
170 43.14963912963867
180 42.98223114013672
190 42.87529373168945
200 42.8065185546875
210 42.762001037597656
220 42.7330436706543
230 42.714115142822266
240 42.70168685913086
250 42.6934928894043
260 42.68808364868164
270 42.684505462646484
280 42.6821174621582
290 42.6805419921875
300 42.67948913574219
310 42.67878341674805
320 42.678314208984375
330 42.678001403808594
340 42.67778778076172
350 42.67765426635742
360 42.67755889892578
370 42.67750930786133
380 42.67746353149414
390 42.67744445800781
400 42.67741775512695
410 42.67740249633789
420 42.677398681640625
430 42.677391052246094
440 42.67738342285156
450 42.6773796081543
460 42.67737579345703
470 42.6773796081543
480 42.67737579345703
490 42.67737579345703
500 42.67737579345703
'''

完整代码 

import torch.nn as nn  
import numpy as np  
import torch  
from torch.utils.data import DataLoader, TensorDataset  # 1. 散点输入数据 (输入数据点)  
data = np.array([  [-0.5, 7.7], [1.8, 98.5], [0.9, 57.8], [0.4, 39.2],  [-1.4, -15.7], [-1.4, -37.3], [-1.8, -49.1], [1.5, 75.6],  [0.4, 34.0], [0.8, 62.3]  
])  # 提取x和y并转换为tensor (提取输入特征和目标值并转换为张量)  
x_train = torch.tensor(data[:, 0], dtype=torch.float32)  # 输入特征 (Input feature)  
y_train = torch.tensor(data[:, 1], dtype=torch.float32)  # 目标值 (Target value)  #*******用于分装张量,组成数据集 (将张量打包成数据集)  
dataset = TensorDataset(x_train, y_train)  # 设置随机数种子 (为了结果可重现设置随机种子)  
seed = 42  
torch.manual_seed(seed)  # 随机取batch_size个 (随机选择batch_size个样本)  
# dataloader是一个可迭代对象,每次迭代会生成一批数据,由输入张量和目标张量组成 (DataLoader是一个可迭代对象,每次迭代会生成一个批次的输入与目标张量)  
dataloader = DataLoader(dataset, batch_size=10, shuffle=True)  # 2. 定义前向模型 (定义线性模型)  
class LinearModel(nn.Module):  def __init__(self):  super(LinearModel, self).__init__()  self.liner1 = nn.Linear(1, 1)  # 第一层线性变换 (第一个线性层)  self.liner2 = nn.Linear(1, 1)  # 第二层线性变换 (第二个线性层,当前未使用)  def forward(self, x):  x = self.liner1(x)  # 将输入x通过第一层 (将输入x传入第一层线性变换)  # x = self.liner2(x)  # 将输入x通过第二层 (将输入x传入第二层线性变换,当前已注释)  return x  # 返回经过处理的x (返回处理后的x)  line_model = LinearModel()  # 实例化线性模型 (创建线性模型的实例)  # 损失函数(均方差损失)(损失函数: 均方误差损失)  
criterion = nn.MSELoss()  # 优化器 (设置优化器)  
optimzer = torch.optim.SGD(line_model.parameters(), lr=0.01)  # 使用随机梯度下降优化器  # 训练模型  
for i in range(1, 501):  total_loss = 0  # 初始化总损失 (初始化总损失)  for x, y in dataloader:  # 遍历数据加载器中的批次 (遍历数据加载器中的每一个批次)  y_hat = line_model(x.unsqueeze(1))  # 获取模型的预测值 (通过模型得到预测值)  # 计算损失 (计算预测值与真实值之间的损失)  loss = criterion(y_hat.squeeze(1), y)  # 计算预测值和真实值的损失  total_loss += loss  # 累加损失 (将当前批次的损失加入总损失)  # 清空之前存储在优化器中的梯度 (清空优化器中的梯度信息)  optimzer.zero_grad()  # 计算损失函数关于模型参数的梯度 (计算损失函数相对于模型参数的梯度)  loss.backward()  # 根据优化算法更新参数 (根据优化算法更新模型参数)  optimzer.step()  avg_loss = total_loss / len(dataloader)  # 计算平均损失 (计算当前周期的平均损失)  # 5. 显示 (每隔一定轮数显示结果)  if i % 10 == 0 or i == 1:  # 每10轮或第一轮显示一次 (每10次迭代或第一次迭代时输出平均损失)  print(i, avg_loss.item())  

七、库函数

7.1、TensorDataset()

        是 PyTorch 中的一个类,用于将多个张量组合成一个数据集。它方便地将输入数据和目标数据成对存储,可以通过索引访问。

7.2、DataLoader()

        是一个 PyTorch 提供的工具,用于在训练过程中批量加载数据。它支持打乱数据、并行加载、以及自动生成批次。

DataLoader(dataset, batch_size=2, shuffle=True)
方法描述
dataset数据集
batch_size每个批次的样本数量。
shuffle是否在每个epoch前打乱数据。

7.3、Sequential()

         是一个容器,用于按顺序将多个子模块堆叠到一起。用于快速构建简单的前馈神经网络。

import torch.nn as nnmodel = nn.Sequential(nn.Linear(1, 10),nn.ReLU(),nn.Linear(10, 1)
)

输入首先经过一个线性层,然后通过 ReLU 激活函数,最后再通过一个线性层。 

7.4、ModuleList()

        是一个模块容器,用于存储子模块的有序列表。它让我们可以在迭代时灵活地构造模型,特别是在需要动态网络结构时。 

7.5、ModuleDict()

        但它允许通过字典的方式存储子模块。它提供了键值对的方式来访问子模块。

7.6、MSELoss()

        是 PyTorch 中用于计算均方误差损失(Mean Squared Error Loss)的类。通常用于回归任务,衡量预测值和真实值之间的差异。

criterion(predictions, targets) 
方法描述
predictions是模型的预测值
targets是真实值

7.7、SGD()

        代表随机梯度下降(Stochastic Gradient Descent),是用于优化模型的算法。它根据当前梯度来更新模型参数。

torch.optim.SGD(model.parameters(), lr=0.01)
方法描述
params要优化的参数(通常是模型的参数)。
lr学习率(learning rate),决定每次参数更新的步长。

7.8、zero_grad()

        用来清空优化器中累积的梯度,以避免梯度在每次迭代中累加。

7.9、backward()

        用来计算当前损失相对于模型参数的梯度。

7.10、step()

        方法用于根据当前累积的梯度更新模型参数。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词