iT邦幫忙

2022 iThome 鐵人賽

DAY 12
0

Part0:前言

原先規劃在今明兩天分享LeNet原始論文,但一看居然有47頁@@,兩天下班時段共約六小時,實在會理解不及,決定透過統整網路資訊,先對LeNet這個模型作簡介和Pytorch code理解,論文本身周末在好好統整囉~ (下班騎車路上,突然覺得每天都直接介紹今日目標,實在太生硬單調了,決定之後都來點前言XD


Part1:今日目標

1.Lenet模型_理論學習1st


Part2:內容

1.LeNet模型起源

2.LeNet模型架構

  • 如上圖,該模型共有7層架構: C1、S2、C3、S4、C5、F6、OUTPUT,其中字母代表神經層種類(C:卷積層、S:池化層、F:全連接層),數字代表層數為第幾層。
  • 各層架構如下:
    • (0)輸入層(Input Layer): 32x32的圖片,通道數為1。
    • (1)C1: 使用6個5x5的卷積核,且padding=0 & stride=1,會得到28x28的輸出特徵圖(feature map),公式為width - kernel_width +1 (32-5+1=28)。
    • (2)S2: 降採樣(downsampling,選用最大池化max pooling: 圖片將會縮小到原來的一半),使用6個2x2池化,且padding=0 & stride=2,得到6個14x14的輸出特徵圖,28/2=14。
    • (3)C3: 使用16個5x5的卷積核,且padding=0 & stride=1,得到16個10x10的輸出特徵圖,14-5+1=10。
    • (4)S4: 16個2x2池化,且padding=0 & stride=2,得到16個5x5的輸出特徵圖,10/2=5。
    • (5)C5: 使用120個5x5x16的卷積核,且padding=0 & stride=1,得到120個1x1的輸出特徵圖,5-5+1=1 等同於120個神經元的全連接層。
    • (6)F6: 84個神經元全連接層,每個神經元都將與前一層C5進行全連接,並接上sigmoid函數。
    • (7)OUTPUT: 全連接層且為Gaussian Connection,採用RBF函數(徑向歐式距離函數),計算輸入向量和參數向量之間的歐式距離。因為LeNet應用於辨識手寫圖像,數字為0~9共10類,所以輸出層為10個神經元。
      ※ 注意: 激活函數(activation functions)使用TANH,而非RELU,這是由於論文當初在模型分類表現上TANH有較好的預測表現。
# 方法一: 建立nn.Module子類別
class LeNet(nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, 5)  # C1: 6個5x5大小的卷積核
        self.relu = nn.ReLU()
        self.maxpool1 = nn.MaxPool2d(2, 2)  # S2: 6個2x2池化
        self.conv2 = nn.Conv2d(6, 16, 5)  # C3: 16個5x5的卷積核
        self.maxpool2 = nn.MaxPool2d(2, 2)  # S4: 16個2x2池化
        self.fc1 = nn.Linear(16*5*5, 120)  # C5: 120個5x5x16的卷積核
        self.fc2 = nn.Linear(120, 84)  # F6: 84個神經元全連接層
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = self.relu(x)
        x = self.maxpool1(x)
        x = self.conv2(x)
        x = self.maxpool2(x)
        x = x.view(-1, 16*5*5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        output = F.log_softmax(x, dim=1)  # 多分類問題,現今多使用softmax
        return output
# 方法二: Sequential組裝
class LeNet5(nn.Module):
    def __init__(self, num_classes):
        super(ConvNeuralNet, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(1, 6, kernel_size=5, stride=1, padding=0),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size = 2, stride = 2))
        self.layer2 = nn.Sequential(
            nn.Conv2d(6, 16, kernel_size=5, stride=1, padding=0),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size = 2, stride = 2))
        self.fc1 = nn.Linear(16*5*5, 120)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(120, 84)
        self.relu1 = nn.ReLU()
        self.fc3 = nn.Linear(84, num_classes)
        self.log_softmax = nn.LogSoftmax()
        
    def forward(self, x):
        x = self.layer1(x)
        x = self.layer2(x)
        x = out.reshape(x.size(0), -1)
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        x = self.relu1(x)
        x = self.fc3(x)
        output = self.log_softmax(x, dim=1)
        return out

Part3:專案進度

  • 完成Lenet模型模型架構學習。
    透過今天的學習,更了解到一個卷積神經網路是如何層層堆疊做運算的,也順利了解一個專案中「模型建構設計和大略實作方法」,其他部分就留到明天做介紹囉,將統整網路上資源了解如何用LeNet完成手寫字母辨識(character recognition)的任務。

Part4:下一步

  • 了解整個Lenet模型預測手寫數字(MNIST dataset)的流程,包括損失函數、反向傳播機制等等。

參考:

心得小語:
能透過鐵人賽強迫自己每天都要有新的學習和吸收,覺得其實是挺好的方式~ 原本要趁周末偷跑進度,結果只有多一天的進度(傻眼XD 只能每天腳踏實地努力囉哈哈
今日工時: 50mins*3

/images/emoticon/emoticon35.gif

有本事任性的人(任性追夢),也要有本事堅強(堅毅前進)
Who is able to be egotistical needs to be strong too.


上一篇
D11-卷積神經網路CNN_理論學習2nd: 進階技巧
下一篇
D13-Lenet模型_模型架構學習2nd
系列文
菜鳥工程師第一個電腦視覺(CV)專案-農作物影像辨識競賽32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言