首页人工智能Pytorch【深度学习(PyTorch...

【深度学习(PyTorch篇)】21.使用nn模块实现线性回归

本系列文章配套代码获取有以下两种途径:

  • 通过百度网盘获取:
链接:https://pan.baidu.com/s/1XuxKa9_G00NznvSK0cr5qw?pwd=mnsj 提取码:mnsj
  • 前往GitHub获取
https://github.com/returu/PyTorch





01

torch.nn:


Pytorch中的nn模块(torch.nn)是用于构建神经网络的核心组件,它提供了许多预定义的层(模块,使得构建神经网络变得简单、高效且结构化

nn模块提供了大量预定义的层,如全连接层、卷积层、池化层、归一化层等。这些预定义层都经过了优化,能够高效地处理大规模的数据和参数。所有神经网络模块都是派生自基类nn.Module,通过它可以构建和管理自定义层、模型等,并将其组合成复杂的神经网络。

另外,nn模块提供了许多预定义的损失函数,用于计算模型预测值与真实值之间的差异,交叉熵损失nn.CrossEntropyLoss)、均方误差(nn.MSELoss等。

nn模块用户可以直接使用或将其作为自定义层的基础,本次将直接使用nn.Module的一个子类nn.Linear全连接层,通过权重和偏置参数对输入数据执行线性变换来实现线性回归.
02

使用nn模块实现线性回归:


本次将从生成数据开始,将之前的代码转换为使用nn模块。
  • 1、生成数据:

PyTorch对神经网络模块的输入进行batch处理(即批处理,指的是一次同时处理的多个数据样本)是一种标准做法,它不仅能够提高计算效率和内存利用率(更高效地利用硬件资源,如GPU的并行计算能力),还能提升模型的稳定性和泛化性能(通过计算整个batch的平均损失来更新模型参数,可以减少梯度更新中的噪声,使梯度下降更加稳定)。

可以使用unsqueeze()方法在输入张量中增加一个新的batch维度。

>>def get_fake_data(num):
...     """
...     生成随机数据,y = 0.5 * x +30并加上一些随机噪声
...     "
""
...     x = torch.randint(low = -5, high=30, size=(num,)).to(dtype=torch.float32)
...     y = 0.5 * x +30 + torch.randn(num,)
...     return x,y


>>> x , y = get_fake_data(num=11)
>>> x = x * 0.1
>>> x.shape , y.shape
(torch.Size([11]), torch.Size([11]))

# 增加batch维度
>>> x = x.unsqueeze(1)
>>> y = y.unsqueeze(1)
>>> x.shape , y.shape
(torch.Size([111]), torch.Size([111]))
通过上述代码将输入转换为(B , Nin),其中,B=11即输入有11个样本,Nin=1即输入样本只有1个输入特征。
  • 2、定义函数:

PyTorch提供的所有nn.Module的子类都定义了它们的__call__()方法,这允许我们实例化一个nn.Linear,并像调用函数一样调用它。

构造函数nn.Linear语法如下:
torch.nn.Linear(in_features, out_features, bias=True, device=None, dtype=None)
其中,
  • in_features (int):输入特征的数量;
  • out_features (int)输出特征的数量;
  • bias (bool)线性模型是否包含偏置,默认为True

本次模型的输入与输出都只有1个特征。

# 定义模型
linear_model = nn.Linear(1,1)

可以通过parameters()方法来访问任何nn.Module或它的子模块拥有的参数列表,调用会递归到模块的构造函数__init__()定义的子模块中,并返回遇到的所有参数的简单列表

>>> linear_model.parameters()
<generator object Module.parameters at 0x000001FC623C8580>

>>> list(linear_model.parameters())
[Parameter containing:
tensor([[-0.1188]], requires_grad=True), Parameter containing:
tensor([0.1292], requires_grad=True)]

也可以直接调用weightbias属性获取参数值。

>>> linear_model.weight
Parameter containing:
tensor([[-0.1188]], requires_grad=True)

>>> linear_model.bias
Parameter containing:
tensor([0.1292], requires_grad=True)

另外,可以直接使用nn模块提供的损失函数,其中包含的均方误差(nn.MSELoss)即使我们之前定义的损失函数loss_fn()

nn 模块中的损失函数也是nn.Module的子类,因此可以直接创建一个实例并将其作为函数调用。

# 定义损失函数
loss_fn = nn.MSELoss()

最后,再实例化一个优化器。

# 实例化一个优化器
learning_rate=1e-2

optimizer = torch.optim.SGD(linear_model.parameters() , lr=learning_rate)


  • 3、循环训练,求解参数值:

最后将循环训练代码进行修改。

需要注意的是,在获取参数值进行绘图部分涉及到两个重要的步骤:

  • 首先,使用detach() 方法创建一个新的与当前计算图分离的Tensor,即不会参与到梯度反向传播中

  • 然后,使用numpy() 方法将这个分离的Tensor转换成一个NumPy数组。
from IPython import display

def training_loop(n_epochs , optimizer , model , loss_fn , x , y):
    for epoch in range(1 , n_epochs+1):
        #前向传播
        y_p = model(x)
        loss = loss_fn(y_p ,y)

        # 梯度归零
        optimizer.zero_grad()
        # 反向传播
        loss.backward()
        # 参数更新
        optimizer.step()

        if epoch % 10 ==0:
            display.clear_output(wait=True)
            plt.plot(x.detach().numpy() , y_p.detach().numpy())

            plt.plot(x.detach().numpy() , y.detach().numpy() , 'o')

            # 获取xy轴的范围
            xmin,xmax,ymin,ymax = plt.axis()

            plt.text(x=xmax*0.2,
                     y=ymax*0.9,
                     s=f"{linear_model.weight.detach().numpy().item()*0.1:.3f}x+{linear_model.bias.detach().numpy().item():.3f}")

            plt.show()
            plt.pause(0.5)

    return list(linear_model.parameters())

设置相关参数值并运行,得到参数值。

training_loop(n_epochs=1000 , optimizer=optimizer , model=linear_model , loss_fn=loss_fn , x=x_new , y=y)



更多内容可以前往官网查看

https://pytorch.org/


本篇文章来源于微信公众号: 码农设计师

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments