torch.nn 究竟是什么?
PyTorch 提供了設計精良的模塊和類,如 torch.nn、torch.optim、Dataset 和 DataLoader,幫助你創建和訓練神經網絡。為了充分利用它們的能力并根據你的問題進行定制,你需要真正理解它們到底在做什么。為了幫助你理解這一點,我們將首先在不使用這些模塊的任何功能的情況下,在 MNIST 數據集上訓練一個基本的神經網絡;我們最初只使用最基本的 PyTorch 張量功能。然后,我們將每次增量添加 torch.nn
、torch.optim
、Dataset
或 DataLoader
中的一個功能,準確展示每個部分的作用,以及它是如何使代碼更簡潔或更靈活的。
本教程假設你已安裝 PyTorch,并熟悉張量操作的基礎知識。(如果你熟悉 Numpy 數組操作,你會發現此處使用的 PyTorch 張量操作幾乎相同)。
MNIST 數據設置
我們將使用經典的 MNIST 數據集,該數據集包含手寫數字(0 到 9)的黑白圖像。
我們將使用 pathlib 來處理路徑(它是 Python 3 標準庫的一部分),并將使用 requests 下載數據集。我們只在使用時導入模塊,這樣你就可以清楚地看到每一步使用了什么。
from pathlib import Path
import requestsDATA_PATH = Path("data")
PATH = DATA_PATH / "mnist"PATH.mkdir(parents=True, exist_ok=True)URL = "https://github.com/pytorch/tutorials/raw/main/_static/"
FILENAME = "mnist.pkl.gz"if not (PATH / FILENAME).exists():content = requests.get(URL + FILENAME).content(PATH / FILENAME).open("wb").write(content)
該數據集采用 numpy 數組格式,并使用 pickle(一種 Python 特有的數據序列化格式)存儲。
import pickle
import gzipwith gzip.open((PATH / FILENAME).as_posix(), "rb") as f:((x_train, y_train), (x_valid, y_valid), _) = pickle.load(f, encoding="latin-1")
每張圖像是 28 x 28 像素,并以長度為 784 (=28x28) 的扁平行存儲。讓我們看一張;我們需要先將其重塑為 2D 形式。
from matplotlib import pyplot
import numpy as nppyplot.imshow(x_train[0].reshape((28, 28)), cmap="gray")
# ``pyplot.show()`` only if not on Colab
try:import google.colab
except ImportError:pyplot.show()
print(x_train.shape)
# plt.show()
輸出為:
(50000, 784)
得到的圖像:
PyTorch 使用 torch.tensor
而非 numpy 數組,因此我們需要轉換數據。
import torchx_train, y_train, x_valid, y_valid = map(torch.tensor, (x_train, y_train, x_valid, y_valid)
)
n, c = x_train.shape
print(x_train, y_train)
print(x_train.shape)
print(y_train.min(), y_train.max())
輸出為:
tensor([[0., 0., 0., ..., 0., 0., 0.],[0., 0., 0., ..., 0., 0., 0.],[0., 0., 0., ..., 0., 0., 0.],...,[0., 0., 0., ..., 0., 0., 0.],[0., 0., 0., ..., 0., 0., 0.],[0., 0., 0., ..., 0., 0., 0.]]) tensor([5, 0, 4, ..., 8, 4, 8])
torch.Size([50000, 784])
tensor(0) tensor(9)
從頭開始構建神經網絡(不使用 torch.nn
)
我們首先只使用 PyTorch 張量操作創建一個模型。我們假設你已經熟悉神經網絡的基礎知識。(如果你不熟悉,可以在