Pytorch搭建网络

面向对象编程

面向对象编程——类class和对象object

  • class是一种类型(Type),object是类的实例(Instance)
  • 每一个类方法都必须在参数列表开头有一个固定参数self,当调用该方法时python会自动加上self这个参数。因此如果方法没有参数,也必须加上self
  • init方法:__init__方法会在对象被实例化时自动运行(初始化)

继承:

  • 要想使用继承,在定义类时我们需要在类后面跟一个包含基类名称的元组。
  • 如果子类中定义了__init__方法,则基类中的__init__方法将不会被自动调用,需要手动调用,此时需要显示调用self;相反,如果子类中未定义__init__方法,则子类的__init__方法将被自动调用。
class Student(SchoolMember):
    '''代表一位学生。'''
    def __init__(self, name, age, marks):
        SchoolMember.__init__(self, name, age)
  • 在子类中调用父方法,都需要显式调用self
  • super(),先简单认为成继承父类
    super(子类, self).父类方法(参数),相当于父类.方法(self, 参数)

类和对象

在面向对象编程中,理解和认出类和对象十分重要
程序中有很多类的结构,一般都要建立该类的对象。例如在LeNet项目中,LeNet5是一个class,在main.py中有net = LeNet5(),即是创建了LeNet5的对象net。
又如输入时MNIST是类,trainset是对象;Dataloader是类,trainloader是对象等等。
面向对象编程并不是全部由类和对象组建程序的,也有函数,和普通变量

  • 变量:有普通数值型变量和Tensor,普通型例如train_loss,大部分都是Tensor型变量
  • 函数:例如torch.max(output),可以写作output.max(),这是函数的应用

总结 - 再看类和对象

class ConvReLU(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=0):
        super(ConvReLU, self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, padding=padding)

    def forward(self, x):
        x = self.conv(x)
        x = F.relu(x)
        return x
  1. 定义了ConvReLU()类,继承了nn.Module父类。
  2. 定义了__init()__方法,在实例化ConvReLU()类时自动调用__init()__方法。
    2.1 输入参数除了必须有的self,还有要想实例化一个{ConvReLU()}的对象需要的参数
    2.2 因为子类定义了__init()__方法,父类的__init()__方法不再自动执行,需要显式执行,nn.Module父类的__init()__方法不需要输入参数,所以super调用不需要输入参数
    2.3 定义了对象变量self.conv,属性是{nn.Conv2d()}对象,实际上self.conv{nn.Conv2d()}类的实例化,实例化时需要参数。
  3. 定义了forward()方法,对输入进行操作
    3.1 对数据操作需要函数,第一行x = self.conv(x)实际上为x = self.conv.forward(x),调用了nn.Conv2d()forward()函数,由于大家都继承了nn.Module父类,根据nn.Module的使用方法,.forward()不写,直接写object(input)
    3.2 第二行x = F.relu(x)直接调用了函数,对输入进行操作

循环与迭代

batchsize:在深度学习中,一般采用SGD训练,即每次训练在训练集中取batchsize个样本训练;
iteration:中文翻译为迭代,1个iteration等于使用batchsize个样本训练一次;
一个迭代 = 一个正向通过+一个反向通过
epoch:迭代次数,1个epoch等于使用训练集中的全部样本训练一次;
一个epoch = 所有训练样本的一个正向传递和一个反向传递

举个例子,训练集有1000个样本,batchsize=10,那么:
训练完整个样本集需要:
100次iteration,1次epoch。

Moudle class

搭建网络的整个过程都需要继承Moduleclass

Base class for all neural network modules.

Your models should also subclass this class.

Module类中最重要的方法是forward

Defines the computation performed at every call.
Should be overridden by all subclasses.
.. note::
Although the recipe for forward pass needs to be defined within
this function, one should call the :class:Module instance afterwards
instead of this since the former takes care of running the
registered hooks while the latter silently ignores them.

