[pytorch系列-38]:工具集-torchvision预定义模型的两种模式model.train和model.eval的表面和本质区别(代码片段)

文火冰糖的硅基工坊 文火冰糖的硅基工坊     2023-01-28     606

关键词:

作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客

本文网址:https://blog.csdn.net/HiWangWenBing/article/details/121176467


目录

第1章 为什么需要讨论model.train()和model.eval的区别。

1.1 利用torchvision.model预定义的模型

1.2 预定义模型的定义:定义模型非常方便!

1.3 预定义模型的两种模式

第2章 两种模式的区别

2.1 代码执行结果的区别

2.2 train模式与eval模式的本质区别

第3章 函数原型说明

3.1 model.train(mode=True)

3.2 model.eval (mode=True)

第4章 源码解析

4.1 model.train(mode=True)

4.2 model.eval (mode=True)



第1章 为什么需要讨论model.train()和model.eval的区别。

1.1 利用torchvision.model预定义的模型

在前面的文章中,我们都在探讨如何手工搭建卷积神经网络,训练网络模型。

很显然,对于一些知名的模型,手工搭建的效率较低,且容易出错。

因此,利用pytorch提供的搭建好的知名模型,是一个不错的选择。

[Pytorch系列-37]:工具集 - torchvision库详解(数据集、数据预处理、模型)_文火冰糖(王文兵)的博客-CSDN博客作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客本文网址:目录第1章Pytorch常见的工具集简介第2章Pytorch的torchvision工具集简介第3章torchvision.datasets 简介3.1 简介3.2 支持的数据集列表第4章torchvision.models简介4.1 简介4.2 支持的模型4.3构造具有随机权重的模型4.4 使用预预训练好的模型第5章 torchvision.tr...https://blog.csdn.net/HiWangWenBing/article/details/121149809

1.2 预定义模型的定义:定义模型非常方便!

(1)案例1

