# 3.9 多層感知機的從零開始實現
我們已經從上一節里了解了多層感知機的原理。下面,我們一起來動手實現一個多層感知機。首先導入實現所需的包或模塊。
``` python
import torch
import numpy as np
import sys
sys.path.append("..")
import d2lzh_pytorch as d2l
```
## 3.9.1 獲取和讀取數據
這里繼續使用Fashion-MNIST數據集。我們將使用多層感知機對圖像進行分類。
``` python
batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
```
## 3.9.2 定義模型參數
我們在3.6節(softmax回歸的從零開始實現)里已經介紹了,Fashion-MNIST數據集中圖像形狀為 `$ 28 \times 28 $`,類別數為10。本節中我們依然使用長度為 `$ 28 \times 28 = 784 $` 的向量表示每一張圖像。因此,輸入個數為784,輸出個數為10。實驗中,我們設超參數隱藏單元個數為256。
``` python
num_inputs, num_outputs, num_hiddens = 784, 10, 256
W1 = torch.tensor(np.random.normal(0, 0.01, (num_inputs, num_hiddens)), dtype=torch.float)
b1 = torch.zeros(num_hiddens, dtype=torch.float)
W2 = torch.tensor(np.random.normal(0, 0.01, (num_hiddens, num_outputs)), dtype=torch.float)
b2 = torch.zeros(num_outputs, dtype=torch.float)
params = [W1, b1, W2, b2]
for param in params:
param.requires_grad_(requires_grad=True)
```
## 3.9.3 定義激活函數
這里我們使用基礎的`max`函數來實現ReLU,而非直接調用`relu`函數。
``` python
def relu(X):
return torch.max(input=X, other=torch.tensor(0.0))
```
## 3.9.4 定義模型
同softmax回歸一樣,我們通過`view`函數將每張原始圖像改成長度為`num_inputs`的向量。然后我們實現上一節中多層感知機的計算表達式。
``` python
def net(X):
X = X.view((-1, num_inputs))
H = relu(torch.matmul(X, W1) + b1)
return torch.matmul(H, W2) + b2
```
## 3.9.5 定義損失函數
為了得到更好的數值穩定性,我們直接使用PyTorch提供的包括softmax運算和交叉熵損失計算的函數。
``` python
loss = torch.nn.CrossEntropyLoss()
```
## 3.9.6 訓練模型
訓練多層感知機的步驟和3.6節中訓練softmax回歸的步驟沒什么區別。我們直接調用`d2lzh_pytorch`包中的`train_ch3`函數,它的實現已經在3.6節里介紹過。我們在這里設超參數迭代周期數為5,學習率為100.0。
> 注:由于原書的mxnet中的`SoftmaxCrossEntropyLoss`在反向傳播的時候相對于沿batch維求和了,而PyTorch默認的是求平均,所以用PyTorch計算得到的loss比mxnet小很多(大概是maxnet計算得到的1/batch_size這個量級),所以反向傳播得到的梯度也小很多,所以為了得到差不多的學習效果,我們把學習率調得成原書的約batch_size倍,原書的學習率為0.5,這里設置成100.0。(之所以這么大,應該是因為d2lzh_pytorch里面的sgd函數在更新的時候除以了batch_size,其實PyTorch在計算loss的時候已經除過一次了,sgd這里應該不用除了)
``` python
num_epochs, lr = 5, 100.0
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, params, lr)
```
輸出:
```
epoch 1, loss 0.0030, train acc 0.714, test acc 0.753
epoch 2, loss 0.0019, train acc 0.821, test acc 0.777
epoch 3, loss 0.0017, train acc 0.842, test acc 0.834
epoch 4, loss 0.0015, train acc 0.857, test acc 0.839
epoch 5, loss 0.0014, train acc 0.865, test acc 0.845
```
## 小結
* 可以通過手動定義模型及其參數來實現簡單的多層感知機。
* 當多層感知機的層數較多時,本節的實現方法會顯得較煩瑣,例如在定義模型參數的時候。
-----------
> 注:本節除了代碼之外與原書基本相同,[原書傳送門](https://zh.d2l.ai/chapter_deep-learning-basics/mlp-scratch.html)
- Home
- Introduce
- 1.深度學習簡介
- 深度學習簡介
- 2.預備知識
- 2.1環境配置
- 2.2數據操作
- 2.3自動求梯度
- 3.深度學習基礎
- 3.1 線性回歸
- 3.2 線性回歸的從零開始實現
- 3.3 線性回歸的簡潔實現
- 3.4 softmax回歸
- 3.5 圖像分類數據集(Fashion-MINST)
- 3.6 softmax回歸的從零開始實現
- 3.7 softmax回歸的簡潔實現
- 3.8 多層感知機
- 3.9 多層感知機的從零開始實現
- 3.10 多層感知機的簡潔實現
- 3.11 模型選擇、反向傳播和計算圖
- 3.12 權重衰減
- 3.13 丟棄法
- 3.14 正向傳播、反向傳播和計算圖
- 3.15 數值穩定性和模型初始化
- 3.16 實戰kaggle比賽:房價預測
- 4 深度學習計算
- 4.1 模型構造
- 4.2 模型參數的訪問、初始化和共享
- 4.3 模型參數的延后初始化
- 4.4 自定義層
- 4.5 讀取和存儲
- 4.6 GPU計算
- 5 卷積神經網絡
- 5.1 二維卷積層
- 5.2 填充和步幅
- 5.3 多輸入通道和多輸出通道
- 5.4 池化層
- 5.5 卷積神經網絡(LeNet)
- 5.6 深度卷積神經網絡(AlexNet)
- 5.7 使用重復元素的網絡(VGG)
- 5.8 網絡中的網絡(NiN)
- 5.9 含并行連結的網絡(GoogLeNet)
- 5.10 批量歸一化
- 5.11 殘差網絡(ResNet)
- 5.12 稠密連接網絡(DenseNet)
- 6 循環神經網絡
- 6.1 語言模型
- 6.2 循環神經網絡
- 6.3 語言模型數據集(周杰倫專輯歌詞)
- 6.4 循環神經網絡的從零開始實現
- 6.5 循環神經網絡的簡單實現
- 6.6 通過時間反向傳播
- 6.7 門控循環單元(GRU)
- 6.8 長短期記憶(LSTM)
- 6.9 深度循環神經網絡
- 6.10 雙向循環神經網絡
- 7 優化算法
- 7.1 優化與深度學習
- 7.2 梯度下降和隨機梯度下降
- 7.3 小批量隨機梯度下降
- 7.4 動量法
- 7.5 AdaGrad算法
- 7.6 RMSProp算法
- 7.7 AdaDelta
- 7.8 Adam算法
- 8 計算性能
- 8.1 命令式和符號式混合編程
- 8.2 異步計算
- 8.3 自動并行計算
- 8.4 多GPU計算
- 9 計算機視覺
- 9.1 圖像增廣
- 9.2 微調
- 9.3 目標檢測和邊界框
- 9.4 錨框
- 10 自然語言處理
- 10.1 詞嵌入(word2vec)
- 10.2 近似訓練
- 10.3 word2vec實現
- 10.4 子詞嵌入(fastText)
- 10.5 全局向量的詞嵌入(Glove)
- 10.6 求近義詞和類比詞
- 10.7 文本情感分類:使用循環神經網絡
- 10.8 文本情感分類:使用卷積網絡
- 10.9 編碼器--解碼器(seq2seq)
- 10.10 束搜索
- 10.11 注意力機制
- 10.12 機器翻譯