Pytorch源碼學習之一: torchvision.models.alexnet

Pytorch源碼學習之一 torchvision.models.alexnet

torch中一行代碼導入的alexnet配置如下:

64@11x11 stride=4 + ReLU + Maxpooling 3x3 stride=2
192@5x5 stride=1 + ReLU + MaxPooling 3x3 stride=2
384@3x3 stride=1 + ReLU
256@3x3 stride=1 + ReLU
256@3x3 stride=1 + ReLU + MaxPooling 3x3 stride=2
AvgPool => 6x6x256
Dropout
fc 6x6x256 => 4096 + ReLU + Dropout
fc 4096 => 4096 + ReLU
fc 4096 => num_classes

一、源碼

參考地址torchvison.models.alexnet源碼

#導入必要的pytorch包
import torch
import torch.nn as nn
class alexnet(nn.Module):
    
    def __init__(self, num_classes=1000):
        super(alexnet, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(64, 192, kernel_size=5, stride=1, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(192, 384, kernel_size=3, stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(384, 256, kernel_size=3, stride=1, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1),
            nn.ReLU(inplace=True)  ,  
            nn.MaxPool2d(kernel_size=3, stride=2)
        )
        self.avgpool = nn.AdaptiveAvgPool2d((6,6))
        self.classifier = nn.Sequential(
            nn.Dropout(),
            nn.Linear(6*6*256, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, num_classes)
        )
    
    def forward(self, x):
        x = self.features(x)
        x = self.avgpool(x)
        x = x.view(x.size(0), -1)
        out = self.classifier(x)
        return out 

一些函數/類用法筆記

下面對復現過程中遇到的函數的用法進行回顧,有些用法雖然已經熟知,仍做簡介

torch.nn.Module
#所有神經網絡的基類,自己寫的代碼應該繼承該類
#繼承主要是兩個函數
#一個是 __init__(self, ) 用來堆疊網絡結構
#一個是forward 用來寫前向傳播,並返回輸出值
super(alexnet, self).__init__()
#super()函數是用來調用父類(超類)的一個方法
#用來解決多重繼承問題,直接用類名調用父類方法在使用單繼承上沒問題,但是如果使用多繼承,會涉及查找順序(MRO)、重複調用等問題.
#主要語法爲
super(type[, object-or-type])
#type -- 類
#object-or-type --類, 一般是self
#該行代碼含義即爲:調用父類nn.Module的.__init__方法
nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=0, groups=1, bias=True)
#padding各個維度0填充的個數,默認是0;
#後三個參數暫時還沒用到,待補充
nn.MaxPool2d(kernel_size, stride=1)
nn.ReLU(inplace=False)
#inplace即爲是否覆蓋原數據,若選擇True,則節省空間
nn.Dropout(p=0.5, inplace=False)
#訓練時引入dropout, p爲將參數歸0的比例,默認保留0.5
nn.linear(in_features, out_features, bias=True)
# 輸入通道數, 輸出通道數, 是否有bias項
torch.Tensor.view(*shape)
#返回同樣數據,不同shape的Tensor,返回的Tenosr必須跟原來的Tensor有相同的元素數
x = x.view(x.size(0), -1)
#即將卷積網絡輸出reshape爲(batch_size, fc_shape),即相當於flatten的工作
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章