1. 構建網絡層
採用torch.nn.Sequentional()來構建網絡層,不過使用這種方法,每層的編碼是默認的數字,不易區分。
可以在sequential()的基礎上,通過字典的形式添加每一層,並且設置單獨的層名稱。
import torch.nn
from collections import OrderedDict
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv = torch.nn.Sequential(
OrderedDict(
[
("conv1",torch.nn.Conv2d(3,32,3,2,2)),
("relu1",torch.nn.ReLU()),
("pool",torch.nn.MaxPool2d(2))
]
)
)
self.dense = torch.nn.Sequential(
OrderedDict(
[
("dense1", torch.nn.Linear(32*3*3, 128)),
("relu2", torch.nn.ReLU()),
("dense2", torch.nn.Linear(128,10))
]
)
)
2. 前向傳播
定義好每層後,還需要通過前向傳播的方式把這些串起來。這就涉及如何定義forward函數的問題。forward函數的任務需要把輸入層、網絡層、輸出層鏈接起來,實現信息的前向傳導。該函數的參數輸入數據,返回值爲輸出數據。
在forward函數中,有些層來自nn.Module,也可以使用nn.functional定義。來自nn.Module的需要實例化,而使用nn.functional定義的可以直接使用。
3. 反向傳播
前向傳播函數定義好以後,接下來就是梯度的反向傳播。Pytorch提供了自動反向傳播的功能,使用nn工具箱,無需自己編寫反向傳播,直接讓損失函數(loss)調用backward()即可。
4. 訓練模型
訓練模型時,需要注意使模型處於訓練模式,即調用model.train(),調用model.train()會把所有的model設置爲訓練模式。如果是測試或驗證階段,需要使模型處於驗證階段,即調用model.eval(),調用model.eval()會把所有的training屬性設置爲False。
缺省情況下梯度是累加的,需要手動把梯度初始化或清零,調用optimizer.zero_grad()即可。
訓練過程中,正向傳播生成網絡的輸出,計算輸出和實際值之間的損失值,調用loss.backward()自動生成梯度,然後使用optimizer.step()執行優化器,把梯度傳播回每個網絡。