• pytorch深度学习实战lesson8


    第八课 自动求导

    理论部分

    求导主要是有两种方式,第一种是符号求导,第二种是数值求导。

    自动求导的内部其实是计算图,计算图是将代码分解成操作子,将计算表示成一个无环图。

    计算图的显式构造:(mxnet)

    计算图的隐式构造:(mxnet)

    反向累计是比较常用的。

    总结:

    构造计算图

    前向:执行图,存储中间结果(设置中间变量)

    反向:从相反的方向执行图

    去除不需要的枝

    深度学习耗GPU资源体现在内存复杂度上面。因为求梯度时需要存储前面的结果。

    实践部分

    1. #自动求导
    2. import torch
    3. x=torch.arange(4.0) #requires_grad=True'''
    4. #x=tensor([0., 1., 2., 3.])
    5. x.requires_grad = True #计算y关于x的梯度之前需要存储梯度,等价于上句话的最后一个参数.
    6. #print(x.grad) #x.grad 默认值是none
    7. ########################################################################################
    8. #计算y
    9. y = 2 * torch.dot(x,x) #结果是个标量
    10. print('###################################################')
    11. print('torch.dot(x,x):\t',torch.dot(x,x))
    12. print('y:\t',y)
    13. y.backward() #通过反向传播函数自动计算y关于x每个分量的梯度
    14. print('x.grad:\t',x.grad)
    15. print('x.grad==4*x?\t',x.grad==4*x)
    16. print('###################################################')
    17. #在默认情况下,torch会累积梯度,所以需要对之前的值进行清零
    18. ########################################################################################
    19. x.grad.zero_() #下划线是指进行重写操作,也就是对x的梯度进行重写为0
    20. #print('x.grad:\t',x.grad)
    21. y=x.sum() #结果是个标量
    22. #print(y)
    23. y.backward()
    24. print('x.grad:\t',x.grad) #如果把16行注释,则结果是x.grad:tensor([ 1., 5., 9., 13.])
    25. #求和,梯度是1
    26. print('###################################################')
    27. ########################################################################################
    28. #在深度学习中,我们的目的不是计算微分矩阵,而是批量中每个样本单独计算的偏导数之和
    29. x.grad.zero_()
    30. y=x*x #结果是个向量
    31. y.sum().backward() #向量的求导转换成对标量求导(先求和再求导)
    32. print('x.grad:\t',x.grad)
    33. print('###################################################')
    34. ########################################################################################
    35. #将某些计算移动到记录的计算图之外,用于固定某些网络参数
    36. x.grad.zero_()
    37. y=x*x #结果是个向量
    38. u=y.detach() #把u做成常数,而非关于y的函数
    39. z=u*x #结果是个向量
    40. z.sum().backward() #向量的求导转换成对标量求导(先求和再求导)
    41. print('x.grad==u:\t',x.grad==u)
    42. x.grad.zero_()
    43. y.sum().backward()
    44. print('x.grad==2*x?\t',x.grad==2*x)
    45. print('###################################################')
    46. ########################################################################################
    47. #即使构建函数的计算图需要通过Python控制流(例如条件、循环或任意函数调用),我们仍然可以计算得到的变量的梯度
    48. def f(a):
    49. b = a * 2
    50. while b.norm() < 1000:
    51. b = b * 2
    52. if b.sum() > 0:
    53. c = b
    54. else:
    55. c = 100 * b
    56. return c
    57. a = torch.randn(size=(),requires_grad=True)
    58. d = f(a)
    59. d.backward()
    60. print('a.grad==d/a\t',a.grad==d/a)
    61. print('###################################################')

    ###################################################
    torch.dot(x,x):     tensor(14., grad_fn=)
    y:     tensor(28., grad_fn=)
    x.grad:     tensor([ 0.,  4.,  8., 12.])
    x.grad==4*x?     tensor([True, True, True, True])
    ###################################################
    x.grad:     tensor([1., 1., 1., 1.])
    ###################################################
    x.grad:     tensor([0., 2., 4., 6.])
    ###################################################
    x.grad==u:     tensor([True, True, True, True])
    x.grad==2*x?     tensor([True, True, True, True])
    ###################################################
    a.grad==d/a     tensor(True)
    ###################################################

    进程已结束,退出代码0

  • 相关阅读:
    【mysql 大表清理】磁盘占用太多,清理无效大表
    Renderbus瑞云渲染现在支持3dsMax 2024了
    视频剪辑高手的秘诀:如何从视频中提取封面,提高视频点击率
    3D工业相机及品牌集合
    《面试八股文》之Dubbo17卷
    CompletableFuture用法
    【机器学习笔记】【数据预处理】
    【多线程案例】定时器
    【Vulhub靶场】】zabbix-SQL注入(CVE-2016-10134)漏洞复现
    配置nginx动静分离全步骤
  • 原文地址:https://blog.csdn.net/weixin_48304306/article/details/127737671