forward实现了每次调用网络的操作,每个网络子类都必须重写forward方法。
注意:调用网络操作时应当调用Module()类而非Module.forward()方法。
即:output = net(img)
而非output = net.forward(img)

torch.nn.XX VS torch.nn.functional.XX

既有torch.nn.Conv2d,又有torch.nn.Functional.Conv2d,区别在于:
nn.Module实现的layer是由class Layer(nn.Module)定义的特殊类,会自动提取可学习参数nn.Parameter;nn.functional中的函数更像是纯函数,由def function(input)定义

  • nn.Conv2d是一个类,把卷积当作一个层时使用
  • F.conv2d()是一个函数,把卷积当作一个运算函数时使用
  • nn.Conv2d的forward()函数实现是用F.conv2d()实现的。
class Conv2d(_ConvNd):
    def forward(self, input):
        return F.conv2d(input, self.weight, self.bias, self.stride,
                        self.padding, self.dilation, self.groups)

在调用Conv2d()操作时执行forward方法,可以看到真正进行操作的还是F.conv2d()函数

参考1
参考2
参考3

pytorch的图像预处理包

pytorch中transform函数

import 和from... import

  • 可以import的单位是packagemodule

.py文件是一个Module

可以from...import...的单位是package,moduleclass/function

  • 导入文件将导入所有的class,用某个class时需要package.class
    导入类可以直接使用该类

例如:torchvisonpakage有3个package和一个module

import torchvision

导入class

在导入MNIST数据集时需要用class MNIST,这个class包含于torchvison.datasets.mnist文件中,因此正确引用的方式有:
from torchvision.datasets.mnist import MNIST,使用时直接用MNIST
import torchvision.datasets.mnist as mnist,使用时用mnist.MNIST

导入module

from torchvision import datasets
import torchvion.datasets as datasets

init.py

此外,通过package的__init__.py文件,可以将package中的class提到package级别
参考
例如class Dataloadertorchvision.datasets.folder.py中,但是因为在torchvision.datasetspackage中的__init__.py中有
from .folder import ImageFolder, DatasetFolder
Datafolder被提到了package级别,可以在package级别引用
from torchvision.datasets import ImageFolder

# in your __init__.py
from .folder import ImageFolder, DatasetFolder

# now import File from package
from torchvision.datasets import ImageFolder

真正要使用的时候肯定是使用一个class,没法使用整个package
可以直接引入class,或先引入package再package.class

net中input的维度

应有四个维度:batch_size, channels, size_len, size_width,如果读取单张图片没有batch_size维度,需要手动添加
image = image.view(1, image.size(0), image.size(1), image.size(2))

trick - 建一个class ConvReLU()

把Conv2d和ReLU()合起来做

class ConvReLu(nn.Module):
    def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0):
        super(ConvReLu, self).__init__()
        self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, padding=padding)

    def forward(self, x):
        x = self.conv(x)
        x = F.relu(x)
        return x

使用方法:

class Layer1and2(nn.Module):
    def __init__(self):
        super(Layer1and2, self).__init__()
        self.op = nn.Sequential(
            ConvReLu(3, 64, 7, 2, 2),
            nn.MaxPool2d(3, 2),
            nn.BatchNorm2d(64),
            ConvReLu(64, 64, 1, 1),
            ConvReLu(64, 192, 3, 1, 1),
            nn.BatchNorm2d(192),
            nn.MaxPool2d(3, 2)
        )

    def forward(self, x):
        x = self.op(x)
        return x

把ConvReLU当作一个整体来用

好处

  1. 省事,提高代码结构化
  2. 在调试的时候可以看到卷积之后的效果,只有forward()中的操作可以调试跟踪,在__init()__nn.Sequential中的操作是无法跟踪的。

trick - forward函数中尽量别把许多步骤合成一个Sequential

否则没办法调试跟踪每一步之后的结果

nn.Sequential()最后一个元素别加逗号

否则最后一个元素将被忽略,为什么?

Python魔术方法getitemsetitemdelitemlen

CSDN

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容