PyTorch: clamp函数与梯度的关系

本文主要以下探究这一点:梯度反向传播过程中,测试强行修改后的预测结果是否还会传递loss?

clamp应用场景:在深度学习计算损失函数的过程中,会有这样一个问题,如果Label是1.0,而预测结果是0.0,则BCE损失中理论上计算出的结果是无穷大的(当然pytorch并不会报错,而是将损失上限设在了100.0),在实际开发过程中,我们一般会使用torch.clamp等函数将预测tensor不符合取值范围的值全部置为最小或最大值。

那对于这些被替换后的元素,他们会在反向传播过程中对网络产生梯度吗?第一想法是没有,因为这些替换后的新值的来源是一个赋值操作,而非通过网络计算出来的,但为了更好的理解,我们来做一个测试。

from torch.nn import functional as F
import torch.nn as nn
import torch
#初始化一个最简单的网络
fc = nn.Linear(in_features=1, out_features=1, bias=True)
fc.weight.data = torch.tensor([[0.01]])
fc.bias.data   = torch.tensor([[0.01]])
input_t = torch.tensor([[1.0]], dtype=torch.float32)
pred    = fc(input_t)
label   = torch.tensor([[1.0]])

这里网络的预测结果为0.02,将其强行截断到0.1,损失的计算仍然是正常的,但是反向传播后,网络的训练参数是没有梯度的,即可以认为这个预测的样本对网络是没有更新作用的,是一个无意义的预测样本

pred = torch.clamp(pred, min=0.1, max=0.9)
loss = F.binary_cross_entropy(pred, label)
print(loss) # tensor(2.3026, grad_fn=<BinaryCrossEntropyBackward>)
loss.backward()
print(fc.weight.grad, fc.bias.grad) #tensor([[0.]]) tensor([[0.]])

 正常的预测结果产生梯度,符合预期。

loss = F.binary_cross_entropy(pred, label)
print(loss) 	 #tensor(3.9120, grad_fn=<BinaryCrossEntropyBackward>)
loss.backward()
print(fc.weight.grad, fc.bias.grad) #tensor([[-50.]]) tensor([[-50.]])

更一般的,假设有n个预测结果,其中有k个值由于torch.clamp等操作被强行修改了值,还剩n - k个预测结果是真实来源于网络,则在梯度反向传播的时候只有这n - k个样本能够成功回传梯度给网络,即便计算的loss是这k个样本产生的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值