1. 程式人生 > >pytorch的基本使用

pytorch的基本使用

需要特別注意的一點

很多部落格或非官方教程中提到了pytorch中的tensor基本上和numpy中的array是一樣的,可以直接通過函式相互轉化,同時pytorch中有variable變數,variable是對tensor的一個封裝,用於構建計算圖,並進行迭代。但是對0.4.1版本來說,Variable不再被支援使用。 可以理解為Variable合併到了Tensor中。 我開始時一些部落格和文件同時看,一直以為tensor沒法求梯度,沒有注意到這一點,所以很困惑。。。 在這裡插入圖片描述

  1. 資料載入和預處理
  2. 模型定義,一般就兩個函式 。 __init__(self)函式中對要進行的計算進行初始化,即設定每層輸入輸出的數量,每層的計算型別。 __forward__(self,x)
    函式中定義具體的計算關係,即每層之間如何連線,是否要pool,relu還是sigmoid等。 如下
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()
  1. 定義損失函式和優化方式 。 之後計算loss時,使用loss = criterion(outputs, labels)
import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
  1. 訓練,每次迭代都是四行程式碼,對應訓練的四個步驟,非常明確。這也是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一樣構建了計算圖,不然沒辦法反向傳播。