天天看點

pytorch中的細節問題

1 nn.Module.cuda() 和 Tensor.cuda() 的作用效果差異:

對于nn.Module:

model = model.cuda()

model.cuda()

上述兩句能夠達到同樣的效果,即對Model自身進行記憶體遷移

2 對于Tensor:

nn.Module不同,調用tensor.cuda()隻是傳回這個tensor對象在GPU記憶體上的拷貝,而不會對自身進行改變

是以必須對tensor進行重新指派,即tensor=tensor.cuda()

model = create_a_model()

tensor = torch.zeros([2,3,10,10])

model.cuda()

tensor.cuda()

model(tensor) # 會報錯

tensor = tensor.cuda()

model(tensor) # 正常運作

3 pytorch計算累積損失的不同

廣泛使用的模式total_loss += loss.data[0]為例

Python0.4.0之前,loss是一個封裝了(1,)張量的Variable,但Python0.4.0的loss現在是一個零維的标量。

對标量進行索引是沒有意義的(似乎會報 invalid index to scalar variable 的錯誤)。

使用loss.item()可以從标量中擷取Python數字。是以改為total_loss += loss.item()

如果在累加損失時未将其轉換為Python數字,則可能出現程式記憶體使用量增加的情況。

這是因為上面表達式的右側原本是一個Python浮點數,而它現在是一個零維張量。

是以,總損失累加了張量和它們的梯度曆史,這可能會産生很大的autograd 圖,耗費記憶體和計算資源

4 torch.Tensor.detach()的使用

假設有模型A和模型B,我們需要将A的輸出作為B的輸入,但訓練時我們隻訓練模型B. 那麼可以這樣做:

input_B = output_A.detach()

它可以使兩個計算圖的梯度傳遞斷開,進而實作我們所需的功能

5 pytorch中loss函數的參數設定

https://blog.csdn.net/hyk_1996/article/details/80824747 參考博文連結位址

6 pytorch的可重複性問題

https://blog.csdn.net/hyk_1996/article/details/84307108 參考博文連結位址

7多GPU處理機制

使用多GPU時,應該記住pytorch的處理邏輯是:

1.在各個GPU上初始化模型。

2.前向傳播時,把batch配置設定到各個GPU上進行計算。

3.得到的輸出在主GPU上進行彙總,計算loss并反向傳播,更新主GPU上的權值。

4.把主GPU上的模型複制到其它GPU上

8 num_batches_tracked參數

KeyError: ‘unexpected key “module.bn1.num_batches_tracked” in state_dict’

經過研究發現,在pytorch 0.4.1及後面的版本裡,BatchNorm層新增了num_batches_tracked參數,用來統計訓練時的forward過的batch數目,源碼如下(pytorch0.4.1)

參數和訓練時的歸一化的計算方式有關。

是以,我們可以知道該錯誤是由于訓練和測試所用的pytorch版本(0.4.1版本前後的差異)不一緻引起的。具體的解決方案是:如果是模型參數(Orderdict格式,很容易修改)裡少了num_batches_tracked變量,就加上去,如果是多了就删掉。偷懶的做法是将load_state_dict的strict參數置為False,如下所示:

load_state_dict(torch.load(weight_path), strict=False)