Motivation

构建模型有时需要使用自定义的函数,为了不影响模型的反向传播,需要实现自动梯度计算(即把自定义函数嵌入计算图)。


实现

要点:

  1. 将函数定义为类,需继承自torch.autograd.Function
  2. 需实现两个静态方法:forward()和backward(),分别对应前向传播和反向传播
  3. 函数使用前需调用apply方法从而嵌入计算图,实现自动求导

用一个例子来说明:
假设我们要实现一个多项式拟合模型: y = a + b P 2 ( c x + d ) y = a + bP_2(cx + d) y=a+bP2​(cx+d) ,用来拟合正切函数,其中 P 2 P_2 P2​为一个二次函数: P 2 ( x ) = x 2 + 2 x P_2(x) = x^2 + 2x P2​(x)=x2+2x,需要我们自定义实现

import torch
import mathdtype = torch.float
#构建训练集,使用随机数据
x = torch.linspace(-math.pi, math.pi, 2000, dtype = dtype)
y = torch.tan(x)#将权重值a,b,c,d随机初始化,设置requires_grad=True以实现自动求偏导
a = torch.randn((), dtype = dtype, requires_grad = True)
b = torch.randn((), dtype = dtype, requires_grad = True)
c = torch.randn((), dtype = dtype, requires_grad = True)
d = torch.randn((), dtype = dtype, requires_grad = True)#实现P2
class P2(torch.autograd.Function): #定义forward方法,以在前向传播中实现函数的功能@staticmethoddef forward(ctx, input):#保存input值,反向传播计算梯度时会用到ctx.save_for_backward(input)return input**2 + 2*input#定义backward方法@staticmethoddef backward(ctx,grad_output): #输入参数grad_output是目标函数对输出结果的梯度#这里需要计算函数输出值相对于输入input的梯度u,#返回grad_output与u的乘积以实现链式法则input, = ctx.saved_tensorsreturn grad_output * (2 * inptu + 2)learning_rate = 1e-6
#全量学习
for t in range(2000):#对刚刚定义的函数fun调用apply方法,使其嵌入计算图p2 = P2.apply#前向传播y_pred = a + b * p2(c * x + d)#定义损失函数loss = (y_pred - y).pow(2).sum()if t%100 == 99:print(t, loss.item())#反向传播计算梯度loss.backward()#更新参数#这里每个参数的梯度自定在反向传播时自动计算好并保存在param.grad中了with torch.no_grad():a -= learning_rate * a.gradb -= learning_rate * b.gradc -= learning_rate * c.gradd -= learning_rate * d.grad#将梯度重置为0a.grad = b.grad = c.grad = d.grad = None
print(f'Result: y = {a.item()} + {b.item()} * P2({c.item} x + {d.item()}')

运行结果:

(由于参数选择很随意,且权重是随机初始化的,所以拟合效果不好)


参考资料

链接:Learning pytorch with examples

pytorch自定义函数实现自动梯度相关推荐

  1. pytorch自定义forward和backward函数

    pytorch会自动求导,但是当遇到无法自动求导的时候,需要自己认为定义求导过程,这个时候就涉及到要定义自己的forward和backward函数. 举例如下: 看到这里,大家应该会有很多疑问,比如: ...

  2. PyTorch定义新的自动求导(Autograd) 函数

    PyTorch定义新的自动求导(Autograd) 函数 pytorch官网提供了定义新的求导函数的方法(链接放在文章末尾了),官网举的例子,可能我比较笨,愣是反应了好一会儿才理解.这篇博客主要讲 P ...

  3. 2.0 自动梯度 - PyTorch学习笔记

    自动梯度 (AUTOGRAD: AUTOMATIC DIFFERENTIATION) 导入 torch 包 import torch 新建一个需要的2x2张量,并设置梯度记录为开启状态 x = tor ...

  4. Tensorflow利用函数修饰符@tf.custom_gradients自定义函数梯度

    Tensorflow学习笔记(1) 利用函数修饰符@tf.custom_gradients自定义函数梯度_寂乐居士的博客-CSDN博客_tf.custom_gradient python中的修饰符以及 ...

  5. Ajax异步请求(重渲染DOM元素时,如何自动调用并执行JS自定义函数【含代码】)- 案例篇

    文章目录 Ajax异步请求(重渲染DOM元素时,如何自动调用并执行JS自定义函数[含代码])- 案例篇 效果截图: 重要代码: 附:全部HTML代码: Ajax异步请求(重渲染DOM元素时,如何自动调 ...

  6. pytorch 中 利用自定义函数 get_mask_from_lengths(lengths, max_len)获取每个batch的mask

    在pytorch中,经常会需要通过batch进行批量处理数据,由于每个batch中各个样本之间存在差异,经常会需要进行先padding后mask的操作. 尤其是在自然语言处理任务中,每个batch中的 ...

  7. 金和oa:自定义表单自动获取当前系统用户名函数

    自定义表单自动获取当前系统用户名函数: function InitPage() {           //初始化申请部门和申请人            var sUserID = GetSessio ...

  8. PyTorch代码调试利器: 自动print每行代码的Tensor信息

    本文介绍一个用于 PyTorch 代码的实用工具 TorchSnooper.作者是TorchSnooper的作者,也是PyTorch开发者之一. GitHub 项目地址: https://github ...

  9. NNDL 实验五 前馈神经网络(2)自动梯度计算 优化问题

    目录 4.3 自动梯度计算 1. 使用pytorch的预定义算子来重新实现二分类任务.(必做) 4.3.1 利用预定义算子重新实现前馈神经网络 4.3.2 完善Runner类 4.3.3 模型训练 4 ...

最新文章

  1. shell 脚本 进行sqlite3初始化
  2. 简单的CSS颜色查看工具
  3. 高颜值的神经网络可视化工具:3D、彩色、可定制,还能可视化参数重要性 | 开源...
  4. 开源 java CMS - FreeCMS2.3会员个人资料
  5. C# GridView单元格合并.
  6. Python 用for循环实现猜数字游戏
  7. 配色方案没有头绪?看看给你灵感的专业指导
  8. 思科称可能是宇宙射线触发了路由器bug
  9. 470.用Rand7()实现Rand10()
  10. python绘制人物关系图,Python来袭,教你用Neo4j构建“复联4”人物关系图谱!
  11. 15.6寸键盘的详细介绍
  12. pi六轴算法_圆周率π的计算历程及各种脑洞大开的估计方法
  13. 蓝桥杯 java 跳马问题
  14. 菜鸟日记(yzy):集成Ucrop裁剪图片架构,并创建管理类使用
  15. 如何高效地阅读论文:三遍阅读法
  16. 笔试题:计算机网络 (1)
  17. 引力产生的原因是什么
  18. 少儿美术课儿童画之水彩画第3集《高高的长颈鹿》
  19. 使用HLK7628N碰到的一些问题
  20. electron 打包后找不到module问题

热门文章

  1. 基于置信度评价消歧的偏标记学习(2017)
  2. 腾讯太极广告一站式机器学习平台的产品化之路
  3. 大数据分析-Excel导入及筛选数据
  4. combobox 如何让text居中_MFC 中ListBox 与 ComboBox 中的文本如何实现水平居中与垂直居中 - 小众知识...
  5. 你真的懂了Camera的尺寸参数了吗?
  6. 妙趣横生的算法 C语言实现 pdf
  7. [Processing学习]ControlP5-02-knob
  8. 迷你日期查询器MiniDate
  9. python引用传递的区别_php传值引用的区别
  10. Dubbo--kazoo库操作zk