PyTorch神经网络工具箱(如何构建神经网络?)
如何构建神经网络?
3.2节中通过使用nn工具箱,搭建了一个神经网络。虽然步骤较多,但关键就是选择
网络层,构建网络,然后选择损失和优化器。在nn工具箱中,可以直接引用的网络很多,
有全连接层、卷积层、循环层、正则化层、激活层等等。假设这些层都定义好了,接下来
应该如何组织或构建这些层呢?
构建网络层
在3.2节实例中,采用了torch.nn.Sequential()来构建网络层,这个有点类似Keras的
models.Sequential(),使用起来就像搭积木一样,非常方便。不过,这种方法每层的编码
是默认的数字,不易区分。
如果要对每层定义一个名称,我们可以采用Sequential的一种改进方法,在Sequential
的基础上,通过add_module()添加每一层,并且为每一层增加一个单独的名字。
此外,还可以在Sequential基础上,通过字典的形式添加每一层,并且设置单独的层
名称。
以下是采用字典方式构建网络的一个示例代码:
class Net(torch.nn.Module):
def __init__(self):
super(Net4, self).__init__()
self.conv = torch.nn.Sequential(
OrderedDict(
[
("conv1", torch.nn.Conv2d(3, 32, 3, 1, 1)),
("relu1", torch.nn.ReLU()),
("pool", torch.nn.MaxPool2d(2))
]
))
self.dense = torch.nn.Sequential(
OrderedDict([
("dense1", torch.nn.Linear(32 * 3 * 3, 128)),
("relu2", torch.nn.ReLU()),
("dense2", torch.nn.Linear(128, 10))
])
)
前向传播
定义好每层后,最后还需要通过前向传播的方式把这些串起来。这就是涉及如何定义
forward函数的问题。forward函数的任务需要把输入层、网络层、输出层链接起来,实现
信息的前向传导。该函数的参数一般为输入数据,返回值为输出数据。
在forward函数中,有些层来自nn.Module,也可以使用nn.functional定义。来自
nn.Module的需要实例化,而使用nn.functional定义的可以直接使用。
反向传播
前向传播函数定义好以后,接下来就是梯度的反向传播。在第2章中,介绍了实现梯
度反向传播的方法。这里关键是利用复合函数的链式法则。深度学习中涉及很多函数,如
果要自己手工实现反向传播,比较费时。好在PyTorch提供了自动反向传播的功能,使用
nn工具箱,无须我们自己编写反向传播,直接让损失函数(loss)调用backward()即可,
非常方便和高效!
在反向传播过程中,优化器是一个重要角色。优化方法有很多,3.2节采用SGD优化
器。此外,我们还可以选择其他优化器。
训练模型
层、模型、损失函数和优化器等都定义或创建好,接下来就是训练模型。训练模型时
需要注意使模型处于训练模式,即调用model.train()。调用model.train()会把所有的module
设置为训练模式。如果是测试或验证阶段,需要使模型处于验证阶段,即调用
model.eval(),调用model.eval()会把所有的training属性设置为False。
缺省情况下梯度是累加的,需要手工把梯度初始化或清零,调用optimizer.zero_grad()
即可。训练过程中,正向传播生成网络的输出,计算输出和实际值之间的损失值。调用
loss.backward()自动生成梯度,然后使用optimizer.step()执行优化器,把梯度传播回每
个网络。
如果希望用GPU训练,需要把模型、训练数据、测试数据发送到GPU上,即调
用.to(device)。如果需要使用多GPU进行处理,可使模型或相关数据引用nn.DataParallel。
nn.DataParallel的具体使用。