神经网络构建

PyTorch中神经网络的构建是使用torch.nn包的。torch.nn包基于自动微分进行模型的定义和差别计算。PyTorch中的网络一般是一个继承了nn.Module类的实例,其中包含了定义的层以及方法.forward(input)来根据输入获得输出。

以下是一个神经网络的定义示例。

import torch
import torch.nn as nn
import torch.nn.functional as F


class Net(nn.Module):

	def __init__(self):
		super().__init__()
		self.conv1 = nn.Conv2d(1, 6, 3)
		self.conv2 = nn.Conv2d(6, 16, 3)
		self.fc1 = nn.Linear(16 * 6 * 6, 120)
		self.fc2 = nn.Linear(120, 84)
		self.fc3 = nn.Linear(84, 10)

	def forward(self, x):
		x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
		x = F.max_pool2d(F.relu(self.conv2(x)), 2)
		x = x.view(-1, self.num_flat_features(x))
		x = F.relu(self.fc1(x))
		x = F.relu(self.fc2(x))
		x = self.fc3(x)
		return x

	def num_flat_features(self, x):
		size = x.size()[1:]
		num_features = 1
		for s in size:
			num_features *= s
		return num_features


net = Net()

当定义了方法.forward(input)后,用于计算梯度的.backward()方法就会在使用自动微分时自动建立。

Module类中可以包含其他的Module类,这样可以形成一个树状的神经网络结构。Module可以表示网络的一层,也可以表示某一个网络结构。在定义Module时,一般会将模型中所需的各层都保存在类变量中,之后在.forward(input)方法中使用nn.functional中的函数定义层与层之间的处理过程。PyTorch中层的实例与Keras中的层实例一样,都可以将其当做函数来调用。例如nn.Conv2d(1, 6, 3)(x)和示例中self.conv1(x)的调用方法是等价的。每一个层都需要至少一个输入,并且在进行函数式调用后都会产生一个输出。将每一层的处理实例保存为类变量的好处是可以在后期进行更加方便的深入调整,而不是只依靠构造函数中的参数。

与Keras相似,神经网络每一层的处理顺序一般都是先进行特征提取,再调用激活函数,从激活函数获得的张量就可以传递给下一层使用了。