pytorch的基本使用
阿新 • • 發佈:2018-12-13
需要特別注意的一點
很多部落格或非官方教程中提到了pytorch中的tensor基本上和numpy中的array是一樣的,可以直接通過函式相互轉化,同時pytorch中有variable變數,variable是對tensor的一個封裝,用於構建計算圖,並進行迭代。但是對0.4.1版本來說,Variable不再被支援使用。 可以理解為Variable合併到了Tensor中。 我開始時一些部落格和文件同時看,一直以為tensor沒法求梯度,沒有注意到這一點,所以很困惑。。。
- 資料載入和預處理
- 模型定義,一般就兩個函式 。
__init__(self)
函式中對要進行的計算進行初始化,即設定每層輸入輸出的數量,每層的計算型別。__forward__(self,x)
class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(3, 6, 5) self.pool = nn.MaxPool2d(2, 2) self.conv2 = nn.Conv2d(6, 16, 5) self.fc1 = nn.Linear(16 * 5 * 5, 120) self.fc2 = nn.Linear(120, 84) self.fc3 = nn.Linear(84, 10) def forward(self, x): x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = x.view(-1, 16 * 5 * 5) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return x net = Net()
- 定義損失函式和優化方式 。
之後計算loss時,使用
loss = criterion(outputs, labels)
import torch.optim as optim
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
- 訓練,每次迭代都是四行程式碼,對應訓練的四個步驟,非常明確。這也是PyTorch的優勢。 四個步驟分別是,前向傳播,計算loss,反向傳播(計算所有引數的梯度),更新引數。
# forward + backward + optimize outputs = net(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step()
- 這裡有個不太明白的地方,為什麼
backward()
是loss的函式? 反向傳播求梯度時,是需要知道神經網路的結構,但是神經網路的結構是定義在Net()
這個類中的,loss沒有獲得神經網路的結構啊,只是通過 output和labels這兩個向量進行了計算。 - 查看了部分原始碼,大概知道每一句做了什麼。
(1) 首先了解一下python類中的
__call__()
函式,__call__()
函式是python類中的特殊函式,初始化物件後,如net = Net()
,執行net()
,這是就會呼叫Net
這個()類中的__call__()
函式。 (2) 執行outputs = net(inputs)
時就呼叫了父類Module中的__call__()
函式,其中呼叫了forward()
函式,forward()
函式返回型別是Tensor。 之後通過loss = criterion(outputs, labels)
來計算損失,這裡也呼叫了CrossEntropyLoss
類中的forward()
函式,返回型別為Variable,即loss型別為Tensor。 (3)loss.backward()
執行了tensor.backward()
, 其中其實是執行了torch.autograd.backward()
- 這裡看著每一步很明確,就像在python中一步一步的來做運算。但還是跟tensorflow一樣構建了計算圖,不然沒辦法反向傳播。