1. 程式人生 > 程式設計 >pytorch 中的重要模組化介面nn.Module的使用

pytorch 中的重要模組化介面nn.Module的使用

torch.nn 是專門為神經網路設計的模組化介面,nn構建於autgrad之上,可以用來定義和執行神經網路
nn.Module 是nn中重要的類,包含網路各層的定義,以及forward方法

檢視原始碼

初始化部分:

def __init__(self):
  self._backend = thnn_backend
  self._parameters = OrderedDict()
  self._buffers = OrderedDict()
  self._backward_hooks = OrderedDict()
  self._forward_hooks = OrderedDict()
  self._forward_pre_hooks = OrderedDict()
  self._state_dict_hooks = OrderedDict()
  self._load_state_dict_pre_hooks = OrderedDict()
  self._modules = OrderedDict()
  self.training = True

屬性解釋:

  • _parameters:字典,儲存使用者直接設定的 Parameter
  • _modules:子 module,即子類建構函式中的內容
  • _buffers:快取
  • _backward_hooks與_forward_hooks:鉤子技術,用來提取中間變數
  • training:判斷值來決定前向傳播策略

方法定義:

def forward(self,*input):
 raise NotImplementedError

沒有實際內容,用於被子類的 forward() 方法覆蓋

且 forward 方法在 __call__ 方法中被呼叫:

def __call__(self,*input,**kwargs):
 for hook in self._forward_pre_hooks.values():
    hook(self,input)
  if torch._C._get_tracing_state():
    result = self._slow_forward(*input,**kwargs)
  else:
    result = self.forward(*input,**kwargs)
  ...
  ...

對於自己定義的網路,需要注意以下幾點:

1)需要繼承nn.Module類,並實現forward方法,只要在nn.Module的子類中定義forward方法,backward函式就會被自動實現(利用autograd機制)
2)一般把網路中可學習引數的層放在建構函式中__init__(),沒有可學習引數的層如Relu層可以放在建構函式中,也可以不放在建構函式中(在forward函式中使用nn.Functional)
3)在forward中可以使用任何Variable支援的函式,在整個pytorch構建的圖中,是Variable在流動,也可以使用for,print,log等
4)基於nn.Module構建的模型中,只支援mini-batch的Variable的輸入方式,如,N*C*H*W

程式碼示例:

class LeNet(nn.Module):
  def __init__(self):
    # nn.Module的子類函式必須在建構函式中執行父類的建構函式
    super(LeNet,self).__init__() # 等價與nn.Module.__init__()

    # nn.Conv2d返回的是一個Conv2d class的一個物件,該類中包含forward函式的實現
    # 當呼叫self.conv1(input)的時候,就會呼叫該類的forward函式
    self.conv1 = nn.Conv2d(1,6,(5,5)) # output (N,C_{out},H_{out},W_{out})`
    self.conv2 = nn.Conv2d(6,16,5))
    self.fc1 = nn.Linear(256,120)
    self.fc2 = nn.Linear(120,84)
    self.fc3 = nn.Linear(84,10)

  def forward(self,x):
    # F.max_pool2d的返回值是一個Variable, input:(10,1,28,28) ouput:(10,12,12)
    x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
    # input:(10,12)  output:(10,4,4)
    x = F.max_pool2d(F.relu(self.conv2(x)),2))
    # 固定樣本個數,將其他維度的資料平鋪,無論你是幾通道,最終都會變成引數, output:(10,256)
    x = x.view(x.size()[0],-1)
    # 全連線
    x = F.relu(self.fc1(x))
    x = F.relu(self.fc2(x))
    x = F.relu(self.fc3(x))

    # 返回值也是一個Variable物件
    return x


def output_name_and_params(net):
  for name,parameters in net.named_parameters():
    print('name: {},param: {}'.format(name,parameters))


if __name__ == '__main__':
  net = LeNet()
  print('net: {}'.format(net))
  params = net.parameters() # generator object
  print('params: {}'.format(params))
  output_name_and_params(net)

  input_image = torch.FloatTensor(10,28)

  # 和tensorflow不一樣,pytorch中模型的輸入是一個Variable,而且是Variable在圖中流動,不是Tensor。
  # 這可以從forward中每一步的執行結果可以看出
  input_image = Variable(input_image)

  output = net(input_image)
  print('output: {}'.format(output))
  print('output.size: {}'.format(output.size()))

到此這篇關於pytorch 中的重要模組化介面nn.Module的使用的文章就介紹到這了,更多相關pytorch nn.Module內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!