mysql连接测试不成功的原因有哪些
290
2022-09-21
RuntimeError: element 0 of tensors does not require grad and does not have a grad_
文章目录
1. 问题描述2. 解决方案
2.1 方案12.2 方案2
3. 参考文献
1. 问题描述
今天在跑代码的过程中,因为要训练一个模型然后在测试阶段使用PGD来生成相应的adv_image来测试这个模型,结果运行到测试阶段出现下面的问题。
报错如下: RuntimeError: element 0 of tensors does not require grad and does not have a grad_
我的代码如下:
def validate_roubst(val_loader, model, criterion, epoch, args, log=None, tf_writer=None, flag='roubst_val'): batch_time = AverageMeter('Time', ':6.3f') losses = AverageMeter('Loss', ':.4e') top1 = AverageMeter('Acc@1', ':6.2f') top5 = AverageMeter('Acc@5', ':6.2f') # switch to evaluate mode model.eval() all_preds = [] all_targets = [] with torch.no_grad(): end = time.time() for i, (input, target) in enumerate(val_loader): if args.gpu is not None: # input = input.cuda(args.gpu, non_blocking=True) print('............') input = input.cuda(args.gpu, non_blocking=True) target = target.cuda(args.gpu, non_blocking=True) attack_method = PGD(model, args.device) adv_example = attack_method.generate(input, target, epsilon = 8/255, num_steps = 20, step_size = 0.01, clip_max = 1.0, clip_min = 0.0, print_process = False, bound = 'linf') # compute output output = model(adv_example) # input loss = criterion(output, target) # measure accuracy and record loss acc1, acc5 = accuracy(output, target, topk=(1, 5)) losses.update(loss.item(), input.size(0)) top1.update(acc1[0], input.size(0)) top5.update(acc5[0], input.size(0)) # measure elapsed time batch_time.update(time.time() - end) end = time.time() _, pred = torch.max(output, 1) all_preds.extend(pred.cpu().numpy()) all_targets.extend(target.cpu().numpy()) if i % args.print_freq == 0: output = ('Test: [{0}/{1}]\t' 'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t' 'Loss {loss.val:.4f} ({loss.avg:.4f})\t' 'Prec@1 {top1.val:.3f} ({top1.avg:.3f})\t' 'Prec@5 {top5.val:.3f} ({top5.avg:.3f})'.format( i, len(val_loader), batch_time=batch_time, loss=losses, top1=top1, top5=top5)) print(output) cf = confusion_matrix(all_targets, all_preds).astype(float) cls_cnt = cf.sum(axis=1) cls_hit = np.diag(cf) cls_acc = cls_hit / cls_cnt output = ('{flag} Results: Prec@1 {top1.avg:.3f} Prec@5 {top5.avg:.3f} Loss {loss.avg:.5f}' .format(flag=flag, top1=top1, top5=top5, loss=losses)) out_cls_acc = '%s Class Accuracy: %s'%(flag,(np.array2string(cls_acc, separator=',', formatter={'float_kind':lambda x: "%.3f" % x}))) print(output) print(out_cls_acc) if log is not None: log.write(output + '\n') log.write(out_cls_acc + '\n') log.flush() tf_writer.add_scalar('loss/test_'+ flag, losses.avg, epoch) tf_writer.add_scalar('acc/test_' + flag + '_top1', top1.avg, epoch) tf_writer.add_scalar('acc/test_' + flag + '_top5', top5.avg, epoch) tf_writer.add_scalars('acc/test_' + flag + '_cls_acc', {str(i):x for i, x in enumerate(cls_acc)}, epoch) return
2. 解决方案
出了问题当然要找到解决方案:
2.1 方案1
大多数人是说要加这一句:
loss.requires_grad_(True) #加入此句就行了
具体做法就是:
loss = criterion(output, target) loss.requires_grad_(True) # 加入此句在这个位置 … loss.backward()
但是经过本人尝试,还是没有什么用,因为我在train阶段不会 出现错误,只有在test阶段就报错。
2.2 方案2
回归本质,还是从报错的角度看,错误提示大致意思就是:元素不需要求梯度 然后我仔细瞅了瞅我那段代码,发现了一个可疑之处:with torch.no_grad() 最后仔细查看了这个东西的一些使用规则(参考文献1):
with torch.no_grad()则主要是用于停止autograd模块的工作,以起到加速和节省显存的作用,具体行为就是停止gradient计算,从而节省了GPU算力和显存,但是并不会影响dropout和batchnorm层的行为。
看到我上面加粗的字体了吧,原来使用with torch.no_grad()就不会自动求梯度了,因为我们使用PGD生成adv_image需要求梯度,所以加上with torch.no_grad()就导致了我们无法求梯度,最终出现了下面的错误。
故解决方案为:
将 with torch.no_grad() 去掉
3. 参考文献
1. Pytorch 中 model.eval() 和 with torch.no_grad() 的区别
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~