- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章pytorch自定义不可导激活函数的操作由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
今天自定义不可导函数的时候遇到了一个大坑.
首先我需要自定义一个函数:sign_f 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import
torch
from
torch.autograd
import
Function
import
torch.nn as nn
class
sign_f(Function):
@staticmethod
def
forward(ctx, inputs):
output
=
inputs.new(inputs.size())
output[inputs >
=
0.
]
=
1
output[inputs <
0.
]
=
-
1
ctx.save_for_backward(inputs)
return
output
@staticmethod
def
backward(ctx, grad_output):
input_,
=
ctx.saved_tensors
grad_output[input_>
1.
]
=
0
grad_output[input_<
-
1.
]
=
0
return
grad_output
|
然后我需要把它封装为一个module 类型,就像 nn.Conv2d 模块 封装 f.conv2d 一样,于是 。
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
|
import
torch
from
torch.autograd
import
Function
import
torch.nn as nn
class
sign_(nn.Module):
# 我需要的module
def
__init__(
self
,
*
kargs,
*
*
kwargs):
super
(sign_,
self
).__init__(
*
kargs,
*
*
kwargs)
def
forward(
self
, inputs):
# 使用自定义函数
outs
=
sign_f(inputs)
return
outs
class
sign_f(Function):
@staticmethod
def
forward(ctx, inputs):
output
=
inputs.new(inputs.size())
output[inputs >
=
0.
]
=
1
output[inputs <
0.
]
=
-
1
ctx.save_for_backward(inputs)
return
output
@staticmethod
def
backward(ctx, grad_output):
input_,
=
ctx.saved_tensors
grad_output[input_>
1.
]
=
0
grad_output[input_<
-
1.
]
=
0
return
grad_output
|
结果报错 。
TypeError: backward() missing 2 required positional arguments: 'ctx' and 'grad_output' 。
我试了半天,发现自定义函数后面要加 apply ,详细见下面 。
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
|
import
torch
from
torch.autograd
import
Function
import
torch.nn as nn
class
sign_(nn.Module):
def
__init__(
self
,
*
kargs,
*
*
kwargs):
super
(sign_,
self
).__init__(
*
kargs,
*
*
kwargs)
self
.r
=
sign_f.
apply
### <-----注意此处
def
forward(
self
, inputs):
outs
=
self
.r(inputs)
return
outs
class
sign_f(Function):
@staticmethod
def
forward(ctx, inputs):
output
=
inputs.new(inputs.size())
output[inputs >
=
0.
]
=
1
output[inputs <
0.
]
=
-
1
ctx.save_for_backward(inputs)
return
output
@staticmethod
def
backward(ctx, grad_output):
input_,
=
ctx.saved_tensors
grad_output[input_>
1.
]
=
0
grad_output[input_<
-
1.
]
=
0
return
grad_output
|
问题解决了! 。
有的时候我们需要给损失函数设一个超参数但是又不想设固定阈值想和网络一起自动学习,例如给Sigmoid一个参数alpha进行调节 。
函数如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import
torch.nn as nn
import
torch
class
LearnableSigmoid(nn.Module):
def
__init__(
self
, ):
super
(LearnableSigmoid,
self
).__init__()
self
.weight
=
torch.nn.Parameter(torch.FloatTensor(
1
), requires_grad
=
True
)
self
.reset_parameters()
def
reset_parameters(
self
):
self
.weight.data.fill_(
1.0
)
def
forward(
self
,
input
):
return
1
/
(
1
+
torch.exp(
-
self
.weight
*
input
))
|
验证和Sigmoid的一致性 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
class
LearnableSigmoid(nn.Module):
def
__init__(
self
, ):
super
(LearnableSigmoid,
self
).__init__()
self
.weight
=
torch.nn.Parameter(torch.FloatTensor(
1
), requires_grad
=
True
)
self
.reset_parameters()
def
reset_parameters(
self
):
self
.weight.data.fill_(
1.0
)
def
forward(
self
,
input
):
return
1
/
(
1
+
torch.exp(
-
self
.weight
*
input
))
Sigmoid
=
nn.Sigmoid()
LearnSigmoid
=
LearnableSigmoid()
input
=
torch.tensor([[
0.5289
,
0.1338
,
0.3513
],
[
0.4379
,
0.1828
,
0.4629
],
[
0.4302
,
0.1358
,
0.4180
]])
print
(Sigmoid(
input
))
print
(LearnSigmoid(
input
))
|
输出结果 。
tensor([[0.6292, 0.5334, 0.5869], [0.6078, 0.5456, 0.6137], [0.6059, 0.5339, 0.6030]]) tensor([[0.6292, 0.5334, 0.5869], [0.6078, 0.5456, 0.6137], [0.6059, 0.5339, 0.6030]], grad_fn=<MulBackward0>) 。
验证权重是不是会更新 。
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
31
32
33
34
35
36
37
38
39
|
import
torch.nn as nn
import
torch
import
torch.optim as optim
class
LearnableSigmoid(nn.Module):
def
__init__(
self
, ):
super
(LearnableSigmoid,
self
).__init__()
self
.weight
=
torch.nn.Parameter(torch.FloatTensor(
1
), requires_grad
=
True
)
self
.reset_parameters()
def
reset_parameters(
self
):
self
.weight.data.fill_(
1.0
)
def
forward(
self
,
input
):
return
1
/
(
1
+
torch.exp(
-
self
.weight
*
input
))
class
Net(nn.Module):
def
__init__(
self
):
super
(Net,
self
).__init__()
self
.LSigmoid
=
LearnableSigmoid()
def
forward(
self
, x):
x
=
self
.LSigmoid(x)
return
x
net
=
Net()
print
(
list
(net.parameters()))
optimizer
=
optim.SGD(net.parameters(), lr
=
0.01
)
learning_rate
=
0.001
input_data
=
torch.randn(
10
,
2
)
target
=
torch.FloatTensor(
10
,
2
).random_(
8
)
criterion
=
torch.nn.MSELoss(
reduce
=
True
, size_average
=
True
)
for
i
in
range
(
2
):
optimizer.zero_grad()
output
=
net(input_data)
loss
=
criterion(output, target)
loss.backward()
optimizer.step()
print
(
list
(net.parameters()))
|
输出结果 。
tensor([1.], requires_grad=True)] [Parameter containing: tensor([0.9979], requires_grad=True)] [Parameter containing: tensor([0.9958], requires_grad=True)] 。
会更新~ 。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持我.
原文链接:https://blog.csdn.net/qq_43110298/article/details/115032262 。
最后此篇关于pytorch自定义不可导激活函数的操作的文章就讲到这里了,如果你想了解更多关于pytorch自定义不可导激活函数的操作的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我目前正在使用发现的重力脚本 here为了在我的网页上创建重力效果,我正在本地开发 atm。 我的问题是,重力效果的激活似乎是在鼠标移动时进行的,而我需要它在文档准备好时才触发。 google.cod
我正在尝试关注 Railsbridge Intallfest 并尝试将我的第一个 Rails 应用程序部署到 heroku。我不断收到以下错误消息: Gem::LoadError: Specified
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
Home-tab 是默认选中的,但是它的颜色是灰色的:( Home Bla Contact
我没有得到它的工作,我不知道为什么......遗憾的是其他问题 + 答案没有帮助。 测试设备: iPhone 6 iPad 2 相关代码: override func viewWillTransiti
我试图加载一个 View ,就像用户已经按下 UISearchBar 一样。我希望 SearchController 加载顶部的 UISearchBar 以及取消按钮。 我已经试过了: func ac
试图在 if whiteDotDist < centerRadius - whiteDotRadius 时获取代码执行它下面的所有代码都是事件的,并且当它下面的代码被执行时它再次变为非事件状态直到if
我正在使用 anaconda python。所以每次,在我的 mac 终端中,我输入终端命令: source /Users/mylaptop/anaconda/bin/activate /Users/
在我的 Angular 项目中,我有这种代码: this.swUpdate.available.subscribe(() => { ... }); 它工作正常,但给了我关于 activated 被
我想弄清楚 Julia 包是如何工作的,因为我喜欢容器化环境。我真的很挣扎。 在 python 中,我会做类似 conda create env --name ds 的事情创建环境然后安装容器化包我会
我的宏中有一些代码如下 ChDir File_pth Workbooks.Open filename:= File_pth & "\" & open_tkt Workbooks.Open filena
长话短说,我有两张纸,一张是“原始数据”,另一张是“结果”。我试图让结果表从“原始数据”表的每第七行中提取文本或数字,因此“结果”中的 A1 将是原始数据中的 A1,“结果”中的 A2 将是“原始数据
我不知道如何做到这一点,或者我是否可以做到这一点。我有一个 jQuery UI Accordion,多个部分,每个部分包含多个 anchor 标记,每个 anchor 标记都有一个唯一的字符串 id。
我不敢相信我还没有找到任何关于此的文档,但我想知道如何命令键盘激活并接收来自它的输入。我可以找到在编辑文本字段时操作弹出键盘的所有示例。谢谢 最佳答案 您还可以使用 UIKeyInput 协议(pro
我正在尝试为我的 Electron 应用程序生成NSIS安装程序的日志。为此,我创建了一个文件'logging.nsh'来定义LogSet和LogText宏。 以下是logging.nsh文件的代码:
几周前,我开始使用 typescript 和 knockoutJS,我有一个具体的问题,但我有解决方案,它太丑了,我无法忍受,但无法从中得到任何更好的东西,有太多代码需要粘贴,但我会尽力描述我的问题:
当我尝试激活我的虚拟环境时收到此错误即源 ~/edu-venv/bin/activate -bash: /home/vagrant/edu-venv/bin/activate: No such fil
要创建触发器,似乎必须发布它才能生效。但是发布需要对“协作”分支进行 PR,这意味着我们甚至在测试触发器是否实际工作之前就必须创建一个 PR,并且还必须创建多个后续 PR,直到我们获得正确的触发器。
我是最近的 IntelliJ Idea 用户,我不知道如何启用 Hibernate。当我右键单击我的项目时,Hibernate 不会出现在“添加框架支持”菜单中(实际上我唯一可以选择的技术是 Groo
要创建触发器,似乎必须发布它才能生效。但是发布需要对“协作”分支进行 PR,这意味着我们甚至在测试触发器是否实际工作之前就必须创建一个 PR,并且还必须创建多个后续 PR,直到我们获得正确的触发器。
我是一名优秀的程序员,十分优秀!