1. 程式人生 > >pytorch程式碼個人心得

pytorch程式碼個人心得

#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裡就是使用的這個函式。、