# 基于 Pytorch 的线性回归简介实现主要内容:借助 Pytorch 框架,结合 d2l 面向对象设计,完成线性回归的简洁实现
# 准备
1 2 3 4 import numpy as npimport torchfrom torch import nnfrom d2l import torch as d2l
torch.nn 包含了常用的神经网络层
# 模型定义 d2l.Module# 参数及其初始化
1 2 3 4 5 6 7 class LinearRegression (d2l.Module): def __init__ (self, lr ): super ().__init__() self.save_hyperparameters() self.net = nn.LazyLinear(1 ) self.net.weight.data.normal_(0 , 0.01 ) self.net.bias.data.fill_(0 )
torch.nn.LazyLinear 是一种线性层,只需指定 输出维度
.data.normal_ 及 .data.fill_ 完成参数的初始化
# 前向传播过程
1 2 3 @d2l.add_to_class(LinearRegression ) def forward (self, X ): return self.net(X)
net 是一个 nn.LazyLinear 对象,直接调用 nn.LazyLinear () 会执行前向传播过程(__call__() 中实现),即进行神经网络的计算
# 损失函数
1 2 3 4 @d2l.add_to_class(LinearRegression ) def loss (self, y_hat, y ): fn = nn.MSELoss() return fn(y_hat, y)
nn.MSELoss () 是 Pytorch 自带的平方损失
# 指定优化器
1 2 3 @d2l.add_to_class(LinearRegression ) def configure_optimizers (self ): return torch.optim.SGD(self.parameters(), self.lr)
LinearRegression.parameters () 储存参数
torch.optim.SGD 即随机梯度下降 调用方法为 SGD (params(一个包含参数的列表), lr(学习率))
# 数据准备 d2l.DataModuleClass SyntheticRegressionData 已在 3.3 实现,并且保存在 d2l 包中,可直接调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class SyntheticRegressionData (d2l.DataModule): """Synthetic data for linear regression. Defined in :numref:`sec_synthetic-regression-data`""" def __init__ (self, w, b, noise=0.01 , num_train=1000 , num_val=1000 , batch_size=32 ): super ().__init__() self.save_hyperparameters() n = num_train + num_val self.X = d2l.randn(n, len (w)) noise = d2l.randn(n, 1 ) * noise self.y = d2l.matmul(self.X, d2l.reshape(w, (-1 , 1 ))) + b + noise def get_dataloader (self, train ): """Defined in :numref:`sec_synthetic-regression-data`""" i = slice (0 , self.num_train) if train else slice (self.num_train, None ) return self.get_tensorloader((self.X, self.y), train, i)
# 训练器 d2l.Trainer一般需要根据实际情况,自定义 fit_epoch (), prepare_batch () 等方法
3.4 中已根据线性回归的需要给出了一个简单实现,且保存在 d2l 包中,可直接调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 def fit_epoch (self ): """Defined in :numref:`sec_linear_scratch`""" self.model.train() for batch in self.train_dataloader: loss = self.model.training_step(self.prepare_batch(batch)) self.optim.zero_grad() with torch.no_grad(): loss.backward() if self.gradient_clip_val > 0 : self.clip_gradients(self.gradient_clip_val, self.model) self.optim.step() self.train_batch_idx += 1 if self.val_dataloader is None : return self.model.eval () for batch in self.val_dataloader: with torch.no_grad(): self.model.validation_step(self.prepare_batch(batch)) self.val_batch_idx += 1
# 训练
1 2 3 4 model = LinearRegression(lr=0.03 ) data = d2l.SyntheticRegressionData(w=torch.tensor([2 , -3.4 ]), b=4.2 ) trainer = d2l.Trainer(max_epochs=10 ) trainer.fit(model, data)
[end]
2024/2/5
mofianger
代码引自 en.d2l.ai
参考:3.5. Concise Implementation of Linear Regression — Dive into Deep Learning 1.0.3 documentation (d2l.ai)