- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章pytorch中的自定义反向传播,求导实例由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
pytorch中自定义backward()函数。在图像处理过程中,我们有时候会使用自己定义的算法处理图像,这些算法多是基于numpy或者scipy等包.
那么如何将自定义算法的梯度加入到pytorch的计算图中,能使用Loss.backward()操作自动求导并优化呢。下面的代码展示了这个功能` 。
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
import
torch
import
numpy as np
from
PIL
import
Image
from
torch.autograd
import
gradcheck
class
Bicubic(torch.autograd.Function):
def
basis_function(
self
, x, a
=
-
1
):
x_abs
=
np.
abs
(x)
if
x_abs <
1
and
x_abs >
=
0
:
y
=
(a
+
2
)
*
np.power(x_abs,
3
)
-
(a
+
3
)
*
np.power(x_abs,
2
)
+
1
elif
x_abs >
1
and
x_abs <
2
:
y
=
a
*
np.power(x_abs,
3
)
-
5
*
a
*
np.power(x_abs,
2
)
+
8
*
a
*
x_abs
-
4
*
a
else
:
y
=
0
return
y
def
bicubic_interpolate(
self
,data_in, scale
=
1
/
4
, mode
=
'edge'
):
# data_in = data_in.detach().numpy()
self
.grad
=
np.zeros(data_in.shape,dtype
=
np.float32)
obj_shape
=
(
int
(data_in.shape[
0
]
*
scale),
int
(data_in.shape[
1
]
*
scale), data_in.shape[
2
])
data_tmp
=
data_in.copy()
data_obj
=
np.zeros(shape
=
obj_shape, dtype
=
np.float32)
data_in
=
np.pad(data_in, pad_width
=
((
2
,
2
), (
2
,
2
), (
0
,
0
)), mode
=
mode)
print
(data_tmp.shape)
for
axis0
in
range
(obj_shape[
0
]):
f_0
=
float
(axis0)
/
scale
-
np.floor(axis0
/
scale)
int_0
=
int
(axis0
/
scale)
+
2
axis0_weight
=
np.array(
[[
self
.basis_function(
1
+
f_0),
self
.basis_function(f_0),
self
.basis_function(
1
-
f_0),
self
.basis_function(
2
-
f_0)]])
for
axis1
in
range
(obj_shape[
1
]):
f_1
=
float
(axis1)
/
scale
-
np.floor(axis1
/
scale)
int_1
=
int
(axis1
/
scale)
+
2
axis1_weight
=
np.array(
[[
self
.basis_function(
1
+
f_1),
self
.basis_function(f_1),
self
.basis_function(
1
-
f_1),
self
.basis_function(
2
-
f_1)]])
nbr_pixel
=
np.zeros(shape
=
(obj_shape[
2
],
4
,
4
), dtype
=
np.float32)
grad_point
=
np.matmul(np.transpose(axis0_weight, (
1
,
0
)), axis1_weight)
for
i
in
range
(
4
):
for
j
in
range
(
4
):
nbr_pixel[:, i, j]
=
data_in[int_0
+
i
-
1
, int_1
+
j
-
1
, :]
for
ii
in
range
(data_in.shape[
2
]):
self
.grad[int_0
-
2
+
i
-
1
, int_1
-
2
+
j
-
1
, ii]
=
grad_point[i,j]
tmp
=
np.matmul(axis0_weight, nbr_pixel)
data_obj[axis0, axis1, :]
=
np.matmul(tmp, np.transpose(axis1_weight, (
1
,
0
)))[:,
0
,
0
]
# img = np.transpose(img[0, :, :, :], [1, 2, 0])
return
data_obj
def
forward(
self
,
input
):
print
(
type
(
input
))
input_
=
input
.detach().numpy()
output
=
self
.bicubic_interpolate(input_)
# return input.new(output)
return
torch.Tensor(output)
def
backward(
self
,grad_output):
print
(
self
.grad.shape,grad_output.shape)
grad_output.detach().numpy()
grad_output_tmp
=
np.zeros(
self
.grad.shape,dtype
=
np.float32)
for
i
in
range
(
self
.grad.shape[
0
]):
for
j
in
range
(
self
.grad.shape[
1
]):
grad_output_tmp[i,j,:]
=
grad_output[
int
(i
/
4
),
int
(j
/
4
),:]
grad_input
=
grad_output_tmp
*
self
.grad
print
(
type
(grad_input))
# return grad_output.new(grad_input)
return
torch.Tensor(grad_input)
def
bicubic(
input
):
return
Bicubic()(
input
)
def
main():
hr
=
Image.
open
(
'./baboon/baboon_hr.png'
).convert(
'L'
)
hr
=
torch.Tensor(np.expand_dims(np.array(hr), axis
=
2
))
hr.requires_grad
=
True
lr
=
bicubic(hr)
print
(lr.is_leaf)
loss
=
torch.mean(lr)
loss.backward()
if
__name__
=
=
'__main__'
:
main()
|
要想实现自动求导,必须同时实现forward(),backward()两个函数.
1、从代码中可以看出来,forward()函数是针对numpy数据操作,返回值再重新指定为torch.Tensor类型。因此就有这个问题出现了:forward输入input被转换为numpy类型,输出转换为tensor类型,那么输出output的grad_fn参数是如何指定的呢。调试发现,当main()中hr的requires_grad被指定为True,即hr被指定为需要求导的叶子节点。只要Bicubic类继承自torch.autograd.Function,那么output也就是代码中的lr的grad_fn就会被指定为<main.Bicubic object at 0x000001DD5A280D68>,即Bicubic这个类.
2、backward()为求导的函数,gard_output是链式求导法则的上一级的梯度,grad_input即为我们想要得到的梯度。只需要在输入指定grad_output,在调用loss.backward()过程中的某一步会执行到Bicubic的backwward()函数 。
以上这篇pytorch中的自定义反向传播,求导实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我.
原文链接:https://blog.csdn.net/xuxiaoyuxuxiaoyu/article/details/86737492 。
最后此篇关于pytorch中的自定义反向传播,求导实例的文章就讲到这里了,如果你想了解更多关于pytorch中的自定义反向传播,求导实例的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 已关闭 3 年前。 此帖子于去年编辑
据我所知,在使用 GPU 训练和验证模型时,GPU 内存主要用于加载数据,向前和向后。据我所知,我认为 GPU 内存使用应该相同 1) 训练前,2) 训练后,3) 验证前,4) 验证后。但在我的例子中
我正在尝试在 PyTorch 中将两个复数矩阵相乘,看起来 the torch.matmul functions is not added yet to PyTorch library for com
我正在尝试定义二分类问题的损失函数。但是,目标标签不是硬标签0,1,而是0~1之间的一个 float 。 Pytorch 中的 torch.nn.CrossEntropy 不支持软标签,所以我想自己写
我正在尝试让 PyTorch 与 DataLoader 一起工作,据说这是处理小批量的最简单方法,在某些情况下这是获得最佳性能所必需的。 DataLoader 需要一个数据集作为输入。 大多数关于 D
Pytorch Dataloader 的迭代顺序是否保证相同(在温和条件下)? 例如: dataloader = DataLoader(my_dataset, batch_size=4,
PyTorch 的负对数似然损失,nn.NLLLoss定义为: 因此,如果以单批处理的标准重量计算损失,则损失的公式始终为: -1 * (prediction of model for correct
在PyTorch中,new_ones()与ones()有什么区别。例如, x2.new_ones(3,2, dtype=torch.double) 与 torch.ones(3,2, dtype=to
假设我有一个矩阵 src带形状(5, 3)和一个 bool 矩阵 adj带形状(5, 5)如下, src = tensor([[ 0, 1, 2], [ 3, 4,
我想知道如果不在第 4 行中使用“for”循环,下面的代码是否有更有效的替代方案? import torch n, d = 37700, 7842 k = 4 sample = torch.cat([
我有三个简单的问题。 如果我的自定义损失函数不可微会发生什么? pytorch 会通过错误还是做其他事情? 如果我在我的自定义函数中声明了一个损失变量来表示模型的最终损失,我应该放 requires_
我想知道 PyTorch Parameter 和 Tensor 的区别? 现有answer适用于使用变量的旧 PyTorch? 最佳答案 这就是 Parameter 的全部想法。类(附加)在单个图像中
给定以下张量(这是网络的结果 [注意 grad_fn]): tensor([121., 241., 125., 1., 108., 238., 125., 121., 13., 117., 12
什么是__constants__在 pytorch class Linear(Module):定义于 https://pytorch.org/docs/stable/_modules/torch/nn
我在哪里可以找到pytorch函数conv2d的源代码? 它应该在 torch.nn.functional 中,但我只找到了 _add_docstr 行, 如果我搜索conv2d。我在这里看了: ht
如 documentation 中所述在 PyTorch 中,Conv2d 层使用默认膨胀为 1。这是否意味着如果我想创建一个简单的 conv2d 层,我必须编写 nn.conv2d(in_chann
我阅读了 Pytorch 的源代码,发现它没有实现 convolution_backward 很奇怪。函数,唯一的 convolution_backward_overrideable 函数是直接引发错
我对编码真的很陌生,现在我正在尝试将我的标签变成一种热门编码。我已经完成将 np.array 传输到张量,如下所示 tensor([4., 4., 4., 4., 4., 4., 4., 4., 4.
我正在尝试实现 text classification model使用CNN。据我所知,对于文本数据,我们应该使用一维卷积。我在 pytorch 中看到了一个使用 Conv2d 的示例,但我想知道如何
我有一个多标签分类问题,我正试图用 Pytorch 中的 CNN 解决这个问题。我有 80,000 个训练示例和 7900 个类;每个示例可以同时属于多个类,每个示例的平均类数为 130。 问题是我的
我是一名优秀的程序员,十分优秀!