【lzy学习笔记-dive into deep learning】数学预备 2.5-2.7

2.5 自动微分

深度学习框架通过⾃动计算导数,即⾃动微分(automatic differentiation)来加快求导。实际中,根据我们设计的模型,系统会构建⼀个计算图(computational graph),来跟踪计算是哪些数据通过哪些操作组合起来产⽣输出。
⾃动微分使系统能够随后反向传播梯度。这⾥,反向传播(backpropagate)意味着跟踪整个计算图,填充关于每个参数的偏导数
一位网友的分享,解释计算图与BP
一个示例

import torch

x = torch.arange(4.0)

# 不会在每次对⼀个参数求导时都分配新的内存
# 因为我们经常会成千上万次地更新相同的参数,每次都分配新的内存可能很快就会将内存耗尽
# 一个标量函数关于向量x的梯度是与x同形状的向量
x.requires_grad_(True)
# 等价于 x=torch.arange(4.0,requires_grad=True)
print(x.grad)

y = 2 * torch.dot(x,x) # y = 2 x⊤ x
print(y)

# 调用反向传播函数来自动计算y关于x每个分量的梯度
y.backward()
print(x.grad)

# f(x) = 2*x0*x0 + 2*x1*x1 + 2*x2*x2 + 2*x3*x3
# df(x)/dx0 = 4*x0  when x0 = 0, df(x)/dx0 = 0
# df(x)/dx1 = 4*x1  when x1 = 1, df(x)/dx0 = 4
# df(x)/dx2 = 4*x2  when x2 = 2, df(x)/dx0 = 8
# df(x)/dx3 = 4*x3  when x3 = 4, df(x)/dx0 = 12

print(x.grad == 4*x)

# 在默认情况下,PyTorch会累积梯度,我们需要清除之前的值
x.grad.zero_()
y = x.sum()
# f(x) = x0 + x1 + x2 + x3
# df(x)/dx0 = df(x)/dx1 = df(x)/dx2 = df(x)/dx3 = 1
y.backward()
print(x.grad)

非标量变量的反向传播
当y不是标量时,向量y关于向量x的导数的最⾃然解释是⼀个矩阵。对于⾼阶和⾼维的y和x,求导的结果可以是⼀个⾼阶张量。
高等数学偏导数里讲的梯度,梯度指明了一个标量函数在某一点处上升或者下降最剧烈的方向和该方向的方向导数值。

x = torch.arange(4.0,requires_grad=True)
y = x * x # 按元素
# 对⾮标量调⽤backward需要传⼊⼀个gradient参数,该参数指定微分函数关于self的梯度。
# 只想求偏导数的和,所以传递⼀个1的梯度是合适的 (乘1相加就是sum)
y.sum().backward()      # y.backward(torch.ones(len(x)))
print(x.grad)

分离计算
希望将某些计算移动到记录的计算图之外。
在这里插入图片描述

import torch

x = torch.arange(4.0,requires_grad=True)
y = x * x # 非标量
u = y.detach()
z = u * x # 非标量
z.sum().backward()
print(x.grad == u) # tensor([True, True, True, True])

x.grad.zero_()
y.sum().backward() # 非标量
print(x.grad == 2 * x) # tensor([True, True, True, True])

Python控制流的梯度计算
使⽤⾃动微分的⼀个好处是:即使构建函数的计算图需要通过Python控制流(例如,条件、循环或任意函数调用),我们仍然可以计算得到的变量的梯度。

import torch
def f(a):
    b = a * 2
    while b.norm() < 1000:
        b = b * 2
    if b.sum() > 0:
        c = b
    else:
        c = 100 * b
    return c

a = torch.randn(size=(), requires_grad=True)
d = f(a)
d.backward()
print(a.grad == d / a)
# tensor(True)

小结
深度学习框架可以⾃动计算导数:我们首先将梯度附加到想要对其计算偏导数的变量上。然后我们记录⽬标值的计算,执行它的反向传播函数,并访问得到的梯度。

2.6 概率

