PyTorch中eval和no_grad有何区别,怎么使用
Admin 2022-06-15 群英技术资讯 670 次浏览
这篇文章给大家分享的是PyTorch中eval和no_grad有何区别,怎么使用。小编觉得挺实用的,因此分享给大家做个参考,文中的介绍得很详细,而要易于理解和学习,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。model.eval()是用来告知model内的各个layer采取eval模式工作。这个操作主要是应对诸如dropout和batchnorm这些在训练模式下需要采取不同操作的特殊layer。训练和测试的时候都可以开启。
torch.no_grad()则是告知自动求导引擎不要进行求导操作。这个操作的意义在于加速计算、节约内存。但是由于没有gradient,也就没有办法进行backward。所以只能在测试的时候开启。
所以在evaluate的时候,需要同时使用两者。
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还可以作为函数是修饰符来用,从而简化代码。
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来测试。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
大家好,本篇文章主要讲的是Python处理excel与txt文件详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
所谓魔法函数(Magic Methods),是Python的⼀种⾼级语法,允许你在类中⾃定义函数(函数名格式⼀般为__xx__),并绑定到类的特殊⽅法中。⽐如在类A中⾃定义__str__()函数,则在调⽤str(A())时,会⾃动调⽤__str__()函数,并返回相应的结果
这篇文章主要介绍了Python批量裁剪图片的程序代码,是批量裁剪某一文件夹下的所有图片,并指定裁剪宽高,本文给大家分享实现思路,需要的朋友可以参考下
首先说,Python中一切皆对象,老生常谈。还有,Python提供了许多特殊方法、元类等等这样的“元编程”机制。像给对象动态添加属性方法之类的,在Python中根本谈不上是“元编程”,但在某些静态语言中却是需要一定技巧的东西。我们来谈些Python程序员也容易被搞糊涂的东西。
本篇文章给大家带来了关于python的相关知识,torch.Tensor 是一种包含单一数据类型元素的多维矩阵,类似于 numpy 的 array,下面一起来看一下Pytorch中的tensor数据结构,希望对大家有帮助。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008