Pytorch面向对象编程OOP

由于非计科出身,对各种计算机类的术语一脸懵逼,每次问计科的朋友相关术语,感觉就在折磨别人。最近学Pytorch,对面向对象编程中存在的各种术语名词更是懵逼。因此通过学Pytorch搭建CNN来学习面向对象编程到底是怎么回事。

首先给出一位大佬的回答:如何给女朋友解释什么是面向对象编程?
大佬的回答可以说是非常浅显易懂了,个人感觉要是配上一些具体的代码讲解,就更完美了。因此本人就国外一位小哥对用Pytorch搭建CNN讲的OOP而进行简单翻译叙述。这里也给出相关链接,供读者查阅:Build PyTorch CNN - Object Oriented Neural Networks

一、什么是面向对象编程?

当我们编写程序或构建软件时,有两个关键组件:代码和数据。通过面向对象编程,我们可以围绕对象来确定程序设计和结构的方向。

何为对象?
在代码中使用类定义为对象。类定义了对象的规范,它指定了类的每个对象应该具有的数据和代码。

当我们创建一个类的对象时,我们称这个对象为类的一个实例,一个给定类的所有实例都有两个核心组件:

  • 方法(code)
  • 属性(data)

1、方法表示代码,而属性表示数据,因此方法和属性是由类定义的。
2、在一个给定的程序中,有许多对象。给定类的一个实例可以同时存在,并且所有实例都具有相同的可用属性和相同的可用方法。从这个角度来看,它们是一致的。
3、同一个类的对象之间的区别是每个属性的对象中包含的值。每个对象都有自己的属性值,这些值决定了对象的内部状态,每个对象的代码和数据都被封装在对象中。

让我们构建一个简单的lizard类来演示类如何封装数据和代码:

class Lizard: #类申明
    def __init__(self, name): #类构造(code)
        self.name = name #attribute (data)
    
    def set_name(self, name): #method declaration (code)
        self.name = name #method implementation (code)

第一行声明类并指定类名Lizard,第二行定义了一个特殊的方法,称为类构造函数,在创建类的新实例时调用类构造函数。作为参数,我们有self和name。
self参数使我们能够创建存储或封装在对象中的属性值。当我们调用这个构造函数或任何其他方法时,我们不传递self参数,Python自动为我们做这些。任何其他参数的参数值都是由调用者任意传递的,这些传入方法的传递值可以在计算中使用,也可以在以后使用self保存和访问。

在我们完成构造函数之后,我们可以创建任意数量的专用方法,比如这里的这个,它允许调用者更改存储在self中的name值。我们在这里所要做的就是调用该方法并为名称传递一个新值。如下:

> lizard = Lizard('deep')
> print(lizard.name)
deep

> lizard.set_name('lizard')
> print(lizard.name)
lizard

我们通过指定类名并传递构造函数参数来创建类的对象实例。构造函数将接收这些参数,构造函数代码将运行保存传递的名称。然后,我们可以访问名称并打印它,还可以调用set_name()方法来更改名称。程序中可以存在多个这样的Lizard实例,每个实例都包含自己的数据。从面向对象的角度来看,这个设置的重要部分是将属性和方法组织起来并包含在对象中。

二、Pytorch面向对象编程

在深度学习各种框架里,Pytorch也是一种OOP框架,自从用了Pytorch,看懂论文的网络结构代码轻轻松松。不多说,下面看面向对象编程是怎样适合于PyTorch。

正如我们所知,深度神经网络是使用多层构建的,这就是网络深入的原因。神经网络中的每一层都有两个主要部分:

  • 函数的变换(code)
  • 一组权重(data)

与生活中的许多事情一样,这一事实使得层成为使用OOP表示为对象的最佳候选对象。实际上,PyTorch就是这种情况。在神经网络包nn中,有一个类叫做Module,它是所有神经网络模块的基类,包括层。这意味着PyTorch中的所有层都扩展了nn.Module类并继承了PyTorch在nn.Module中的所有内置函数。在OOP中,这个概念被称为继承。
甚至连神经网络也会扩展nn.Module类。这是讲得通的,因为神经网络本身可以被认为是一个大的层(如果需要,让它随着时间的推移而下沉)。
PyTorch中的神经网络和层扩展了nn.Module类,这意味着我们在PyTorch中构建新层或神经网络时必须扩展nn.Module类。

PyTorch nn.Modules Have A forward() Method
1、当我们把一个张量作为输入传递给网络时,张量通过每一层变换向前流动,直到张量到达输出层。这种张量通过网络向前流动的过程被称为向前传递。每一层都有自己的变换(code)及张量通过每一层向前传递,所有单独层转发的组成定义了网络的整体转发转换。
2、整个转换的目标是将输入转换或映射到正确的预测输出类,在训练过程中,层权重(数据)以这样的方式更新,从而使映射调整,使输出更接近正确的预测。
3、这就意味着,每个nn.Module类有一个forward()方法,因此在构建层和网络时,必须提供forward()方法的实现。前向方法是实际的变换。

PyTorch’s nn.functional Package

1、当我们使用nn.Module子类的forward()方法时,我们通常会使用来自nn.functional包。这个包为我们提供了许多可以用于构建层的神经网络操作。事实上,许多nn.Module层类使用nn.functional函数执行其操作。
2、nn.functional包包含用于实现forward()函数的nn.Module子类的方法,nn.Conv2d卷积层类就是其中一种。

Building A Neural Network In PyTorch

我们现在有足够的信息来提供PyTorch中构建神经网络的概要,步骤如下:

  • 创建一个扩展nn.Module基类的神经网络类。
  • 在类构造函数中,使用torch.nn中预构建的层将网络层定义为类属性。
  • 使用网络的层属性以及来自nn.functional API的操作定义网络的前向传播。
class Network(nn.Module):
    def __init__(self):
        super().__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):
        # implement the forward pass
        return t
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值