校园网网站建设规划书,中国沙漠建设 志愿者 兵团官方网站,汇鑫网站建设便捷,wordpress服务本地目录
1 Pytorch实现线性回归
1.1 实现思路
1.2 完整代码
2 各部分代码逐行详解
2.1 准备数据集
2.2 设计模型
2.2.1 代码
2.2.2 代码逐行详解
2.2.3 疑难点解答
2.3 构建损失函数和优化器
2.4 训练周期
2.5 测试结果
3 线性回归中常用优化器 1 Pytorch实现线性回归…目录
1 Pytorch实现线性回归
1.1 实现思路
1.2 完整代码
2 各部分代码逐行详解
2.1 准备数据集
2.2 设计模型
2.2.1 代码
2.2.2 代码逐行详解
2.2.3 疑难点解答
2.3 构建损失函数和优化器
2.4 训练周期
2.5 测试结果
3 线性回归中常用优化器 1 Pytorch实现线性回归
1.1 实现思路 图1 实现线性回归主要过程图2 线性回归计算图1.2 完整代码
import torch
x_data torch.Tensor([[1.0], [2.0], [3.0]])
y_data torch.Tensor([[2.0], [4.0], [6.0]])
class LinearModel(torch.nn.Module):def __init__(self):super(LinearModel, self).__init__()self.linear torch.nn.Linear(1, 1)def forward(self, x):y_pred self.linear(x)return y_pred
model LinearModel()
criterion torch.nn.MSELoss(size_averageFalse)
optimizer torch.optim.SGD(model.parameters(), lr0.01)
for epoch in range(500):y_pred model(x_data)loss criterion(y_pred, y_data)print(epoch, loss.item())optimizer.zero_grad()loss.backward()optimizer.step()
print(w , model.linear.weight.item())
print(b , model.linear.bias.item())
x_test torch.Tensor([[4.0]])
y_test model(x_test)
print(y_pred , y_test.data) 2 各部分代码逐行详解
2.1 准备数据集
在PyTorch中一般需要采取mini-batch形式构建数据集也就是把数据集定义成张量(Tensor)形式以方便后续计算。
在下面这段代码中x_data是个二维张量它有3个样本每个样本有1个特征值即维度是 (3, 1)y_data同理。不清楚的同学可以使用 x.dim() 方法和 x.shape 属性来获取张量的维度和尺寸自行调试。简言之在minibatch中行表示样本列表示feature
import torch
x_data torch.Tensor([[1.0], [2.0], [3.0]])
y_data torch.Tensor([[2.0], [4.0], [6.0]]) 2.2 设计模型 图3 目标计算图主要目标构建计算图 2.2.1 代码
class LinearModel(torch.nn.Module):def __init__(self):super(LinearModel, self).__init__()self.linear torch.nn.Linear(1, 1)def forward(self, x):y_pred self.linear(x)return y_pred
model LinearModel() 2.2.2 代码逐行详解
class LinearModel(torch.nn.Module):
一般我们需要一个类并继承自PyTorch的Module类这是因为torch.nn.Module提供了很多有用的功能使得我们可以更方便地定义、训练和使用神经网络模型。 接下来至少需要实现两个函数即init和forward。 __init__方法 def __init__(self):super(LinearModel, self).__init__()self.linear torch.nn.Linear(1, 1)
该方法对模型的参数进行初始化。 在super(LinearModel, self).__init__() 中第一个参数 LinearModel 指定了查找的起点即在 LinearModel 类的父类中查找第二个参数 self 指定了当前对象即调用该方法的对象。该语句的作用是调用 LinearModel 的父类 torch.nn.Module 的 __init__ 方法并对父类的属性进行初始化。这是初始化模型的一个必要语句。
接下来将一个torch.nn.Linear对象实例化并赋值给self.linear属性。torch.nn.Linear 的构造函数接收三个参数in_features 、 out_features、bias分别代表输入特征的数量、输出特征的数量和偏置量。 图4 Linear类构造函数参数介绍forward方法 def forward(self, x):y_pred self.linear(x)return y_pred
forward()方法作用是进行前馈运算相当于计算。
注意这里相当于是重写了torch.nn.Linear 类中的forward方法。在我们重写forward后函数将会执行的过程如下 图5 forward前馈运算y_pred self.linear(x) 的作用是将输入 x 传入全连接层进行线性变换得到输出 y_pred。 最后通过实例化LinearModel类来调用模型
model LinearModel() 2.2.3 疑难点解答
1、可能你会有疑问代码中的backward过程体现在哪呢
答torch.nn.Module类构造出的对象会自动完成backward过程。Module 类及其子类在前向传递时会自动构建计算图并在反向传播(backward)时自动进行梯度计算和参数更新。比如self.lineartorch.nn.Linear(1, 1),
这里的linear属性得到Linear类的实例后相当于继承自Module所以它也会自动进行backward就无须我们再手动求导了。 2、y_pred self.linear(x) 中linear为什么后面可以直接跟括号呢
这里涉及到了python语法中的可调用对象(Callable Object)知识点。在self.linear后面加括号相当于直接在对象上加括号相当于实现了一个可调用对象。
self.linear torch.nn.Linear(1, 1)中相当于我们创建了一个Module对象因为nn.Linear类继承自nn.Module类。
接着我们执行了y_pred self.linear(x)这段代码相当于我们调用了Moudle 类的 __call__ 方法。
于是nn.Module类的__call__方法又会进一步去自动调用模块的forward方法。 举个例子
class Adder:def __init__(self, n):self.n ndef __call__(self, x):return self.n xadd5 Adder(5)
print(add5(3)) # 输出 8在这个例子中我们定义了一个 Adder 类它接受一个参数 n并且实现了 __call__ 方法。当我们创建 add5 对象时实际上是创建了一个 Adder 对象并且把参数 n 设置为 5。当我们调用 add5 对象时实际上是调用了 Adder 对象的 __call__ 方法
通过实现 __call__ 方法我们可以让对象像函数一样被调用这在一些场景下很有用例如我们可以用它来实现一个状态机、一个闭包或者一个装饰器等。 3、权重体现在哪forward里面好像没涉及到权重值的传入
这里 self.linear 实际上是一个 PyTorch 模块Module包含了权重矩阵和偏置向量于是我们便可以用这个对象来完成下图所示计算 图6 模块成员关系图图7 nn.Linear包含两个成员那么权重是怎么传入forward中的呢
在torch.nn.Linear类的构造函数__init__中它会自动创建一个nn.Parameter对象用于存储权重并将其注册为模型的可学习参数Learnable Parameter。
这个nn.Parameter对象的创建代码位于nn.Linear类的__init__函数中的这一行 图8 Linear类中的weight接收器因此self.linear中的weight属性实际上是从nn.Parameter对象中获取的。在forward方法中self.linear会自动获取到它的weight属性并用它来完成矩阵乘法的操作。 2.3 构建损失函数和优化器
criterion torch.nn.MSELoss(size_averageFalse)
optimizer torch.optim.SGD(model.parameters(), lr0.01) 图9 MSE损失函数公式torch.nn.MSELoss 是一个均方误差损失函数用于计算模型输出与真实值之间的差异即MSE。其中size_average 参数指定是否对损失求均值默认为 True即求平均值。在这个例子中size_averageFalse 意味着我们希望得到所有样本的平方误差之和。 图10 SGD随机梯度下降公式torch.optim.SGD 是随机梯度下降优化器用于更新神经网络中的参数。其中model.parameters() 对神经网络中的参数进行优化它会检查所有成员告诉优化器需要更新哪些参数。在反向传播时优化器会通过这些参数计算梯度并对其进行更新。lr 参数表示学习率即每次参数更新的步长。在这个例子中我们使用随机梯度下降作为优化器学习率为 0.01。最后我们得到了一个优化器对象optimizer。 2.4 训练周期
for epoch in range(500): # 训练500轮y_pred model(x_data) # 前向计算loss criterion(y_pred, y_data) # 计算损失print(epoch, loss.item()) # 打印损失值optimizer.zero_grad() # 梯度清零不清零梯度的结果就变成这次的梯度原来的梯度loss.backward() # 反向传播optimizer.step() # 更新权重 2.5 测试结果
循环迭代进行训练500轮。
# Output weight and bias
print(w , model.linear.weight.item())
print(b , model.linear.bias.item())
# Test Model
x_test torch.Tensor([[4.0]])
y_test model(x_test)
print(y_pred , y_test.data)
输出结果部分截图 0 23.694297790527344 1 10.621758460998535 2 4.801174163818359 3 2.208972215652466 4 1.0539695024490356 5 0.5387794971466064 6 0.3084312379360199 7 0.20490160584449768 8 0.1578415036201477 9 0.13593381643295288 10 0.12523764371871948 11 0.1195460706949234 12 0.11609543859958649 ··· 494 0.00010695526725612581 495 0.00010541956726228818 496 0.00010390445095254108 497 0.00010240855044685304 498 0.00010094392928294837 499 9.949218656402081e-05 w 1.993359923362732 b 0.015094676986336708 y_pred tensor([[7.9885]]) Process finished with exit code 0 总之求yhat求loss然后backward最后更新权重 3 线性回归中常用优化器 • torch.optim.Adagrad • torch.optim.Adam • torch.optim.Adamax • torch.optim.ASGD • torch.optim.LBFGS • torch.optim.RMSprop • torch.optim.Rprop • torch.optim.SGD 阅读官方教程的更多示例
Learning PyTorch with Examples — PyTorch Tutorials 1.13.1cu117 documentation