Pytorch中怎么调用forward()函数

其他教程   发布日期:2023年06月22日   浏览次数:463

这篇文章主要讲解了“Pytorch中怎么调用forward()函数”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Pytorch中怎么调用forward()函数”吧!

Pytorch调用forward()函数

Module类是nn模块里提供的一个模型构造类,是所有神经网络模块的基类,我们可以继承它来定义我们想要的模型。

下面继承Module类构造本节开头提到的多层感知机。

这里定义的MLP类重载了Module类的__init__函数和forward函数。

它们分别用于创建模型参数和定义前向计算。

前向计算也即正向传播。

  1. import torch
  2. from torch import nn
  3. class MLP(nn.Module):
  4. # 声明带有模型参数的层,这里声明了两个全连接层
  5. def __init__(self, **kwargs):
  6. # 调用MLP父类Module的构造函数来进行必要的初始化。这样在构造实例时还可以指定其他函数
  7. # 参数,如“模型参数的访问、初始化和共享”一节将介绍的模型参数params
  8. super(MLP, self).__init__(**kwargs)
  9. self.hidden = nn.Linear(784, 256) # 隐藏层
  10. self.act = nn.ReLU()
  11. self.output = nn.Linear(256, 10) # 输出层
  12. # 定义模型的前向计算,即如何根据输入x计算返回所需要的模型输出
  13. def forward(self, x):
  14. a = self.act(self.hidden(x))
  15. return self.output(a)
  16. X = torch.rand(2, 784)
  17. net = MLP()
  18. print(net)
  19. net(X)

输出:

MLP( (hidden): Linear(in_features=784, out_features=256, bias=True) (act): ReLU() (output): Linear(in_features=256, out_features=10, bias=True) ) tensor([[-0.1798, -0.2253, 0.0206, -0.1067, -0.0889, 0.1818, -0.1474, 0.1845, -0.1870, 0.1970], [-0.1843, -0.1562, -0.0090, 0.0351, -0.1538, 0.0992, -0.0883, 0.0911, -0.2293, 0.2360]], grad_fn=<ThAddmmBackward>)

为什么会调用forward()呢,是因为Module中定义了__call__()函数,该函数调用了forward()函数,当执行net(x)的时候,会自动调用__call__()函数

Pytorch函数调用的问题和源码解读

最近用到 softmax 函数,但是发现 softmax 的写法五花八门,记录如下

  1. # torch._C._VariableFunctions
  2. torch.softmax(x, dim=-1)
  1. # class
  2. softmax = torch.nn.Softmax(dim=-1)
  3. x=softmax(x)
  1. # function
  2. x = torch.nn.functional.softmax(x, dim=-1)

简单测试了一下,用 torch.nn.Softmax 类是最慢的,另外两个差不多

torch.nn.Softmax 源码如下,可以看到这是个类,而他这里的 return F.softmax(input, self.dim, _stacklevel=5) 调用的是 torch.nn.functional.softmax

  1. class Softmax(Module):
  2. r"""Applies the Softmax function to an n-dimensional input Tensor
  3. rescaling them so that the elements of the n-dimensional output Tensor
  4. lie in the range [0,1] and sum to 1.
  5. Softmax is defined as:
  6. .. math::
  7. ext{Softmax}(x_{i}) = frac{exp(x_i)}{sum_j exp(x_j)}
  8. When the input Tensor is a sparse tensor then the unspecifed
  9. values are treated as ``-inf``.
  10. Shape:
  11. - Input: :math:`(*)` where `*` means, any number of additional
  12. dimensions
  13. - Output: :math:`(*)`, same shape as the input
  14. Returns:
  15. a Tensor of the same dimension and shape as the input with
  16. values in the range [0, 1]
  17. Args:
  18. dim (int): A dimension along which Softmax will be computed (so every slice
  19. along dim will sum to 1).
  20. .. note::
  21. This module doesn't work directly with NLLLoss,
  22. which expects the Log to be computed between the Softmax and itself.
  23. Use `LogSoftmax` instead (it's faster and has better numerical properties).
  24. Examples::
  25. >>> m = nn.Softmax(dim=1)
  26. >>> input = torch.randn(2, 3)
  27. >>> output = m(input)
  28. """
  29. __constants__ = ['dim']
  30. dim: Optional[int]
  31. def __init__(self, dim: Optional[int] = None) -> None:
  32. super(Softmax, self).__init__()
  33. self.dim = dim
  34. def __setstate__(self, state):
  35. self.__dict__.update(state)
  36. if not hasattr(self, 'dim'):
  37. self.dim = None
  38. def forward(self, input: Tensor) -> Tensor:
  39. return F.softmax(input, self.dim, _stacklevel=5)
  40. def extra_repr(self) -> str:
  41. return 'dim={dim}'.format(dim=self.dim)

torch.nn.functional.softmax 函数源码如下,可以看到 ret = input.softmax(dim) 实际上调用了 torch._C._VariableFunctions 中的 softmax 函数

  1. def softmax(input: Tensor, dim: Optional[int] = None, _stacklevel: int = 3, dtype: Optional[DType] = None) -> Tensor:
  2. r"""Applies a softmax function.
  3. Softmax is defined as:
  4. :math:` ext{Softmax}(x_{i}) = frac{exp(x_i)}{sum_j exp(x_j)}`
  5. It is applied to all slices along dim, and will re-scale them so that the elements
  6. lie in the range `[0, 1]` and sum to 1.
  7. See :class:`~torch.nn.Softmax` for more details.
  8. Args:
  9. input (Tensor): input
  10. dim (int): A dimension along which softmax will be computed.
  11. dtype (:class:`torch.dtype`, optional): the desired data type of returned tensor.
  12. If specified, the input tensor is casted to :attr:`dtype` before the operation
  13. is performed. This is useful for preventing data type overflows. Default: None.
  14. .. note::
  15. This function doesn't work directly with NLLLoss,
  16. which expects the Log to be computed between the Softmax and itself.
  17. Use log_softmax instead (it's faster and has better numerical properties).
  18. """
  19. if has_torch_function_unary(input):
  20. return handle_torch_function(softmax, (input,), input, dim=dim, _stacklevel=_stacklevel, dtype=dtype)
  21. if dim is None:
  22. dim = _get_softmax_dim("softmax", input.dim(), _stacklevel)
  23. if dtype is None:
  24. ret = input.softmax(dim)
  25. else:
  26. ret = input.softmax(dim, dtype=dtype)
  27. return ret

那么不如直接调用 built-in C 的函数?

但是有个博客 A selective excursion into the internals of PyTorch 里说

Note: That bilinear is exported as torch.bilinear is somewhat accidental. Do use the documented interfaces, here torch.nn.functional.bilinear whenever you can!

意思是说 built-in C 能被 torch.xxx 直接调用是意外的,强烈建议使用 torch.nn.functional.xxx 这样的接口

看到最新的 transformer 官方代码里也用的是 torch.nn.functional.softmax,还是和他们一致更好。

以上就是Pytorch中怎么调用forward()函数的详细内容,更多关于Pytorch中怎么调用forward()函数的资料请关注九品源码其它相关文章!