Pytorch本人疑問(1) torch.nn和torch.nn.functional之間的區別


 

在寫代碼時發現我們在定義Model時,有兩種定義方法:

torch.nn.Conv2d()和torch.nn.functional.conv2d()

那么這兩種方法到底有什么區別呢,我們通過下述代碼看出差別,先拿torch.nn.Conv2d

  • torch.nn.Conv2d
class Conv2d(_ConvNd):
    def __init__(self, in_channels, out_channels, kernel_size, stride=1,
                 padding=0, dilation=1, groups=1,
                 bias=True, padding_mode='zeros'):
        kernel_size = _pair(kernel_size)
        stride = _pair(stride)
        padding = _pair(padding)
        dilation = _pair(dilation)
        super(Conv2d, self).__init__(
            in_channels, out_channels, kernel_size, stride, padding, dilation,
            False, _pair(0), groups, bias, padding_mode)

        def forward(self, input):
            return self.conv2d_forward(input, self.weight)    
  • torch.nn.functional.conv2d
def conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1,
                groups=1):
    if input is not None and input.dim() != 4:
        raise ValueError("Expected 4D tensor as input, got {}D tensor instead.".format(input.dim()))
    f = _ConvNd(_pair(stride), _pair(padding), _pair(dilation), False,
                        _pair(0), groups, torch.backends.cudnn.benchmark,
            torch.backends.cudnn.deterministic,torch.backends.cudnn.enabled)  
    return f(input, weight, bias)

對比上述代碼我們可以發現,torch.nn.Conv2d是一個類,而torch.nn.functiona.conv2d()是一個函數,並且torch.nn.Conv2d中的forward()函數

是由torch.nn.functiona.conv2d()實現的(在Module類中有一個__call__實現了forward的調用)所以他們在功能的使用上並沒有什么區別,但是我

們有了一個疑問,為什么要有着兩個功能一樣的方法呢?

其實主要的原因在乎我們構建計算圖的時候,有些操作不需要進行體現在計算圖中的,例如ReLu層,池化層。但是像卷積層、全連接層還是

需要體現在計算圖中的。如果所有的層我們都用torch.nn.functional來定義,那么我們需要將卷積層和全連接層中的weights、bias全部手動寫入

計算圖中去,這樣是非常不方便的。如果我們全部使用類的方式來構建計算圖,這樣即使是非常簡單的操作都需要構建類,這樣是寫代碼的效率是

非常低的。所以我們將卷積層、全連接層使用類的方式來進行定義,將池化和激活操作使用函數的方式進行使用,這樣使我們更方便的構建計算圖。

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM