• 0606-nn.functional


    0606-nn.functional

    pytorch完整教程目录:https://www.cnblogs.com/nickchen121/p/14662511.html

    一、nn.functional 和 nn.Module 的区别

    nn 中还有一个经常使用的模块 nn.functional,nn 中的绝大多数的 layer 在 functional 中都有一个和它对应的函数。

    nn.functionalnn.Module的区别在于,Module 实现的 layers 是一个特殊的类,由 class Layer(nn.Module) 定义,会自动提取可学习的参数;而 functional 中的函数更像是一个纯函数,由 def fucntion(input) 定义。

    import torch as t
    from torch import nn
    from torch.autograd import Variable as V
    inp = V(t.randn(2, 3))
    model = nn.Linear(3, 4)
    output1 = model(inp)
    output2 = nn.functional.linear(inp, model.weight, model.bias)
    output1 == output2
    
    tensor([[True, True, True, True],
            [True, True, True, True]])
    
    b = nn.functional.relu(inp)
    b2 = nn.ReLU()(inp)
    b == b2
    
    tensor([[True, True, True],
            [True, True, True]])
    

    从上述代码可以看到 Module 和 functional 的功能类似,那么这两者我们什么时候会用到呢?

    答案很简单,如果有可学习的参数时,最好用 Module,反之既可以用 functional,当然也可以用 Module,因为二者在性能上并没有很大的差别。

    例如,由于激活函数、池化等层没有可学习参数,可以使用对应的 functional 函数代替,而卷积、全连接层有可学习参数,尽量使用 Module。

    但是有一个例外,dropout 操作也没有可学习参数,但是由于 dropout 操作在训练和测试两个阶段的行为有区别,如果使用 Module 对象那个能够通过 model.eval 加以区分。

    二、nn.functional 和 nn.Module 结合使用

    下面举例将 functional 和 Module 结合使用。

    from torch.nn import functional as F
    
    
    class Net(nn.Module):
        def __init__(self):
            super(Net, self).__init__()
            self.conv1 = nn.Conv2d(3, 6, 5)
            self.conv2 = nn.Conv2d(6, 16, 5)
            self.fc1 = nn.Linear(16 * 5 * 5, 120)
            self.fc2 = nn.Linear(120, 84)
            self.fc3 = nn.Linear(84, 10)
    
        def forward(self, x):
            x = F.pool(F.relu(self.conv1(x)), 2)
            x = F.pool(F.relu(self.conv2(x)), 2)
            x = x.view(-1, 16 * 5 * 5)
            x = F.relu(self.fc1(x))
            x = F.relu(self.fc2(x))
            x = self.fc3(x)
    
            return x
    

    没有可学习参数的层,可以用函数代替他们,因此可以不用放在构造函数中。

    对于有可学习参数的层,虽然也可以用 functional 替代,只不过实现起来步骤麻烦,需要自己手动定义参数,比如前面实现的全连接层,既可以吧 weight 和 bias 两个参数拿出来,在构造函数中初始化为 parameter,例子如下:

    class MyLinear(nn.Module):
        def __init__(self):
            super(MyLinear, sefl).__init__()
            self.weight = nn.Parameter(t.randn(3, 4))
            self.bias = nn.Parameter(t.zeros(3))
    
        def forward(self):
            return F.linear(input, weight, bias)
    

    从上面的代码可以看出,如果通过 functional 去构造一个具有可学习参数的层,是非常麻烦的,不如 Module 那样简便。

    很多同学现在可能会想,functional 看起也不是那么方便,并且 Module 已经够好了,为什么还要设计 functional 呢?想深入了解 functional 和 Module的区别的同学,可以参考论坛的讨论和作者写的说明:https://discuss.pytorch.org/search?q=nn.functional

  • 相关阅读:
    实验10 指针2。
    作业5 指针应用1。
    实验9 指针1。
    作业4 函数应用。
    实验8 数组2。
    实验7 综合练习。
    实验6 数组1。
    实验5 函数。
    作业3 应用分支与循环结构解决问题。
    作业2 分支、循环结构。
  • 原文地址:https://www.cnblogs.com/nickchen121/p/14701785.html
Copyright © 2020-2023  润新知