一、Inception塊
1、白色部分通過降低通道數來控制模型復雜度,藍色做特征提取工作,每條路上的通道數可能不同,大概我們會把更重要的那部分特征分配更多的通道數
2、Inception只改變高寬,不改變通道數
3、在不同的情況下需要選擇不同的模型,而Inception全都要了,很神奇的思想
4、模型復雜度可以看作是可以學習的參數個數,inception它大大降低了參數個數,從而降低了計算復雜度,而且它可以在運算的時候加入不同的卷積層
二、GoogLeNet
1、Stage是一個高寬減半
2、并不強求最后的stage得出來的個數等于類別數,可以通過全局avegpool得到的結果拉成通道數的向量,在使用全連接層將其映射到相應的標號上
三、Inception后續變種
變種的1×7、7×1(3同理)卷積層是一個先看行的信息,另外一個在看列的信息
四、總結
1、Inception塊相當于一個有4條路徑的子網絡。它通過不同窗口形狀的卷積層和最大匯聚層來并行抽取信息,并使用1×1卷積層減少每像素級別上的通道維數從而降低模型復雜度,主要優點是模型參數小,計算復雜度低。
2、GoogLeNet將9個設計精細的Inception塊與其他層(卷積層、全連接層)串聯起來,是第一個達到有上百層的網絡。其中Inception塊的通道數分配之比是在ImageNet數據集上通過大量的實驗得來的,后續有大量變種。
3、GoogLeNet和它的后繼者們一度是ImageNet上最有效的模型之一:它以較低的計算復雜度提供了類似的測試精度。
五、代碼
1、Inception塊
import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2lclass Inception(nn.Module):# c1--c4是每條路徑的輸出通道數def __init__(self, in_channels, c1, c2, c3, c4, **kwargs):super(Inception, self).__init__(**kwargs)# 線路1,單1x1卷積層self.p1_1 = nn.Conv2d(in_channels, c1, kernel_size=1)# 線路2,1x1卷積層后接3x3卷積層self.p2_1 = nn.Conv2d(in_channels, c2[0], kernel_size=1)self.p2_2 = nn.Conv2d(c2[0], c2[1], kernel_size=3, padding=1)# 線路3,1x1卷積層后接5x5卷積層self.p3_1 = nn.Conv2d(in_channels, c3[0], kernel_size=1)self.p3_2 = nn.Conv2d(c3[0], c3[1], kernel_size=5, padding=2)# 線路4,3x3最大匯聚層后接1x1卷積層self.p4_1 = nn.MaxPool2d(kernel_size=3, stride=1, padding=1)self.p4_2 = nn.Conv2d(in_channels, c4, kernel_size=1)def forward(self, x):p1 = F.relu(self.p1_1(x))p2 = F.relu(self.p2_2(F.relu(self.p2_1(x))))p3 = F.relu(self.p3_2(F.relu(self.p3_1(x))))p4 = F.relu(self.p4_2(self.p4_1(x)))# 在通道維度上連結輸出return torch.cat((p1, p2, p3, p4), dim=1)
2、GoogLeNet模型
#第一個模塊使用64個通道、7×7卷積層 b1 = nn.Sequential(nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3),nn.ReLU(),nn.MaxPool2d(kernel_size=3, stride=2, padding=1))#第二個模塊使用兩個卷積層:第一個卷積層是64個通道、1×1卷積層;第二個卷積層使用將通道數量增加三倍的3×3卷積層。 這對應于Inception塊中的第二條路徑。 b2 = nn.Sequential(nn.Conv2d(64, 64, kernel_size=1),nn.ReLU(),nn.Conv2d(64, 192, kernel_size=3, padding=1),nn.ReLU(),nn.MaxPool2d(kernel_size=3, stride=2, padding=1))#第三個模塊串聯兩個完整的Inception塊。 b3 = nn.Sequential(Inception(192, 64, (96, 128), (16, 32), 32),Inception(256, 128, (128, 192), (32, 96), 64),nn.MaxPool2d(kernel_size=3, stride=2, padding=1))#第四模塊串聯了5個Inception塊 b4 = nn.Sequential(Inception(480, 192, (96, 208), (16, 48), 64),Inception(512, 160, (112, 224), (24, 64), 64),Inception(512, 128, (128, 256), (24, 64), 64),Inception(512, 112, (144, 288), (32, 64), 64),Inception(528, 256, (160, 320), (32, 128), 128),nn.MaxPool2d(kernel_size=3, stride=2, padding=1))#第五模塊包含兩個Inception塊 b5 = nn.Sequential(Inception(832, 256, (160, 320), (32, 128), 128),Inception(832, 384, (192, 384), (48, 128), 128),nn.AdaptiveAvgPool2d((1,1)),nn.Flatten())net = nn.Sequential(b1, b2, b3, b4, b5, nn.Linear(1024, 10))