# 2-3 使用torchvision.models定义神经网络
net_a = models.alexnet(num_classes = 10)
print(net_a)
AlexNet(
  (features): Sequential(
    (0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
    (1): ReLU(inplace=True)
    (2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
    (3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (4): ReLU(inplace=True)
    (5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
    (6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (7): ReLU(inplace=True)
    (8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (9): ReLU(inplace=True)
    (10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (11): ReLU(inplace=True)
    (12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (avgpool): AdaptiveAvgPool2d(output_size=(6, 6))
  (classifier): Sequential(
    (0): Dropout(p=0.5, inplace=False)
    (1): Linear(in_features=9216, out_features=4096, bias=True)
    (2): ReLU(inplace=True)
    (3): Dropout(p=0.5, inplace=False)
    (4): Linear(in_features=4096, out_features=4096, bias=True)
    (5): ReLU(inplace=True)
    (6): Linear(in_features=4096, out_features=10, bias=True)
  )
)

(2)案例2:

net_b = models.vgg16(num_classes = 10)
print(net_b)
VGG(
  (features): Sequential(
    (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (1): ReLU(inplace=True)
    (2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (3): ReLU(inplace=True)
    (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (6): ReLU(inplace=True)
    (7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (8): ReLU(inplace=True)
    (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (11): ReLU(inplace=True)
    (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (13): ReLU(inplace=True)
    (14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (15): ReLU(inplace=True)
    (16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (18): ReLU(inplace=True)
    (19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (20): ReLU(inplace=True)
    (21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (22): ReLU(inplace=True)
    (23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (25): ReLU(inplace=True)
    (26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (27): ReLU(inplace=True)
    (28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (29): ReLU(inplace=True)
    (30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (avgpool): AdaptiveAvgPool2d(output_size=(7, 7))
  (classifier): Sequential(
    (0): Linear(in_features=25088, out_features=4096, bias=True)
    (1): ReLU(inplace=True)
    (2): Dropout(p=0.5, inplace=False)
    (3): Linear(in_features=4096, out_features=4096, bias=True)
    (4): ReLU(inplace=True)
    (5): Dropout(p=0.5, inplace=False)
    (6): Linear(in_features=4096, out_features=10, bias=True)
  )
)

1.3 预定义模型的两种模式

预定义模型支持两种工作模式

  • model.train:适用于训练模式
  • model.eval:适用于预测模式

第2章 两种模式的区别

2.1 代码执行结果的区别

(1)train模式

# 2-4 定义网络预测输出
# 测试网络是否能够工作
print("定义测试数据")
input = torch.randn(1, 3, 224, 224)
print(input.shape)

print("")
net_a.train()    #设置在训练模式,不设置,模式为训练模式

print("net_a的输出方法1:")
out = net_a(input)
print(out.shape)
print(out)

print("")
print("net_a的输出方法2:")
out = net_a.forward(input)
print(out)

定义测试数据
torch.Size([1, 3, 224, 224])

net_a的输出方法1:
torch.Size([1, 10])
tensor([[ 1.3295e-02,  3.6363e-05,  9.0679e-04,  2.2399e-03,  2.4310e-03,
         -6.0430e-03, -9.2381e-03, -8.3501e-03, -7.8011e-03, -7.4917e-03]],
       grad_fn=<AddmmBackward>)

net_a的输出方法2:
tensor([[ 0.0195, -0.0109, -0.0017, -0.0027,  0.0131, -0.0014, -0.0212, -0.0030,
         -0.0114, -0.0041]], grad_fn=<AddmmBackward>)

备注:

连续两次的预测结果是不完全一样的。

(2)评估模式

# 2-4 定义网络预测输出
# 测试网络是否能够工作
print("定义测试数据")
input = torch.randn(1, 3, 224, 224)
print(input.shape)

print("")
net_a.eval()    #设置在训练模式,不设置,模式为训练模式

print("net_a的输出方法1:")
out = net_a(input)
print(out.shape)
print(out)

print("")
print("net_a的输出方法2:")
out = net_a.forward(input)
print(out)
定义测试数据
torch.Size([1, 3, 224, 224])

net_a的输出方法1:
torch.Size([1, 10])
tensor([[ 0.0106, -0.0096,  0.0060,  0.0017,  0.0017, -0.0004, -0.0031, -0.0126,
         -0.0078, -0.0079]], grad_fn=<AddmmBackward>)

net_a的输出方法2:
tensor([[ 0.0106, -0.0096,  0.0060,  0.0017,  0.0017, -0.0004, -0.0031, -0.0126,
         -0.0078, -0.0079]], grad_fn=<AddmmBackward>)

备注:

连续两次的预测结果是完全一样的!

(3)train模式预eval模式的区别

  • model.train:连续两次的预测结果是不完全一样的。
  • model.eval:连续两次的预测结果是完全一样的!

为什么呢?

2.2 train模式与eval模式的本质区别

(1)根本原因

对于一些含有BatchNormDropout等层的模型,model.train()和model.eval()的区别主要在于Batch Normalization和Dropout两层的处理上不同。

(2)train模式

如果模型中有BN层(Batch Normalization)和 Dropout,需要在训练时添加model.train(),启用 Batch Normalization Dropout的特殊处理的功能。

model.train()是保证BN层能够用到每一批数据的均值和方差。

对于Dropout,model.train()是随机取一部分网络连接来训练更新参数,导致在该模式下,每次预测,使用的网络参数连接不尽相同。这就导致,每次预测输出的结果不完全一样。

备注:

至于Dropout和Batch Normalization,请查看相关的文档,文本不再叙述。

(3)eval模式

如果模型中有BN层(Batch Normalization)和Dropout,在测试时添加model.eval()。关闭 Batch Normalization 和 Dropout的功能。

model.eval()是保证BN层能够用全部训练数据的均值和方差,即测试过程中要保证BN层的均值和方差不变。

对于Dropout,model.eval()是利用到了所有网络连接,即不进行随机舍弃神经元。
 

第3章 函数原型说明

torch.nn — PyTorch 1.10.0 documentationhttps://pytorch.org/docs/stable/nn.html?highlight=module%20eval#torch.nn.Module.eval

3.1 model.train(mode=True)

3.2 model.eval (mode=True)

第4章 源码解析

4.1 model.train(mode=True)

    def train(self, mode=True):
        r"""Sets the module in training mode.

        This has any effect only on certain modules. See documentations of
        particular modules for details of their behaviors in training/evaluation
        mode, if they are affected, e.g. :class:`Dropout`, :class:`BatchNorm`,
        etc.

        Returns:
            Module: self
        """
        self.training = mode
        for module in self.children():
            module.train(mode)
        return self

4.2 model.eval (mode=True)

def eval(self):
    return self.train(False)

作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客

本文网址:https://blog.csdn.net/HiWangWenBing/article/details/121176467

[pytorch系列-42]:工具集-torchvision常见预训练模型的下载地址(代码片段)

作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客本文网址:https://blog.csdn.net/HiWangWenBing/article/details/121184391目录步骤1:torchvision概述步骤2:如何获取框架提供的预... 查看详情

[pytorch系列-43]:工具集-torchvision预训练模型参数的导入(以resnet为例)(代码片段)

作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客本文网址:https://blog.csdn.net/HiWangWenBing/article/details/121184678目录第1章 torchvision与预训练模型的自动下载第2章预训练模型的... 查看详情

[pytorch系列-47]:工具集-torchvision.transforms.normalize和tosensor的深入详解(代码片段)

作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客本文网址:https://blog.csdn.net/HiWangWenBing/article/details/121300054目录第1章关于标准化的概念说明1.1提前声明:网络中对Normali... 查看详情

pytorch使用gpu

Pytorch使用GPUpytorch默认是不使用gpu的,即使我们已经安装好了支持的cuda版本和cudnn,所以要使用gpu需要在程序里面设置一下。步骤importtorchuse_gpu=torch.cuda.is_available()定义一个检查GPU是否可用的全局变量加载模型、并设置... 查看详情

[pytorch系列-39]:工具集-torchvision搭建alexnet/vgg/resnet等网络并训练cfar10分类数据(代码片段)

作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客本文网址:https://blog.csdn.net/HiWangWenBing/article/details/121132377目录第1章torchvision概述1.1为什么需要通过torchvision1.2 torchvision详... 查看详情

[pytorch系列-23]:pytorch基础-其他

。。。。。。。 查看详情

[pytorch系列-70]:开发环境-可视化工具visdom安装与使用方法(代码片段)

...2启动后台visdomserver2.3启动前台IE显示第3章使用:通过pytorch代码可视化信息3.1导入库3.2实例化一个Visdom窗口3.3通过wind对象可视化图像第1章概述1.1概述在深度学习领域,模型训练是一个必须的过程,因此常常需要实时... 查看详情

yoloair,一个基于pytorch的yolo工具箱...

...内容不迷路机器之心编辑部YOLOAir算法代码库是一个基于PyTorch的YOLO系列目标检测开源工具箱。使用统一模型代码框架、统一应用方式、统一调参,该库包含大量的改进模块,可使用不同网络模块来快速构建不同网络的检... 查看详情

yoloair,一个基于pytorch的yolo工具箱...

...内容不迷路机器之心编辑部YOLOAir算法代码库是一个基于PyTorch的YOLO系列目标检测开源工具箱。使用统一模型代码框架、统一应用方式、统一调参,该库包含大量的改进模块,可使用不同网络模块来快速构建不同网络的检... 查看详情

深度学习-pytorch框架实战系列

深度学习-PyTorch框架实战系列PyTorch是一个开源的Python机器学习库,基于Torch,用于自然语言处理等应用程序。2017年1月,由Facebook人工智能研究院(FAIR)基于Torch推出了PyTorch。它是一个基于Python的可续计算包,提供两个高级功能... 查看详情

pytorch系列教程-使用字符级rnn生成姓名(代码片段)

前言本系列教程为pytorch官网文档翻译。本文对应官网地址:https://pytorch.org/tutorials/intermediate/char_rnn_generation_tutorial.html系列教程总目录传送门:我是一个传送门本系列教程对应的jupyternotebook可以在我的Github仓库下载:下载地址:htt... 查看详情

pytorch深度学习60分钟快速入门part0:系列介绍

 说明:本系列教程翻译自PyTorch官方教程《DeepLearningwithPyTorch:A60MinuteBlitz》 教程目标在高层次上理解PyTorch的Tensor库和神经网络训练一个小型的神经网络来分类图像前提条件假设读者熟悉基础的NumPy库确保已经安装了torch和t... 查看详情

深度学习100例|第41天:语音识别-pytorch实现(代码片段)

文章目录一、导入数据1.下载数据2.数据展示二、数据准备工作1.格式化数据2.标签的编码与还原3.构建数据加载器三、构建模型四、训练模型1.训练过程中的loss五、测试模型🍖我的环境:语言环境:Python3.8编译器:... 查看详情

[pytorch系列-18]:pytorch基础-张量的范数(代码片段)

作者主页(文火冰糖的硅基工坊):https://blog.csdn.net/HiWangWenBing本文网址:https://blog.csdn.net/HiWangWenBing/article/details/119707901目录第1章什么是范数1.1常见的范数与定义1.2代码演示的前置条件1.3范数的函数说明:torch.norm(input,p 查看详情

pytorch学习系列——环境搭建(代码片段)

文章目录1.安装英伟达驱动2.安装Anaconda环境3.安装pytorch、CUDA和cuDNN环境(1)配置国内镜像加速(2)安装4.查看安装环境的版本4.1查看Anaconda版本4.2查看Nvidia驱动版本4.3查看pytorch版本4.4查看CUDA版本4.5查看cuDNN版本由... 查看详情

pytorch学习系列——加载数据2(代码片段)

...数据MyDataset,那么怎么在训练时提供batch数据呢?PyTorch提供了生成batch数据的类。PyTorch用类torch.utils.data.DataLoader加载数据,并对数据进行采样,生成batch迭代器。classtorch.utils.data.DataLoader(da 查看详情

Highcharts 仅在链接系列之间共享工具提示

】Highcharts仅在链接系列之间共享工具提示【英文标题】:Highchartssharingtooltipbetweenlinkedseriesonly【发布时间】:2018-04-2513:42:38【问题描述】:我正在制作一个置信区间的图表,如下所示:https://www.highcharts.com/demo/arearange-line效果很... 查看详情

三维深度学习pytorch-pointnet系列之win10下环境安装与demo运行(代码片段)

【三维深度学习】Pytorch-PointNet系列之win10下环境安装与demo运行提示:最近开始在三维深度学习方面进行研究,从PointNet开始入手,对这个系列的网络进入深入学习,记录相关知识点,分享学习中遇到的问题已经解决的方法。文章目录【... 查看详情