首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将PyTorch sigmoid函数变为更陡峭的函数

如何将PyTorch sigmoid函数变为更陡峭的函数
EN

Stack Overflow用户
提问于 2021-04-22 05:22:54
回答 2查看 412关注 0票数 2

当我使用torch.sigmoid时,我的模型可以工作。我试图通过创建一个新的sigmoid函数来使sigmoid变得更陡峭:

代码语言:javascript
运行
复制
def sigmoid(x):
    return 1 / (1 + torch.exp(-1e5*x))

但是由于某种原因,渐变并没有流过它(我得到的是NaN)。我的函数是否有问题,或者有没有办法简单地将PyTorch实现更改为更陡峭(像我的函数一样)?

代码示例:

代码语言:javascript
运行
复制
def sigmoid(x):
  return 1 / (1 + torch.exp(-1e5*x))

a = torch.tensor(0.0, requires_grad=True)
b = torch.tensor(0.58, requires_grad=True)

c = sigmoid(a-b)
c.backward()
a.grad
>>> tensor(nan)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-22 06:22:00

问题似乎是,当sigmoid实现的输入为负时,torch.exp的参数会变得非常大,从而导致溢出。使用torch.autograd.set_detect_anomaly(True)作为建议的here,您可以看到以下错误:

代码语言:javascript
运行
复制
RuntimeError: Function 'ExpBackward' returned nan values in its 0th output.

如果您确实需要使用您定义的函数,一种可能的解决方法是对参数进行条件检查(但我不确定它是否稳定,因此我无法评论它的有用性):

代码语言:javascript
运行
复制
def sigmoid(x):
    if x >= 0:
        return 1./(1+torch.exp(-1e5*x))
    else:
        return torch.exp(1e5*x)/(1+torch.exp(1e5*x)) 

在这里,else分支中的表达式通过将分子和分母乘以torch.exp(1e5*x)等同于原始函数。这可确保torch.exp的参数始终为负或接近于零。

正如trialNerror所指出的,指数值是如此之高,以至于除了非常接近于零的值之外,其他任何地方的渐变都将计算为零,因为实际的斜率将非常小,并且无法通过数据类型来解析。因此,如果你计划在网络中使用它,你可能会发现很难学习任何东西,因为梯度几乎总是为零。根据您的用例,选择一个较小的指数可能会更好。

票数 2
EN

Stack Overflow用户

发布于 2021-04-22 06:08:25

你在你的指数中加上1e5的扩张值。1e5的指数是如此之高,以至于在这里没有希望得到有意义的结果。您可能会得到一个NaN,因为您正试图通过一个计算图进行反向传播,该图在某一时刻的计算结果为inf (甚至更高!)

总之,要使函数的斜率更陡峭,记住df(a.x)/dx = a.df(x)/dx,所以你需要将它的参数乘以一个大于1的值(并且不是负的,你将改变你的导数的符号),但不要那么大!尝试使用10个可能,它还取决于您将在函数中输入的输入的数量级

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67203664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档