4.定義網絡(AlexNet)
AlexNet 結構:
輸入層:圖像大小爲 227×227×3,其中 3 表示輸入圖像的 channel 數(R,G,B)爲 3。
卷積層:filter 大小 11×11,filter 個數 96,卷積步長 s=4。(filter 大小隻列出了寬和高,filter矩陣的 channel 數和輸入圖片的 channel 數一樣,在這裏沒有列出)
池化層:max pooling,filter 大小 3×3,步長 s=2。
卷積層:filter 大小 5×5,filter 個數 256,步長 s=1,padding 使用 same convolution,即使得卷積層輸出圖像和輸入圖像在寬和高上保持不變。
池化層:max pooling,filter 大小 3×3,步長 s=2。
卷積層:filter 大小 3×3,filter 個數 384,步長 s=1,padding 使用 same convolution。
卷積層:filter 大小 3×3,filter 個數 384,步長 s=1,padding 使用 same convolution。
卷積層:filter 大小 3×3,filter 個數 256,步長 s=1,padding 使用 same convolution。
池化層:max pooling,filter 大小 3×3,步長 s=2;池化操作結束後,將大小爲 6×6×256 的輸出矩陣 flatten 成一個 9216 維的向量。
全連接層:neuron 數量爲 4096。
全連接層:neuron 數量爲 4096。
全連接層,輸出層:softmax 激活函數,neuron 數量爲 1000,代表 1000 個類別。
AlexNet 一些性質:
大約 60million 個參數;
使用 ReLU 作爲激活函數。
import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.optim as optim
# 定義神經網絡
class AlexNet(nn.Module): # 訓練 ALexNet
'''
三層卷積,三層全連接 (應該是5層卷積,由於圖片是 32 * 32,且爲了效率,這裏設成了 3 層)
'''
def __init__(self):
super(AlexNet, self).__init__()
# 五個卷積層 輸入 32 * 32 * 3
self.conv1 = nn.Sequential(
nn.Conv2d(in_channels=3, out_channels=6, kernel_size=3, stride=1, padding=1), # (32-3+2)/1+1 = 32
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2, padding=0) # (32-2)/2+1 = 16
)
self.conv2 = nn.Sequential( # 輸入 16 * 16 * 6
nn.Conv2d(in_channels=6, out_channels=16, kernel_size=3, stride=1, padding=1), # (16-3+2)/1+1 = 16
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2, padding=0) # (16-2)/2+1 = 8
)
self.conv3 = nn.Sequential( # 輸入 8 * 8 * 16
nn.Conv2d(in_channels=16, out_channels=32, kernel_size=3, stride=1, padding=1), # (8-3+2)/1+1 = 8
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2, padding=0) # (8-2)/2+1 = 4
)
self.conv4 = nn.Sequential( # 輸入 4 * 4 * 64
nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, stride=1, padding=1), # (4-3+2)/1+1 = 4
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2, padding=0) # (4-2)/2+1 = 2
)
self.conv5 = nn.Sequential( # 輸入 2 * 2 * 128
nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, stride=1, padding=1),# (2-3+2)/1+1 = 2
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2, padding=0) # (2-2)/2+1 = 1
) # 最後一層卷積層,輸出 1 * 1 * 128
# 全連接層
self.dense = nn.Sequential(
nn.Linear(128, 120),
nn.ReLU(),
nn.Linear(120, 84),
nn.ReLU(),
nn.Linear(84, 10)
)
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = self.conv3(x)
x = self.conv4(x)
x = self.conv5(x)
x = x.view(x.size()[0],-1)
x = self.dense(x)
return x
net = AlexNet().cuda()
print(net)