前言
𝐭𝐨𝐫𝐜𝐡.𝐧𝐧 模块是Pytorch为神经网络设计的模块化接口, 该模块定义了大量的神经网络层。𝐧𝐧 利用 𝐚𝐮𝐭𝐨𝐠𝐫𝐚𝐝 来定义模型,其核心数据结构是 𝐌𝐨𝐝𝐮𝐥𝐞。今天,我们就使用nn来实现最最简单的线性回归。
一、torch.nn模块简介
在实现线性回归之前,我们先来介绍一下nn的常用模块,也是之后会拿来使用的几个模块。如下图所示
二、实现线性回归
1.读取数据
PyTorch提供了 data 库来读取数据。由于data常用作变量名,这里将导入的 data 模块用 Data 代替。对前面的读取数据部分可以使用 data 库来处理。在每一次迭代张,使用 Data 随机读取包含10个数据样本的小批量。
import torch
import torch.nn as nn
import numpy as np
import torch.utils.data as Data
num_inputs = 2
num_examples = 1000
true_w = [2,-3.4]
true_b = 4.2
#其中np.random.normal(0,1,(num_examples,num_inputs)) 0,1代表了标准正态分布
# size 是 1000*2 (行,列)
features = torch.tensor(np.random.normal(0,1,(num_examples,num_inputs)),dtype=torch.float)
labels = true_w[0]*features[:,0]+true_w[1]*features[:,1]+true_b
labels += torch.tensor(np.random.normal(0,0.01,size=labels.size()),dtype=torch.float)
lr = 0.03
#批量,每次从数据集中抽取10个数据来训练
batch_size = 10
dataset = Data.TensorDataset(features,labels)
data_iter = Data.DataLoader(
dataset=dataset,
batch_size=batch_size,
shuffle=True,
num_workers=0
)
2.构建模型
构建模型的过程中,最常见的方法就是继承 𝐧𝐧.𝐌𝐨𝐝𝐮𝐥𝐞,然后构建自己的网络。一个 𝐧𝐧.𝐌𝐨𝐝𝐮𝐥𝐞 实例需要包含一些层以及返回输出的前向传播方法。下面利用 𝐧𝐧.𝐌𝐨𝐝𝐮𝐥𝐞 构建一个线性回归模型。
class LinearNet(nn.Module):
def __init__(self,n_feature):
super(LinearNet,self).__init__()
self.linear = nn.Linear(n_feature,1)
def forward(self,x):
y = self.linear(x)
return y
net = LinearNet(num_inputs)
除了继承 𝐧𝐧.𝐌𝐨𝐮𝐝𝐥𝐞 来构建线性回归模型,还可以利用 𝐧𝐧.𝐒𝐞𝐪𝐮𝐞𝐧𝐭𝐢𝐚𝐥 结合 𝐧𝐧.𝐋𝐢𝐧𝐞𝐚𝐫 来搭建模型
#写法1:
net = nn.Sequential(
nn.Linear(num_inputs,1)
)
#写法2:
net = nn.Sequential()
net.add_module('linear',nn.Linear(num_inputs,1))
net.add_module(................)
3.模型参数初始化
在使用定义的模型net之前,需要对模型中的一些参数进行初始化。Pytorch在init模块中提供了许多初始化参数的方法。我们可以调运𝐢𝐧𝐢𝐭.𝐧𝐨𝐫𝐦𝐚𝐥模块通过正态分布对线性回归中的权重和偏差进行初始化
from torch.nn import init
init.normal_(net[0].weight,mean=0,std=0.01)
init.constant_(net[0].bias,val=0)
上述代码,将参数中的每个元素随机初始化为了均值为0,标准差为0.01的正态分布,同时将偏差初始化为零
4.定义损失函数和优化方法
Pytorch在 𝑡𝑜𝑟𝑐ℎ.𝑛𝑛 中提供了各种损失函数,这些损失函数实现为 𝐧𝐧.𝐌𝐨𝐝𝐮𝐥𝐞 的子类,可以将这些损失函数作为一种特殊的层。
loss = nn.MSELoss()
Pytorch在 𝐭𝐨𝐫𝐜𝐡.𝐨𝐩𝐭𝐢𝐦 模块中提供了诸如 𝑺𝑮𝑫 , 𝑨𝒅𝒂𝒎 和 𝑹𝑴𝑺𝑷𝒓𝒐𝒐𝒑 等优化算法。本例将使用小批量随机梯度下降算法进行优化。
import torch.optim as optim
optimizer = optim.SGD(net.parameters(),lr=0.03)
#可以为不同的子网络设置不同的子网络
# optimizer =optim.SGD([
# # 如果不指定学习率,则用默认的最外层学习率
# {'params': net.subnet1.parameters()}, # lr=0.03
# {'params': net.subnet2.parameters(), 'lr': 0.01}
# ], lr=0.03)
5.模型的训练
训练模型时,可以调用 𝐨𝐩𝐭𝐢𝐦 中的 𝐬𝐭𝐞𝐩() 函数来迭代模型参数。按照小批量随机梯度下降的定义,在 𝐬𝐭𝐞𝐩() 函数中指定批量大小,从而对批量中的样本梯度求平均。
num_epochs = 4
for epoch in range(1,num_epochs+1):
for X,y in data_iter:
output = net(X)
l = loss(output,y.view(-1,1))
optimizer.zero_grad()
l.backward()
optimizer.step()
print('epoch%d,loss%f'%(epoch,l.item()))
输出结果:
epoch1,loss0.000472
epoch2,loss0.000179
epoch3,loss0.000106
epoch4,loss0.000106