- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章聊聊PyTorch中eval和no_grad的关系由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
model.eval()是用来告知model内的各个layer采取eval模式工作。这个操作主要是应对诸如dropout和batchnorm这些在训练模式下需要采取不同操作的特殊layer。训练和测试的时候都可以开启.
torch.no_grad()则是告知自动求导引擎不要进行求导操作。这个操作的意义在于加速计算、节约内存。但是由于没有gradient,也就没有办法进行backward。所以只能在测试的时候开启.
所以在evaluate的时候,需要同时使用两者.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
model
=
...
dataset
=
...
loss_fun
=
...
# training
lr
=
0.001
model.train()
for
x,y
in
dataset:
model.zero_grad()
p
=
model(x)
l
=
loss_fun(p, y)
l.backward()
for
p
in
model.parameters():
p.data
-
=
lr
*
p.grad
# evaluating
sum_loss
=
0.0
model.
eval
()
with torch.no_grad():
for
x,y
in
dataset:
p
=
model(x)
l
=
loss_fun(p, y)
sum_loss
+
=
l
print
(
'total loss:'
, sum_loss)
|
另外no_grad还可以作为函数是修饰符来用,从而简化代码.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
def
train(model, dataset, loss_fun, lr
=
0.001
):
model.train()
for
x,y
in
dataset:
model.zero_grad()
p
=
model(x)
l
=
loss_fun(p, y)
l.backward()
for
p
in
model.parameters():
p.data
-
=
lr
*
p.grad
@torch
.no_grad()
def
test(model, dataset, loss_fun):
sum_loss
=
0.0
model.
eval
()
for
x,y
in
dataset:
p
=
model(x)
l
=
loss_fun(p, y)
sum_loss
+
=
l
return
sum_loss
# main block:
model
=
...
dataset
=
...
loss_fun
=
...
# training
train()
# test
sum_loss
=
test()
print
(
'total loss:'
, sum_loss)
|
补充:pytorch中model.train、model.eval以及torch.no_grad的用法 。
启用 BatchNormalization 和 Dropout 。
model.train() 让model变成训练模式,此时 dropout和batch normalization的操作在训练起到防止网络过拟合的问题 。
不启用 BatchNormalization 和 Dropout 。
model.eval(),pytorch会自动把BN和DropOut固定住,而用训练好的值。不然的话,一旦test的batch_size过小,很容易就会被BN层导致所生成图片颜色失真极大 。
训练完train样本后,生成的模型model要用来测试样本。在model(test)之前,需要加上model.eval(),否则的话,有输入数据,即使不训练,它也会改变权值。这是model中含有batch normalization层所带来的的性质.
对于在训练和测试时为什么要这样做,可以从下面两段话理解:
在训练的时候, 会计算一个batch内的mean 和var, 但是因为是小batch小batch的训练的,所以会采用加权或者动量的形式来将每个batch的 mean和var来累加起来,也就是说再算当前的batch的时候,其实当前的权重只是占了0.1, 之前所有训练过的占了0.9的权重,这样做的好处是不至于因为某一个batch太过奇葩而导致的训练不稳定.
好,现在假设训练完成了, 那么在整个训练集上面也得到了一个最终的”mean 和var”, BN层里面的参数也学习完了(如果指定学习的话),而现在需要测试了,测试的时候往往会一张图一张图的去测,这时候没有batch而言了,对单独一个数据做 mean和var是没有意义的, 那么怎么办,实际上在测试的时候BN里面用的mean和var就是训练结束后的mean_final 和 val_final. 也可说是在测试的时候BN就是一个变换。所以在用pytorch的时候要注意这一点,在训练之前要有model.train() 来告诉网络现在开启了训练模式,在eval的时候要用”model.eval()”, 用来告诉网络现在要进入测试模式了.因为这两种模式下BN的作用是不同的.
这条语句的作用是:在测试时不进行梯度的计算,这样可以在测试时有效减小显存的占用,以免发生显存溢出(OOM).
这条语句通常加在网络预测的那条代码上.
在PyTorch中进行validation时,会使用model.eval()切换到测试模式,在该模式下, 。
主要用于通知dropout层和batchnorm层在train和val模式间切换 。
在train模式下,dropout网络层会按照设定的参数p设置保留激活单元的概率(保留概率=p); batchnorm层会继续计算数据的mean和var等参数并更新.
在val模式下,dropout层会让所有的激活单元都通过,而batchnorm层会停止计算和更新mean和var,直接使用在训练阶段已经学出的mean和var值.
该模式不会影响各层的gradient计算行为,即gradient计算和存储与training模式一样,只是不进行反传(backprobagation) 。
而with torch.zero_grad()则主要是用于停止autograd模块的工作,以起到加速和节省显存的作用,具体行为就是停止gradient计算,从而节省了GPU算力和显存,但是并不会影响dropout和batchnorm层的行为.
如果不在意显存大小和计算时间的话,仅仅使用model.eval()已足够得到正确的validation的结果;而with torch.zero_grad()则是更进一步加速和节省gpu空间(因为不用计算和存储gradient),从而可以更快计算,也可以跑更大的batch来测试.
以上为个人经验,希望能给大家一个参考,也希望大家多多支持我。如有错误或未考虑完全的地方,望不吝赐教.
原文链接:https://blog.csdn.net/yanxiangtianji/article/details/113798888 。
最后此篇关于聊聊PyTorch中eval和no_grad的关系的文章就讲到这里了,如果你想了解更多关于聊聊PyTorch中eval和no_grad的关系的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
有多久,没有发过短信了? 1、背景简介 在常规的分布式架构下,「消息中心」的服务里通常会集成「短信」的渠道,作为信息触达的重要手段,其他常用的手段还包括:「某微」、「某钉」、
区块链、低代码、元宇宙、AI智能; 01 【 先来说说背景 】 这个概念由来已久,但是在国内兴起,是最近几年; 低代码即「 Low-Code
目录 1、背景简介 2、订单业务 1、订单体系 2、流程管理 2
1. 相同点 用Python语言编写的源代码文件,其文件后缀是 “.py” 或 “.ipynb”。用Python语言编写的源代码文件,其文件后缀是 “.py” 或 “.ipynb”。 2. 区别
功能简介 闭锁是一种同步工具类,可以延迟线程的进度直到其到达终止状态【CPJ 3.4.2】。闭锁的作用相当于一扇门∶ 在闭锁到达结束状态之前,这扇门一直是关闭的,并且没有任何线程能通过,当到达
高阶函数,英文叫 Higher Order function。一个函数可以接收另外一个函数作为参数,这种函数就叫做高阶函数。 示例: function add(x, 
引文 最近公司项目中使用了 Nuxt 框架,进行首屏的服务端渲染,加快了内容的到达时间 (time-to-content),于是笔者开始了对 Nuxt 的学习和使用。以下是从源码角度对 Nux
什么是游标? 游标(cursor)是一个存储在MySQL服务器上的数据库查询, 它不是一条SELECT语句,而是被该语句检索出来的结果集。在存储了游 标之后,应用程序可以根据需要滚动或浏
流水线工作模型在工业领域内十分常见,它将工作流程分为多个环节,每个环节根据工作强度安排合适的人员数量。良好的流水线设计尽量让各环节的流通率平衡,最大化提高产能效率。 Go 是一门实用性语言,流
1. Spring JDBC Spring JDBC的配置 2. Spring JdbcTemplate的常用方法 execute()
1. 前言 大家好,我是安果! 日常编写的 Python 自动化程序,如果在本地运行稳定后,就可以考虑将它部署到服务器,结合定时任务完全解放双手 但是,由于自动化程序与平台兼
前言 有时候我们会有在需要在网页中写代码或者改代码配置的需求,这个时候就需要用到代码编辑器,常规的代码编辑器有 CodeMirror 和 Monaco Editor, CodeMirror 使用的
前言:模块机制是 Node.js 中非常重要的组成,模块机制使得我们可以以模块化的方式写代码,而不是全部代码都写到一个文件里。我们平时使用的比较多的通过 require 加载模块,但是我们可能不
随着互联网的发展,越来越多的公司摒弃了Hibernate,而选择拥抱了MyBatis。而且,很多大厂在面试的时候喜欢问MyBatis底层的原理和源码实现。 总之,MyBatis几乎成为了Jav
@requestmapping和@getmapping @postmapping的区别 最近学习看一些代码,发现对于发送请求这件事,有的地方用@requestmapping,有的地方用@postm
@RequestParam 和 @PathVariable 注解是用于从request中接收请求的,两个都可以接收参数,关键点不同的是@RequestParam 是从request里面拿取值,而 @
PHP8的Alpha版本,过几天就要发布了,其中包含了不少的新特性,当然我自己认为最重要的还是JIT,这个我从2013年开始参与,中间挫折无数,失败无数后,终于要发布的东东。 不过,今天呢,我不打
引言 我们想要网格的服务发现、路由、熔断降级、负载均衡,这些流量治理都在数据面Envoy中执行才行。Envoy也提供的Filter机制来做这些功能,通常有以下方式: 通过C
我是一名优秀的程序员,十分优秀!