PyTorch中的 torch.nn包提供了很多与实现神经网络中的具体功能相 关的类,这些类涵盖了深度神经网络模型在搭建和参数优化过程中的常 用内容,比如神经网络中的卷积层、池化层、全连接层这类层次构造的 方法、防止过拟合的参数归一化方法、Dropout 方法,还有激活函数部 分的线性激活函数、非线性激活函数相关的方法,等等。

首先先看一段代码:

import torch
from torch.autograd import Variable
batch_n = 100
hidden_layer = 100
input_data = 1000
output_data = 10
epoch_n = 10000
learning_rate = 1e-4
loss_fn = torch.nn.MSELoss()

models = torch.nn.Sequential(
    torch.nn.Linear(input_data,hidden_layer),
    torch.nn.ReLU(),
    torch.nn.Linear(hidden_layer,output_data)
    )

x = Variable(torch.randn(batch_n,input_data),requires_grad = False)
y = Variable(torch.randn(batch_n,output_data),requires_grad = False)
for epoch in range(epoch_n):
    y_pred = models(x)
    loss = loss_fn(y_pred, y)
    if epoch%1000 == 0 :
        print("Epoch:{},Loss:{:.4f}".format(epoch,loss.item()))
    models.zero_grad()
    loss.backward()
    
    for param in models.parameters():
        param.data -= param.grad.data*learning_rate

上面这段代码调用了几个nn里面的参数,这也是我们在搭建模型的时候最常用的。下面主要介绍一下这些参数 

1.使用torch.nn.Sequential

torch.nn.Sequential类是torch.nn中的一种 序列容器,通过在容器中嵌套各种实现神经网络中具体功能相关的类, 来完成对神经网络模型的搭建,最主要的是,参数会按照我们定义好的序列自动传递下去。

模块添加方式有两种:

一是使用直接嵌套模型:

import torch
from torch.autograd import Variable
hidden_layer = 100 #定义隐藏层
input_data = 100 #定义输入层
output_data = 10 #定义输出层

models = torch.nn.Sequential(
    torch.nn.Linear(input_data,hidden_layer),
    torch.nn.ReLU(),
    torch.nn.Linear(hidden_layer,output_data)
    )
print(models)

输出结果为:

Sequential(
  (0): Linear(in_features=100, out_features=100, bias=True)
  (1): ReLU()
  (2): Linear(in_features=100, out_features=10, bias=True)
)

第二种是使用有序字典orderdict来添加模块:

import torch
from torch.autograd import Variable
from collections import OrderedDict
hidden_layer = 100
input_data = 100
output_data = 10

models = torch.nn.Sequential(OrderedDict([
    ("Liner1",torch.nn.Linear(input_data,hidden_layer)),
    ("Relu",torch.nn.ReLU()),
    ("Linier2",torch.nn.Linear(hidden_layer,output_data))])
                             
    )
print(models)

结果:

Sequential(
  (Liner1): Linear(in_features=100, out_features=100, bias=True)
  (Relu): ReLU()
  (Linier2): Linear(in_features=100, out_features=10, bias=True)
)

2.使用torch.nn.Linear

torch.nn.Linear类用于定义模型的线性层, 即完成前面提到的不同的层之间的线性变换。torch.nn.Linear类接收的参 数有三个,分别是输入特征数、输出特征数和是否使用偏置,设置是否 使用偏置的参数是一个布尔值,默认为True,即使用偏置。

3.使用torch.nn.ReLU()

相当于我们激活函数,将线性输入转变为非线性输出。常用的激活函数还有tanh,softmax等等。

4.使用torch.nn.MSELoss

 torch.nn.MSELoss类使用均方误差函数对 损失值进行计算,在定义类的对象时不用传入任何参数,但在使用实例 时需要输入两个维度一样的参数方可进行计算。

5.使用torch.nn.L1Loss

torch.nn.L1Loss类使用平均绝对误差函数对 损失值进行计算,同样,在定义类的对象时不用传入任何参数,但在使 用实例时需要输入两个维度一样的参数进行计算。

6.使用torch.nn.CrossEntropyLoss

orch.nn.CrossEntropyLoss类用 于计算交叉熵,在定义类的对象时不用传入任何参数,在使用实例时需 要输入两个满足交叉熵的计算条件的参数, 注意在使用CrossEntropyLoss的时候

代码示例:

import torch
from torch.autograd import Variable
loss_f = torch.nn.CrossEntropyLoss()
# loss_f = torch.nn.L1Loss()
# loss_f = torch.nn.MSELoss()
x = Variable(torch.randn(3,5))
y = Variable(torch.LongTensor(3).random_(5))
loss = loss_f(x,y)
print(loss.data)
tensor(1.8163)

好了几个函数都介绍完了,可以开始训练我们文章一开始的数据了:

import torch
from torch.autograd import Variable
batch_n = 100
hidden_layer = 100
input_data = 1000
output_data = 10
epoch_n = 10000
learning_rate = 1e-4
loss_fn = torch.nn.MSELoss()

models = torch.nn.Sequential(
    torch.nn.Linear(input_data,hidden_layer),
    torch.nn.ReLU(),
    torch.nn.Linear(hidden_layer,output_data)
    )

x = Variable(torch.randn(batch_n,input_data),requires_grad = False)
y = Variable(torch.randn(batch_n,output_data),requires_grad = False)
for epoch in range(epoch_n):
    y_pred = models(x)
    loss = loss_fn(y_pred, y)
    if epoch%1000 == 0 :
        print("Epoch:{},Loss:{:.4f}".format(epoch,loss.item()))
    models.zero_grad()
    loss.backward()
    
    for param in models.parameters():
        param.data -= param.grad.data*learning_rate

输出的结果: 

Epoch:0,Loss:0.9901
Epoch:1000,Loss:0.9134
Epoch:2000,Loss:0.8483
Epoch:3000,Loss:0.7914
Epoch:4000,Loss:0.7407
Epoch:5000,Loss:0.6952
Epoch:6000,Loss:0.6540
Epoch:7000,Loss:0.6161
Epoch:8000,Loss:0.5810
Epoch:9000,Loss:0.5481

 可以看到我们的loss在不断减少,也就是我们在不断靠近输出的Y值。