python中forward的作用_Pytorch学习笔记07----nn.Module类与前向传播函数forward的理解

1.nn.Module类理解

pytorch里面一切自定义操作基本上都是继承nn.Module类来实现的

方法预览:

classModule(object):def __init__(self):def forward(self, *input):defadd_module(self, name, module):def cuda(self, device=None):defcpu(self):def __call__(self, *input, **kwargs):def parameters(self, recurse=True):def named_parameters(self, prefix='', recurse=True):defchildren(self):defnamed_children(self):defmodules(self):def named_modules(self, memo=None, prefix=''):def train(self, mode=True):defeval(self):defzero_grad(self):def __repr__(self):def __dir__(self):'''有一部分没有完全列出来'''

我们在定义自已的网络的时候,需要继承nn.Module类,并重新实现构造函数__init__和forward这两个方法。但有一些注意技巧:

(1)一般把网络中具有可学习参数的层(如全连接层、卷积层等)放在构造函数__init__()中,当然我也可以吧不具有参数的层也放在里面;

(2)一般把不具有可学习参数的层(如ReLU、dropout、BatchNormanation层)可放在构造函数中,也可不放在构造函数中,如果不放在构造函数__init__里面,则在forward方法里面可以使用nn.functional来代替

(3)forward方法是必须要重写的,它是实现模型的功能,实现各个层之间的连接关系的核心。

总结:

torch.nn是专门为神经网络设计的模块化接口。nn构建于autograd之上,可以用来定义和运行神经网络。

nn.Module是nn中十分重要的类,包含网络各层的定义及forward方法。

定义自已的网络:

需要继承nn.Module类,并实现forward方法。

一般把网络中具有可学习参数的层放在构造函数__init__()中,

不具有可学习参数的层(如ReLU)可放在构造函数中,也可不放在构造函数中(而在forward中使用nn.functional来代替)

只要在nn.Module的子类中定义了forward函数,backward函数就会被自动实现(利用Autograd)。

在forward函数中可以使用任何Variable支持的函数,毕竟在整个pytorch构建的图中,是Variable在流动。还可以使用if,for,print,log等python语法.

注:Pytorch基于nn.Module构建的模型中,只支持mini-batch的Variable输入方式

2.forward()函数自动调用的理解和分析

最近在使用pytorch的时候,模型训练时,不需要使用forward,只要在实例化一个对象中传入对应的参数就可以自动调用 forward 函数

自动调用 forward 函数原因分析:

利用Python的语言特性,y = model(x)是调用了对象model的__call__方法,而nn.Module把__call__方法实现为类对象的forward函数,所以任意继承了nn.Module的类对象都可以这样简写来调用forward函数。

案例:

classLeNet(nn.Module):def __init__(self):

super(LeNet, self).__init__()

layer1=nn.Sequential()

layer1.add_module('conv1', nn.Conv(1, 6, 3, padding=1))

layer1.add_moudle('pool1', nn.MaxPool2d(2, 2))

self.layer1=layer1

layer2=nn.Sequential()

layer2.add_module('conv2', nn.Conv(6, 16, 5))

layer2.add_moudle('pool2', nn.MaxPool2d(2, 2))

self.layer2=layer2

layer3=nn.Sequential()

layer3.add_module('fc1', nn.Linear(400, 120))

layer3.add_moudle('fc2', nn.Linear(120, 84))

layer3.add_moudle('fc3', nn.Linear(84, 10))

self.layer3=layer3defforward(self, x):

x=self.layer1(x)

x=self.layer2(x)

x= x.view(x.size(0), -1)

x=self.layer3(x)return x

模型调用:

model =LeNet()

y= model(x)

调用forward方法的具体流程是:

执行y = model(x)时,由于LeNet类继承了Module类,而Module这个基类中定义了__call__方法,所以会执行__call__方法,而__call__方法中调用了forward()方法

只要定义类型的时候,实现__call__函数,这个类型就成为可调用的。 换句话说,我们可以把这个类型的对象当作函数来使用

定义__call__方法的类可以当作函数调用(参见:https://www.cnblogs.com/luckyplj/p/13378008.html)

def __call__(self, *input, **kwargs):for hook inself._forward_pre_hooks.values():

result=hook(self, input)if result is notNone:if notisinstance(result, tuple):

result=(result,)

input=resultiftorch._C._get_tracing_state():

result= self._slow_forward(*input, **kwargs)else:

result= self.forward(*input, **kwargs)for hook inself._forward_hooks.values():

hook_result=hook(self, input, result)if hook_result is notNone:

result=hook_resultif len(self._backward_hooks) >0:

var=resultwhile notisinstance(var, torch.Tensor):ifisinstance(var, dict):

var= next((v for v in var.values() ifisinstance(v, torch.Tensor)))else:

var=var[0]

grad_fn=var.grad_fnif grad_fn is notNone:for hook inself._backward_hooks.values():

wrapper=functools.partial(hook, self)

functools.update_wrapper(wrapper, hook)

grad_fn.register_hook(wrapper)return result

总结:当执行model(x)的时候,底层自动调用forward方法计算结果

参考文献:

https://blog.csdn.net/u011501388/article/details/84062483

  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PyTorch,`nn.Module`是所有神经网络模块的基。它是一个封装了参数、计算方法以及其他网络组件的,可以用来构建自己的神经网络模型。 每个`nn.Module`子的构造函数都应该调用基的构造函数。在`__init__`方法,我们可以定义网络的各个层、参数和其他组件。我们也可以在`forward`方法定义网络的传播过程,即输入数据经过一系列计算后得到输出结果。 `nn.Module`提供了很多实用的方法,例如`parameters`方法可以返回模型所有可训练的参数,`to`方法可以将模型转移到指定的设备上等。 示例代码: ```python import torch import torch.nn as nn class MyModel(nn.Module): def __init__(self): super(MyModel, self).__init__() self.conv1 = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1) self.relu = nn.ReLU(inplace=True) self.pool = nn.MaxPool2d(kernel_size=2, stride=2) self.fc = nn.Linear(16 * 14 * 14, 10) def forward(self, x): x = self.conv1(x) x = self.relu(x) x = self.pool(x) x = x.view(x.size(0), -1) x = self.fc(x) return x model = MyModel() input = torch.randn(1, 3, 28, 28) output = model(input) ``` 这里我们定义了一个简单的卷积神经网络模型,包括了一个卷积层、一个ReLU激活函数、一个最大池化层和一个全连接层。在`forward`方法,我们定义了输入数据的传播过程。我们可以通过调用`parameters`方法打印出模型的所有参数:`print(list(model.parameters()))`。我们还可以使用`to`方法将模型转移到GPU上:`model.to(device)`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值