PyTorch之前向传播函数forward用法解读

 更新时间:2023年09月08日 09:58:21   作者:鹊踏枝-码农  
这篇文章主要介绍了PyTorch之前向传播函数forward用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

之前向传播函数forward用法

神经网络的典型处理如下所示:

  • 1.定义可学习参数的网络结构(堆叠各层和层的设计);
  • 2.数据集输入;
  • 3.对输入进行处理(由定义的网络层进行处理),主要体现在网络的前向传播;
  • 4.计算loss ,由Loss层计算;
  • 5.反向传播求梯度;
  • 6.根据梯度改变参数值,最简单的实现方式(SGD)为:
weight = weight - learning_rate * gradient

利用PyTorch定义深度网络层(Op)示例

class FeatureL2Norm(torch.nn.Module):
    def __init__(self):
        super(FeatureL2Norm, self).__init__()
    def forward(self, feature):
        epsilon = 1e-6
#        print(feature.size())
#        print(torch.pow(torch.sum(torch.pow(feature,2),1)+epsilon,0.5).size())
        norm = torch.pow(torch.sum(torch.pow(feature,2),1)+epsilon,0.5).unsqueeze(1).expand_as(feature)
        return torch.div(feature,norm)
class FeatureRegression(nn.Module):
    def __init__(self, output_dim=6, use_cuda=True):
        super(FeatureRegression, self).__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(225, 128, kernel_size=7, padding=0),
            nn.BatchNorm2d(128),
            nn.ReLU(inplace=True),
            nn.Conv2d(128, 64, kernel_size=5, padding=0),
            nn.BatchNorm2d(64),
            nn.ReLU(inplace=True),
        )
        self.linear = nn.Linear(64 * 5 * 5, output_dim)
        if use_cuda:
            self.conv.cuda()
            self.linear.cuda()
    def forward(self, x):
        x = self.conv(x)
        x = x.view(x.size(0), -1)
        x = self.linear(x)
        return x

由上例代码可以看到,不论是在定义网络结构还是定义网络层的操作(Op),均需要定义forward函数,下面看一下PyTorch官网对PyTorch的forward方法的描述:

那么调用forward方法的具体流程是什么样的呢?

具体流程是这样的

以一个Module为例:

  • 1.调用module的call方法
  • 2.module的call里面调用module的forward方法
  • 3.forward里面如果碰到Module的子类,回到第1步,如果碰到的是Function的子类,继续往下
  • 4.调用Function的call方法
  • 5.Function的call方法调用了Function的forward方法。
  • 6.Function的forward返回值
  • 7.module的forward返回值
  • 8.在module的call进行forward_hook操作,然后返回值。

上述中“调用module的call方法”是指nn.Module 的__call__方法。

定义__call__方法的类可以当作函数调用,具体参考Python的面向对象编程。

也就是说,当把定义的网络模型model当作函数调用的时候就自动调用定义的网络模型的forward方法。

nn.Module 的__call__方法部分源码

如下所示:

def __call__(self, *input, **kwargs):
   result = self.forward(*input, **kwargs)
   for hook in self._forward_hooks.values():
       #将注册的hook拿出来用
       hook_result = hook(self, input, result)
   ...
   return result

可以看到,当执行model(x)的时候,底层自动调用forward方法计算结果。

具体示例如下:

class LeNet(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 = layer3
    def forward(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方法。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • matplotlib绘制多个子图(subplot)的方法

    matplotlib绘制多个子图(subplot)的方法

    这篇文章主要介绍了matplotlib绘制多个子图(subplot)的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • python实现简单的socket server实例

    python实现简单的socket server实例

    这篇文章主要介绍了python实现简单的socket server的方法,实例分析了Python中socket的操作技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • python数据预处理之将类别数据转换为数值的方法

    python数据预处理之将类别数据转换为数值的方法

    下面小编就为大家带来一篇python数据预处理之将类别数据转换为数值的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • Python开发编码规范

    Python开发编码规范

    Python开发编码规范...
    2006-09-09
  • Python Pandas如何获取和修改任意位置的值(at,iat,loc,iloc)

    Python Pandas如何获取和修改任意位置的值(at,iat,loc,iloc)

    在我们对数据进行选择之后,需要对特定的数据进行设置更改,设置,下面这篇文章主要给大家介绍了关于Python Pandas如何获取和修改任意位置的值(at,iat,loc,iloc)的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-01-01
  • 在Python中定义和使用抽象类的方法

    在Python中定义和使用抽象类的方法

    提起Java的抽象类大家都比较熟悉,Python中我们可以使用abc模块来构建抽象类,这里就为大家讲解在Python中定义和使用抽象类的方法
    2016-06-06
  • Python人脸检测实战之疲劳检测

    Python人脸检测实战之疲劳检测

    本文主要介绍了实现疲劳检测:如果眼睛已经闭上了一段时间,我们会认为他们开始打瞌睡并发出警报来唤醒他们并引起他们的注意。感兴趣的朋友可以了解一下
    2021-12-12
  • 搭建python django虚拟环境完整步骤详解

    搭建python django虚拟环境完整步骤详解

    这篇文章主要介绍了搭建python django虚拟环境完整步骤详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • 对python中的乘法dot和对应分量相乘multiply详解

    对python中的乘法dot和对应分量相乘multiply详解

    今天小编就为大家分享一篇对python中的乘法dot和对应分量相乘multiply详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-11-11
  • 浅谈在django中使用redirect重定向数据传输的问题

    浅谈在django中使用redirect重定向数据传输的问题

    这篇文章主要介绍了浅谈在django中使用redirect重定向数据传输的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03

最新评论