易学好用的 Pytorch—Module模块

这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战

在 PyTorch 的 nn,nn 也就是 neural network 的缩写,在 nn 包中有一个 Module 类这是神经网络模块的基类,我们定义层、块大部分都是 Module 的子类。

  • 定义 class 并且继承于 nn.Module
  • 在 class 中,定义其属性为 layer
  • 实现 class 中 forward 方法
class Network:
  def __init__(self):
    self.layer = None

  def forward(self,t):
    t = self.layer(t)
    return t
复制代码

然后我们在这个基础上进行小小改造就得到了一个 pytorch ,让 Network 继承于 nn.Module类,好处是 nn.Module 在背后做了很多工作。

class Network(nn.Module):
  def __init__(self):
    super(Network,self).__init__()
    self.layer = None

  def forward(self,t):
    t = self.layer(t)
    return t
复制代码
class Network(nn.Module):
  def __init__(self):
    super(Network,self).__init__()
    self.conv1 = nn.Conv2d(in_channels=1,out_channels=6,kernel_size=5)
    self.conv2 = nn.Conv2d(in_channels=6,out_channels=12,kernel_size=5)

    self.fc1 = nn.Linear(in_features=12*4*4,out_features=120)
    self.fc2 = nn.Linear(in_features=120,out_features=60)
    self.out = nn.Linear(in_features=60,out_features=10)

  def forward(self,t):
    return t
复制代码

我们可以通过实例化一个网络,然后通过实例来查看一下网络的结构。

network = Network()
network
复制代码
Network( (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1)) (conv2): Conv2d(6, 12, kernel_size=(5, 5), stride=(1, 1)) (fc1): Linear(in_features=192, out_features=120, bias=True) (fc2): Linear(in_features=120, out_features=60, bias=True) (out): Linear(in_features=60, out_features=10, bias=True) )
复制代码
class CustomLinear(nn.Module):
  def __init__(self,in_features,out_features,bias=True):
      super(CustomLinear,self).__init__()
      self.in_features = in_features
      self.out_features = out_features

      self.weight = Parameter(torch.Tensor(out_features,in_features))
      if bias:
        self.bias = Parameter(torch.Tensor(out_features))
      else:
        self.register_parameter('bias',None)
      
      self.reset_parameters()
    
    def forward(self,input):
      return F.linear(input,self.weight,self.bias)
复制代码

这里 Parameter 是继承于 torch.Tensor 的类,这个 self.weight 是模型在训练过程需要通过学习不断更新的变量。在源码中 self.register_parameter(name,value) 对参数进行注册。

我们经常会遇到 argument 和 parameter 这两个词,他们区别是,当调用一个函数传入参数是 argument,argument 是实实在在数值我们传入到要调用函数的数值。而在函数内部持有变量的是 parameter,也就是 parameter 通用于函数内部,出于此原因我们可以将 parameter 看成一个 placeholder。我们可以用 argument 来更新内部的 parameter。

self.conv1 = nn.Conv2d(in_channels=1,out_channels=6,kernel_size=5)
self.conv2 = nn.Conv2d(in_channels=6,out_channels=12,kernel_size=5)

self.fc1 = nn.Linear(in_features=12*4*4,out_features=120)
self.fc2 = nn.Linear(in_features=120,out_features=60)
self.out = nn.Linear(in_features=60,out_features=10)
复制代码
  • Hyperparameter(超参数)
  • Data dependent hyperparameter

在 Conv2d 的参数为 in_channels、out_channels 和 kernel_size 三个参数,而对于 Linear 只有 in_features 和 out_features 两个参数。那么 Hyperparameter 超参数是人为选定的参数,但是并不是随意选择,主要基于验证和误差反馈来选择利于得到好的效果来调整这些参数。在卷积层和全连接层 kernel_sizeout_featuresout_channels 是人为定义参数。

其中 conv1 的 in_channels 和 out 全连接层 out_features 依赖数据和任务的,所以这些参数是 Data dependent hyperparameter 的参数。

猜你喜欢

转载自juejin.im/post/7061534341267980325