1. 程式人生 > 程式設計 >Pytorch 實現權重初始化

Pytorch 實現權重初始化

在TensorFlow中,權重的初始化主要是在宣告張量的時候進行的。 而PyTorch則提供了另一種方法:首先應該宣告張量,然後修改張量的權重。通過呼叫torch.nn.init包中的多種方法可以將權重初始化為直接訪問張量的屬性。

1、不初始化的效果

在Pytorch中,定義一個tensor,不進行初始化,列印看看結果:

w = torch.Tensor(3,4)
print (w)

可以看到這時候的初始化的數值都是隨機的,而且特別大,這對網路的訓練必定不好,最後導致精度提不上,甚至損失無法收斂。

2、初始化的效果

PyTorch提供了多種引數初始化函式:

torch.nn.init.constant(tensor,val)
torch.nn.init.normal(tensor,mean=0,std=1)
torch.nn.init.xavier_uniform(tensor,gain=1)

等等。詳細請參考:http://pytorch.org/docs/nn.html#torch-nn-init

注意上面的初始化函式的引數tensor,雖然寫的是tensor,但是也可以是Variable型別的。而神經網路的引數型別Parameter是Variable類的子類,所以初始化函式可以直接作用於神經網路引數。實際上,我們初始化也是直接去初始化神經網路的引數。

讓我們試試效果:

w = torch.Tensor(3,4)
torch.nn.init.normal_(w)
print (w)

3、初始化神經網路的引數

對神經網路的初始化往往放在模型的__init__()函式中,如下所示:

class Net(nn.Module):

def __init__(self,block,layers,num_classes=1000):
  self.inplanes = 64
  super(Net,self).__init__()
  ***
  *** #定義自己的網路層
  ***

  for m in self.modules():
    if isinstance(m,nn.Conv2d):
      n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
      m.weight.data.normal_(0,math.sqrt(2. / n))
    elif isinstance(m,nn.BatchNorm2d):
      m.weight.data.fill_(1)
      m.bias.data.zero_()

***
*** #定義後續的函式
***

也可以採取另一種方式:

定義一個權重初始化函式,如下:

def weights_init(m):
  classname = m.__class__.__name__
  if classname.find('Conv2d') != -1:
    init.xavier_normal_(m.weight.data)
    init.constant_(m.bias.data,0.0)
  elif classname.find('Linear') != -1:
    init.xavier_normal_(m.weight.data)
    init.constant_(m.bias.data,0.0)

在模型宣告時,呼叫初始化函式,初始化神經網路引數:

model = Net(*****)
model.apply(weights_init)

以上這篇Pytorch 實現權重初始化就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。