欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

pytorch实现最简单的线性回归

程序员文章站 2022-05-26 20:43:50
...
import torch
import time
from torch.autograd import Variable
import torch.nn.functional as F

x = torch.unsqueeze(torch.linspace(-2, 2, 10), dim=1)
y = x.pow(2) + 0.2 * torch.rand(x.size())
#math.pow(100, 2) :  10000.0
#t.unsqueeze(di)     //在di个维度处升维
#t=T.rand(t.size())    //均匀分布
#t=T.randn(t.size())   //标准正态分布
#t=T.linspace(m,n,step_num)  //[m,n]中以m为首项,n为末项,均分区间为step_num段
x, y = Variable(x), Variable(y)
#Variable就是 变量 的意思。实质上也就是可以变化的量,区别于int变量,它是一种可以变化的变量,这正好就符合了反向传播,参数更新的属性
#把鸡蛋放到篮子里, requires_grad是参不参与误差反向传播, 要不要计算梯度
#tensor不能反向传播,variable可以反向传播。
class Net(torch.nn.Module):
    def __init__(self, n_features, n_hidden, n_output):
        super(Net, self).__init__()
        self.hidden = torch.nn.Linear(n_features, n_hidden)
        self.predict = torch.nn.Linear(n_hidden, n_output)

    def forward(self, x):
        x = F.relu(self.hidden(x))
        x = self.predict(x)
        return x
        
model=Net(1,1,1)
optimizer = torch.optim.SGD(model.parameters(), lr=0.3)
loss_func = torch.nn.MSELoss()

for t in range(10):
    prediction = model(x)
    loss = loss_func(prediction,y)
    print(loss)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

一般神经网络的类都继承自torch.nn.Module,init()和forward()两个函数是自定义类的主要函数。在__init__()中都要添加一句super(Net, self).init(),这是固定的标准写法,用于继承父类的初始化函数。init()中只是对神经网络的模块进行了声明,真正的搭建是在forwad()中实现。自定义类中的成员都通过self指针来进行访问,所以参数列表中都包含了self。
训练网络之前我们需要先定义优化器和损失函数。torch.optim包中包括了各种优化器,这里我们选用最常见的SGD作为优化器。因为我们要对网络的参数进行优化,所以我们要把网络的参数net.parameters()传入优化器中,并设置学习率(一般小于1)。
由于这里是回归任务,我们选择torch.nn.MSELoss()作为损失函数。
由于优化器是基于梯度来优化参数的,并且梯度会保存在其中。所以在每次优化前要通过optimizer.zero_grad()把梯度置零,然后再后向传播及更新。

torch.nn.module
定义自已的网络:
需要继承nn.Module类,并实现forward方法。
一般把网络中具有可学习参数的层放在构造函数__init__()中,
不具有可学习参数的层(如ReLU)可放在构造函数中,也可不放在构造函数中(而在forward中使用nn.functional来代替)
只要在nn.Module的子类中定义了forward函数,backward函数就会被自动实现(利用Autograd)。
在forward函数中可以使用任何Variable支持的函数,毕竟在整个pytorch构建的图中,是Variable在流动。还可以使用if,for,print,log等python语法.