pytorch实现最简单的线性回归
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语法.