Autograd自动微分库使用教程:从基础到实战

Autograd自动微分库使用教程:从基础到实战

autograd Efficiently computes derivatives of numpy code. autograd 项目地址: https://gitcode.com/gh_mirrors/au/autograd

为什么需要Autograd?

在机器学习和科学计算领域,我们经常需要计算复杂函数的导数。传统方法主要有两种:

  1. 手动推导并实现导数计算
  2. 使用Theano或TensorFlow等框架的限制性语法

Autograd提供了第三种选择:使用标准的Numpy库编写函数,Autograd会自动计算其梯度。这种方法既保持了编程的灵活性,又省去了手动推导的麻烦。

Autograd基础用法

Autograd的核心是grad函数,它接收一个函数并返回该函数的导数计算函数。需要注意的是,目标函数的输出必须是标量值(单个浮点数)。

基本示例:泰勒展开近似正弦函数

import autograd.numpy as np   # Autograd封装的Numpy
from autograd import grad

def taylor_sine(x):  # 使用泰勒级数近似正弦函数
    ans = currterm = x
    i = 0
    while np.abs(currterm) > 0.001:
        currterm = -currterm * x**2 / ((2 * i + 3) * (2 * i + 2))
        ans = ans + currterm
        i += 1
    return ans

grad_sine = grad(taylor_sine)
print("π处的梯度是:", grad_sine(np.pi))

这个例子展示了Autograd的强大之处:它能正确处理循环和条件判断等控制流结构。

实战案例:逻辑回归

让我们通过一个完整的逻辑回归示例来展示Autograd的实际应用:

import autograd.numpy as np
from autograd import grad

def sigmoid(x):
    return 0.5 * (np.tanh(x / 2.) + 1)

def logistic_predictions(weights, inputs):
    # 计算逻辑回归模型的预测概率
    return sigmoid(np.dot(inputs, weights))

def training_loss(weights):
    # 训练损失是训练标签的负对数似然
    preds = logistic_predictions(weights, inputs)
    label_probabilities = preds * targets + (1 - preds) * (1 - targets)
    return -np.sum(np.log(label_probabilities))

# 构建小型数据集
inputs = np.array([[0.52, 1.12,  0.77],
                   [0.88, -1.08, 0.15],
                   [0.52, 0.06, -1.30],
                   [0.74, -2.49, 1.39]])
targets = np.array([True, True, False, True])

# 使用Autograd创建梯度计算函数
training_gradient_fun = grad(training_loss)

# 梯度下降优化权重
weights = np.array([0.0, 0.0, 0.0])
print("初始损失:", training_loss(weights))
for i in range(100):
    weights -= training_gradient_fun(weights) * 0.01

print("训练后损失:", training_loss(weights))

Autograd工作原理

Autograd通过以下步骤实现自动微分:

  1. 计算图构建:在执行函数时记录所有操作
  2. 反向模式微分:从输出向输入反向传播梯度
  3. 向量-雅可比积:高效计算梯度而不显式构造雅可比矩阵

反向模式微分的优势

对于输入维度高、输出为标量的函数(如机器学习中的损失函数),反向模式微分比正向模式或有限差分法更高效。在机器学习中,这被称为"反向传播"。

支持的Numpy/Scipy功能

Autograd支持大多数Numpy操作,包括:

  • 数学运算
  • 数组和矩阵操作
  • 线性代数函数
  • 快速傅里叶变换
  • 复数运算
  • N维卷积

使用限制

  1. 不支持数组赋值操作(如A[i,j] = x
  2. 不支持A.dot(B)语法(应使用np.dot(A,B)
  3. 避免原地操作(如a += b
  4. 某些isinstance检查需要使用Autograd提供的版本

扩展Autograd:自定义原语

当Autograd不支持某个函数时,可以自定义其梯度计算:

from autograd.extend import primitive, defvjp

@primitive
def logsumexp(x):
    """数值稳定的log(sum(exp(x)))"""
    max_x = np.max(x)
    return max_x + np.log(np.sum(np.exp(x - max_x)))

def logsumexp_vjp(ans, x):
    x_shape = x.shape
    return lambda g: np.full(x_shape, g) * np.exp(x - np.full(x_shape, ans))

defvjp(logsumexp, logsumexp_vjp)

复数支持

Autograd采用特定约定支持复数运算:

  1. 对于全纯函数,得到常规复导数
  2. 对于复参数的实值损失函数,结果可用于基于梯度的优化器
  3. 对于内部使用复数运算的实值函数,结果与纯实数实现一致

性能优化建议

  1. 避免不必要的计算图构建
  2. 对于重复计算,考虑缓存梯度函数
  3. 使用Autograd提供的builtins模块进行类型检查
  4. 对于性能关键部分,考虑自定义原语

Autograd将自动微分的能力带入了标准的Python和Numpy编程环境中,使研究人员能够快速实验新模型而无需手动推导梯度或学习新的框架语法。

autograd Efficiently computes derivatives of numpy code. autograd 项目地址: https://gitcode.com/gh_mirrors/au/autograd

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诸余煦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值