Windows操作系统下,模型的路径为:C:\Python35\Lib\site-packages\torchvision\models\xxnet.py,这里有许多常用的网络结构的定义,包括AlexNet, ResNet, Inception, DenseNet等,可以供我们直接使用:
from torchvision import models
model = models.alexnet(pretrained=False)
现在开始读AlexNet源代码:
首先导入必要的包,然后定义 __all__ 变量,使用此功能是为了对命名空间的破坏最小化,因为from xx import *时会把所有变量复制出去,导入者可以得到超出它所需的部分(也许会覆盖导入者定义变量的变量名),当存在 __all__ 列表时,只会把列表中的变量名复制出来。这里与_X惯例相反:__all__是指出要复制的变量名,而_X是指出不可以复制的变量名。Python会寻找模型内的__all__列表,如果没有定义的话,那么from xx import *时就会复制出开头没有下划线的所有变量名。
model_urls定义一个字典,字典的键为模型名称(结构),值为对应的预训练模型参数的下载地址。
import torch
import torch.nn as nn
from .utils import load_state_dict_from_url
__all__ = ['AlexNet', 'alexnet']
model_urls = {
'alexnet': 'https://download.pytorch.org/models/alexnet-owt-4df8aa71.pth',
}
接下来是AlexNet类,继承自torch.nn.Module,这是所有神经网络module的父类。
首先定义初始化__init__方法,参数num_classes为几分类,默认为ImageNet的1000类。
在最开始,super(AlexNet, self).__init__(),用父类的初始化方法来初始化子类,nn.Module部分源码如下:
class Module(object):
dump_patches = False
_version = 1
def __init__(self):
"""
Initializes internal Module state, shared by both nn.Module and ScriptModule.
"""
torch._C._log_api_usage_once("python.nn_module")
self.training = True
self._parameters = OrderedDict()
self._buffers = OrderedDict()
self._backward_hooks = OrderedDict()
self._forward_hooks = OrderedDict()
self._forward_pre_hooks = OrderedDict()
self._state_dict_hooks = OrderedDict()
self._load_state_dict_pre_hooks = OrderedDict()
self._modules = OrderedDict()
之后定义卷积神经网络的结构:若干conv+maxpooling然后连接3个FC层的经典方式,除了第一个卷积层步长为4,其余的卷积层步长都是1,且使用了"same"的padding方式,而且所有maxpooling的filter_size都是3。AdaptiveAvgPool2d是一种自适应的平均池化,此方法可以根据参数的target_size和input_size计算出kernel_size=(input_size+target_size-1) // target_size,输出的通道数保持不变,尺寸变为参数设置的target_size。最后是全连接层,p=0.5的Dropout。
之后是forward方法,它定义每次