CNN循環訓練的解釋 | PyTorch系列(二十二)

點擊上方AI算法與圖像處理”,選擇加"星標"或“置頂”

重磅乾貨,第一時間送達

文 |AI_study

原標題:CNN Training Loop Explained - Neural Network Code Project

  • 準備數據

  • 建立模型

  • 訓練模型

    • 建立訓練 loop

  • 分析模型的結果

單個 batch  進行訓練 

我們可以將單個 batch  訓練的代碼總結如下:

network = Network()


train_loader = torch.utils.data.DataLoader(train_set, batch_size=100)
optimizer = optim.Adam(network.parameters(), lr=0.01)


batch = next(iter(train_loader)) # Get Batch
images, labels = batch


preds = network(images) # Pass Batch
loss = F.cross_entropy(preds, labels) # Calculate Loss


loss.backward() # Calculate Gradients
optimizer.step() # Update Weights


print('loss1:', loss.item())
preds = network(images)
loss = F.cross_entropy(preds, labels)
print('loss2:', loss.item())

輸出

loss1: 2.3034827709198
loss2: 2.2825052738189697

您會注意到的一件事是,每次運行這段代碼都會得到不同的結果。這是因爲模型每次都是在頂部創建的,我們從以前的文章中知道模型的權重是隨機初始化的。

現在讓我們看看如何修改這段代碼來使用所有的batch,從而使用整個訓練集進行訓練。

所有 batch的訓練 (epoch)

現在,爲了訓練我們的數據加載器中可用的所有批次,我們需要做一些更改並添加額外的一行代碼:

network = Network()


train_loader = torch.utils.data.DataLoader(train_set, batch_size=100)
optimizer = optim.Adam(network.parameters(), lr=0.01)


total_loss = 0
total_correct = 0


for batch in train_loader: # Get Batch
    images, labels = batch


    preds = network(images) # Pass Batch
    loss = F.cross_entropy(preds, labels) # Calculate Loss


    optimizer.zero_grad()
    loss.backward() # Calculate Gradients
    optimizer.step() # Update Weights


    total_loss += loss.item()
    total_correct += get_num_correct(preds, labels)
    
print(
    "epoch:", 0, 
    "total_correct:", total_correct, 
    "loss:", total_loss
)

我們將創建一個for循環來迭代所有batch  處理,而不是從數據加載器獲取單個batch  處理。

因爲我們的訓練集中有60,000個樣本,所以我們將有60,000 / 100 = 600次迭代。由於這個原因,我們將從循環中刪除print語句,並跟蹤總損失和最後打印它們的正確預測總數。

關於這600次迭代需要注意的一點是,到循環結束時,我們的權重將更新600次。如果我們提高batch_size這個數字會下降如果我們降低batch_size這個數字會上升。

最後,在我們對loss張量調用backward() 方法之後,我們知道梯度將被計算出來並添加到網絡參數的grad屬性中。因爲這個原因,我們需要把這些梯度歸零。我們可以使用優化器附帶的zero_grad()方法來實現這一點。

我們已經準備好運行這段代碼。這一次代碼將花費更長的時間,因爲循環將處理600個批。

epoch: 0 total_correct: 42104 loss: 476.6809593439102

我們得到了結果,我們可以看到60000中正確的總數是42104。

> total_correct / len(train_set)
0.7017333333333333

在只有一個epoch(一次完整的數據傳遞)之後,這已經很好了。即使我們做了一個epoch,我們仍然需要記住,權重被更新了600次,這取決於我們的批大小。如果讓batch_batch的大小更大一些,比如10,000,那麼權重只會更新  6  次,結果也不會很好。

多個 epoch的 訓練 

要執行多個epoch,我們所要做的就是將此代碼放入for循環中。我們還將把epoch數添加到print語句中。

network = Network()


train_loader = torch.utils.data.DataLoader(train_set, batch_size=100)
optimizer = optim.Adam(network.parameters(), lr=0.01)


for epoch in range(10):
    
    total_loss = 0
    total_correct = 0
    
    for batch in train_loader: # Get Batch
        images, labels = batch


        preds = network(images) # Pass Batch
        loss = F.cross_entropy(preds, labels) # Calculate Loss


        optimizer.zero_grad()
        loss.backward() # Calculate Gradients
        optimizer.step() # Update Weights


        total_loss += loss.item()
        total_correct += get_num_correct(preds, labels)


    print(
        "epoch", epoch, 
        "total_correct:", total_correct, 
        "loss:", total_loss
    )

運行這段代碼後,我們得到每個epoch的結果:

epoch 0 total_correct: 43301 loss: 447.59147948026657
epoch 1 total_correct: 49565 loss: 284.43429669737816
epoch 2 total_correct: 51063 loss: 244.08825492858887
epoch 3 total_correct: 51955 loss: 220.5841210782528
epoch 4 total_correct: 52551 loss: 204.73878084123135
epoch 5 total_correct: 52914 loss: 193.1240530461073
epoch 6 total_correct: 53195 loss: 184.50964668393135
epoch 7 total_correct: 53445 loss: 177.78808392584324
epoch 8 total_correct: 53629 loss: 171.81662507355213
epoch 9 total_correct: 53819 loss: 166.2412590533495

我們可以看到正確值的數量增加了,而loss減少了。

完整的訓練 loop

將所有這些放在一起,我們可以將網絡、優化器和train_loader從訓練循環單元中提取出來。

network = Network()
optimizer = optim.Adam(network.parameters(), lr=0.01)
train_loader = torch.utils.data.DataLoader(
    train_set
    ,batch_size=100
    ,shuffle=True
)

optimizer = optim.Adam(network.parameters(), lr=0.01)

for epoch in range(10):


    total_loss = 0
    total_correct = 0


    for batch in train_loader: # Get Batch
        images, labels = batch


        preds = network(images) # Pass Batch
        loss = F.cross_entropy(preds, labels) # Calculate Loss


        optimizer.zero_grad()
        loss.backward() # Calculate Gradients
        optimizer.step() # Update Weights


        total_loss += loss.item()
        total_correct += get_num_correct(preds, labels)


    print(
        "epoch", epoch, 
        "total_correct:", total_correct, 
        "loss:", total_loss
    )

接下來是可視化結果

我們現在應該很好地理解了訓練循環以及如何使用PyTorch來構建它們。PyTorch很酷的一點是,我們可以像調試forward()函數那樣調試訓練循環代碼。

在下一篇文章中,我們將看到如何獲得訓練集中每個樣本的預測,並使用這些預測創建一個混淆矩陣。下節課見!

文章中內容都是經過仔細研究的,本人水平有限,翻譯無法做到完美,但是真的是費了很大功夫,希望小夥伴能動動你性感的小手,分享朋友圈或點個“在看”,支持一下我 ^_^

英文原文鏈接是:

https://deeplizard.com/learn/video/XfYmia3q2Ow

加羣交流

歡迎小夥伴加羣交流,目前已有交流羣的方向包括:AI學習交流羣,目標檢測,秋招互助,資料下載等等;加羣可掃描並回復感興趣方向即可(註明:地區+學校/企業+研究方向+暱稱)

 謝謝你看到這裏! ????

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章