基本概率论
从概率分布中抽取样本的过程称为抽样(sampling)
将概率分配给⼀些离散选择的分布称为多项分布(multinomial distribution)
在估计⼀个骰⼦的公平性时,我们希望从同⼀分布中⽣成多个样本。如果⽤Python的for循环来完成这个任务,速度会慢得惊⼈。因此我们使⽤深度学习框架的函数同时抽取多个样本,得到我们想要的任意形状的独⽴样本数组。

import torch
from torch.distributions import multinomial
import matplotlib.pyplot as plt

# 概率分布
fair_probs = torch.ones([6]) / 6
# 对数据采样/抽样
# sample 600 times with fair probs. theoritical output [100, 100, 100, 100, 100, 100]
print(multinomial.Multinomial(600, fair_probs).sample())

# 计算相对频率以作为真实概率的估计
counts = multinomial.Multinomial(1000, fair_probs).sample()
print(counts / 1000)      # theoritical value: 1/6 ~= 0.167

# 概率如何随着时间的推移收敛到真实概率
# 进⾏500组实验,每组抽取10个样本
counts = multinomial.Multinomial(10, fair_probs).sample((500,))
cum_counts = counts.cumsum(dim=0) # 按行累加
estimates = cum_counts / cum_counts.sum(dim=1, keepdims=True) # 不降维保持形状
print(estimates)

# 画6条线
for i in range(6):
    plt.plot(estimates[:, i].numpy(), label=("P(die=" + str(i + 1) + ")"))

plt.axhline(y=0.167, color='black', linestyle='dashed') # axhline绘制平行于x轴的水平参考线
plt.gca().set_xlabel("Groups of experiments")
plt.gca().set_ylabel("Estimated probability")
plt.legend() # 加图标
plt.show()

公理:
在处理骰子掷出时,我们将集合S = {1, 2, 3, 4, 5, 6} 称为样本空间(sample space)或结果空间(outcome
space),其中每个元素都是结果(outcome)
事件(event)是⼀组给定样本空间的随机结果
在这里插入图片描述
随机变量:
在这里插入图片描述
离散随机变量 vs 连续随机变量(区间)
在这些情况下,我们将这个看到某个数值的可能性量化为密度(density)。高度恰好为1.80米的概率为0,但密度不是0。
处理多个随机变量
① 联合概率joint probability P(A = a, B = b)
A = a和B = b同时发⽣的可能性不⼤于A = a或是B = b单独发⽣的可能性
② 条件概率conditional probability
在这里插入图片描述
③贝叶斯定理Bayes’theorem
在这里插入图片描述
④边际化
在这里插入图片描述
⑤独立性
依赖(dependence)与独⽴(independence)
如果两个随机变量A和B是独⽴的,意味着事件A的发⽣跟B事件的发⽣⽆关。
两个随机变量是独⽴的,当且仅当两个随机变量的联合分布是其各⾃分布的乘积。
在这里插入图片描述
期望和方差:概括概率分布的关键特征
在这里插入图片描述
⼩结
• 我们可以从概率分布中采样。
• 我们可以使⽤联合分布、条件分布、Bayes定理、边缘化和独⽴性假设来分析多个随机变量。
• 期望和⽅差为概率分布的关键特征的概括提供了实⽤的度量形式。

2.7 查阅文档

查找模块中的所有函数和类
通常,我们可以忽略以“__”(双下划线)开始和结束的函数(它们是Python中的特殊对象),或以单个“_”(单下划线)开始的函数(它们通常是内部函数)。

import torch
# 查看PyTorch API的指导

# 查询随机数⽣成模块中的所有属性
print(dir(torch.distributions)) # 模块中可以调⽤哪些函数和类

查找特定函数和类的用法

import torch
# 如何使⽤给定函数或类的更具体说明

# 查看张量ones函数
help(torch.ones)

⼩结
• 官⽅⽂档提供了本书之外的⼤量描述和⽰例。
• 我们可以通过调⽤dir和help函数或在Jupyter记事本中使⽤?和??查看API的⽤法⽂档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值