pytorch程式碼個人心得
阿新 • • 發佈:2018-12-27
#1
nn.crossentropyloss()類包含兩步函式: log_softmax和nllloss,(log-likelihood loss), 後者沒有log步驟。
如果loss只想要交叉熵,不要softmax步驟,可以在網路最後加上nn.softmax層,以及torch.log()函式進行輸出,訓練的loss使用nn.NLLLoss()類。
#2
torch.log()等運算不需要參提供引數,所以直接呼叫即可。
torch.nn.functional是函式,除了一般的輸入輸出,還需要輸入計算所用的引數,所以不能直接呼叫。定義如下:
def cross_entropy(input, target, weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='elementwise_mean'): if size_average is not None or reduce is not None: reduction = _Reduction.legacy_get_string(size_average, reduce) return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)
為了使用torch.nn.functional更加方便, 就有了類torch.nn.CrossEntropyLoss,這裡init定義了需要的引數,在forward裡呼叫torch.nn.functional, 這樣就很好地解決了引數的儲存問題,使得神經網路訓練過程更加方便。
class CrossEntropyLoss(_WeightedLoss): def __init__(self, weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='elementwise_mean'): super(CrossEntropyLoss, self).__init__(weight, size_average, reduce, reduction) self.ignore_index = ignore_index def forward(self, input, target): return F.cross_entropy(input, target, weight=self.weight, ignore_index=self.ignore_index, reduction=self.reduction)
#3
在版本3.0.1中,Variable最好作為一個整體來做處理,而不要拆分,否則容易影響到梯度的計算。
比如, 想對一個數組變數s的個別分量做倍乘等處理,可以單獨設定一個和s一樣尺寸的變數mask,初始化為1,把mask在s要處理的對應位置上設為倍乘倍率,然後點乘s*mask。這樣做矩陣導數可以直接得到這一步對mask的導數為s。
#4
pytorch中的autograd求梯度方式不會儲存中間量(如x)的梯度,只會儲存類初始化定義的變數(如self.conv()引數)。
而hook函式可以記錄中間的任意中間量,如CNN裡面的feature map。 Grad_CAM裡就是使用的這個函式。、