张量网络的自动微分(文献翻译)

本文介绍了自动微分技术在张量网络中的应用,详细阐述了如何利用自动微分来优化张量网络收缩算法,包括张量重整化群(TRG)和角转移矩阵重整化群(CTMRG)方法。通过反向自动微分计算高阶导数,实现了张量网络状态的高效优化,并在自由能高阶微分和iPEPS基于梯度的优化中展示了其能力。同时,文章讨论了稳定后向传播的策略,如通过洛伦兹展宽处理数值稳定性问题,以及使用checkpointing和不动点迭代来节省内存。

本文为文献 Differentiable Programming Tensor Networks 的原创译文,转载请注明出处。
Author:小岚岚

I.引言

张量网络是研究经典统计物理和量子多体物理问题的重要方法[1-3]。近年来,它的应用迅速扩展到不同的领域,包括量子电路的仿真与设计[4-7]、量子误差校正[8,9]、机器学习[10-14]、语言建模[15,16]、量子场论[17-20]、nolographic二象性[21,22]。

张量网络在一般情况下的优化是众多研究方向的核心问题之一。尽管一维矩阵积状态的优化方案非常成功[23-28],但二维或高维张量网络的优化一直是一个具有挑战性的课题。这个困难部分原因是张量收缩的计算成本高,还要部分原因是在高维情况下缺乏有效的优化方案。对于无限平动不变量子系统,优化张量网络状态的挑战尤其紧迫。在这些情况下,同一个张量以多种方式影响变分能量,从而导致高度非线性的优化问题。基于近似虚时算符的优化方案[29-33]努力解决目标函数中的非局部依赖性。文献[34,35]采用基于梯度的优化,结果明显改善。
然而,即使对于一个简单的物理哈密顿量,从解析的角度推导张量网络状态梯度也很麻烦,而且容易出错。这一事实限制了基于梯度的张量网络状态优化在更复杂系统中的广泛应用。替代方法如使用数值导数计算梯度,精度和效率有限;因此,它们只适用于变化参数较少的情况[36,37]。使用链式法则手动推导梯度只适用于精心设计的简单张量网络结构[38]。

可微编程通过以完全可微的方式组合整个张量网络程序并使用自动微分来优化它们,为这些问题提供了优雅而有效的解决方案。在本文中,我们提出基本的自动微分技术,计算张量网络程序的(高阶)导数有效地数值精度。这一进展为一般情况下基于梯度(甚至基于hessian)的张量网络状态优化打开了大门。此外,计算张量网络算法输出的(高阶)梯度提供了一个简单的方法来计算物理量,如比热和磁化率。可微规划方法不知道详细的格点几何、哈密顿量和张量网络收缩方案。因此,该方法的通用性足以支持广泛的张量网络应用。我们的重点是涉及二维无限张量网络的应用,与传统方法相比,可微规划技术提供了显著的好处。我们证明,在通过奇异值分解(SVD)解决数值稳定微分和不动点迭代的内存高效实现等重大技术挑战后,可以获得张量网络状态变分优化的最先进结果。
本文的组织结构如下。在第二节中,我们在张量网络算法的背景下引入自动微分,并将张量网络收缩表示为计算图。在第三节中,我们给出了张量网络算法的稳定和可扩展可微规划的关键技术。在第四节中,我们证明了该方法的能力,并将其应用于无限正方晶格上的经典Ising模型和量子海森堡模型。最后,我们在第五节对未来的研究方向进行了展望。我们的代码实现是公开的(参见参考[39])。

II.一般理论

A.自动微分

通过计算图自动微分是一个统一的框架,涵盖了机器学习训练神经网络,优化量子物理张量网络等等。我们首先回顾自动微分的核心思想,然后解释它在以计算图形式表述的各种张量网络收缩算法中的应用。
自动微分机械地计算用计算机程序[40]表示的计算过程的导数。与数值微分不同,自动微分计算的导数值精确到机器精度。其性能有、普适的理论保证,不超过原程序的算法复杂度[41,42]。
在这里插入图片描述

图1所示。计算图的反向自动微分。黑色箭头表示从输入到输出的正向评价函数。红色箭头表示伴随反向传播的后退步骤。(a)链图。(b)一个更一般的计算图。在向后传递过程中,给定节点的伴随点根据公式(2)计算。

自动微分是现代深度学习应用的计算引擎[43,44]。在量子最优控制[45]和量子化学计算中也有应用,如计算力[46],优化基参数[47]等。自动微分的中心是计算图的概念。计算图是由基本计算步骤组成的有向无环图。图的节点表示数据,数据可以是标量、向量,矩阵,或者张量[48]。图连通性表示计算过程中数据流的依赖性。最简单的计算图是图1(a)所示的链。例如,从输入参数向量theta开始,可以计算一系列中间结果,直到最终的输出L,我们假设它是一个标量。所谓的正向求值就是按顺序遍历链图,即 θ → T 1 → . . . → T n → L \theta \rightarrow T^1\rightarrow...\rightarrow T^n \rightarrow \mathcal{L} θT1...TnL
为了计算目标函数相对于输入参数的梯度,我们可以利用链式法则
∂ L ∂ θ = ∂ L ∂ T n ∂ T n ∂ T n − 1 . . . ∂ T 2 ∂ T 1 ∂ T 1 ∂ θ . ( 1 ) \frac{\partial \mathcal{L} }{\partial \theta}= \frac{\partial \mathcal{L} }{\partial T^n} \frac{\partial T^n }{\partial T^{n-1}}... \frac{\partial T^2 }{\partial T^1} \frac{\partial T^1}{\partial \theta}. (1) θL=TnLTn1Tn...T1T2θT1.(1)
由于我们考虑的情况是,输入维数大于输出维数,在Eq.(1)中通过使用一系列雅可比向量乘积从左到右相乘来计算梯度是更有效的。根据图1(a)所示的计算图,将图向后遍历,并将梯度信号从输出端传播回输入端。用这种方法计算导数叫做反向自动微分。这种方法通常称为反向传播算法[43],被认为是训练深度神经网络最成功的方法。引入伴随变量 T ˉ = ∂ L / ∂ T \bar T=\partial \mathcal{L} /\partial T Tˉ=L/T 来表示最终输出L相对于变量T的梯度。我们可以看到,反向自动微分将伴随变量从 T n ‾ = L ˉ ∂ L / ∂ T n \overline {T^n} =\bar \mathcal{L} \partial \mathcal{L}/\partial T^n Tn=LˉL/Tn L ˉ = 1 \bar \mathcal{L}=1 Lˉ=1
一直传播到 T i ‾ = T i + 1 ‾ ∂ T i + 1 / ∂ T i , i = n − 1 , . . . 1 \overline

<think>好的,我现在需要帮助用户了解如何在TensorFlow和PyTorch中计算两个张量之间的梯度,可能用于自定义反向传播或优化算法。首先,我要回忆一下这两个框架中处理梯度的方法,然后结合用户提供的引用内容,特别是PyTorch相关的部分,来组织回答。 用户提到他们想计算两个张量之间的梯度,可能是为了自定义反向传播或优化。这说明他们可能需要了解如何手动计算梯度,或者如何覆盖默认的梯度计算方式。我需要分步骤解释在两种框架中的实现方法,并且可能需要给出代码示例,确保符合用户提到的格式要求,比如行内数学公式用$...$,独立公式用$$...$$。 首先,在PyTorch中,自动微分主要依赖于requires_grad和backward()方法。用户提供的引用[1]和[2]中提到了使用autograd模块,特别是torch.autograd.grad函数。这可能与计算两个张量之间的梯度有关,比如y相对于x的梯度。需要说明如何设置requires_grad,然后使用grad函数或者backward()来获取梯度。例如,用户可能需要计算张量A对张量B的梯度,这时候需要确保两个张量都在计算图中,并且正确地进行前向计算,然后调用反向传播或者直接使用grad函数。 在TensorFlow中,梯度带(GradientTape)是常用的工具。用户需要了解如何使用tf.GradientTape来记录操作,然后计算梯度。同样,可能需要两个张量之间的梯度,比如计算y相对于x的导数。需要展示如何通过tape.gradient(y, x)来获取梯度,并且说明如何处理多个变量的情况。 另外,用户可能对自定义梯度感兴趣,比如在某些情况下覆盖默认的梯度计算,这在两种框架中都有支持。例如,在TensorFlow中使用@tf.custom_gradient装饰器,在PyTorch中重写backward方法或者使用torch.autograd.Function。这部分需要详细说明,并给出示例代码。 需要注意用户提到的格式要求,比如代码块需要用反引号包裹,行内公式用$符号。例如,在解释梯度计算时,涉及到的数学公式如$\frac{\partial y}{\partial x}$需要用正确的LaTeX语法。同时,生成的相关问题需要符合用户的需求,比如如何应用自定义梯度到优化算法,或者在复杂计算图中的处理。 在组织回答时,结构要清晰,分PyTorch和TensorFlow两部分,每部分包括基本梯度计算、高阶梯度计算(如果适用)以及自定义梯度的方法。每个步骤都需要有代码示例,并解释关键点,比如设置requires_grad、使用GradientTape、以及如何定义自定义梯度函数。 最后,生成的相关问题要围绕用户可能的后续疑问展开,比如性能优化、应用场景、调试方法等。确保问题能够帮助用户深入理解相关主题,并引导他们进一步学习。 现在需要检查是否覆盖了所有关键点:两种框架的基本梯度计算、自定义梯度的方法、代码示例是否正确、数学公式格式是否符合要求,以及相关问题是否合适。同时,引用用户提供的参考文献,特别是引用[1]和[2]中关于PyTorch自动微分的内容,确保回答的准确性。</think>### 计算两个张量之间梯度的方法(TensorFlow/PyTorch) 在深度学习中,计算两个张量之间的梯度是实现自定义反向传播或优化算法的核心步骤。以下是针对 **TensorFlow** 和 **PyTorch** 的具体实现方法: --- #### **PyTorch 实现** 1. **基础梯度计算** - 使用 `torch.autograd.grad` 直接计算梯度: ```python import torch x = torch.tensor([2.0], requires_grad=True) y = x ** 3 # y = x^3 dy_dx = torch.autograd.grad(outputs=y, inputs=x)[0] # dy/dx = 3x^2 print(dy_dx) # 输出 tensor([12.]) (3*2^2=12) ``` - 或通过 `backward()` 累积梯度: ```python y.backward() print(x.grad) # 同上 ``` 2. **计算两个张量之间的高阶梯度** 若需计算 $z = f(y)$ 对 $x$ 的梯度(链式法则): $$ \frac{\partial z}{\partial x} = \frac{\partial z}{\partial y} \cdot \frac{\partial y}{\partial x} $$ ```python x = torch.tensor([3.0], requires_grad=True) y = x ** 2 # y = x^2 z = torch.sin(y) # z = sin(y) dz_dx = torch.autograd.grad(z, x, create_graph=True)[0] # dz/dx = 2x*cos(x^2) print(dz_dx) # tensor([-5.4679], grad_fn=<MulBackward0>) ``` 3. **自定义梯度规则** 通过继承 `torch.autograd.Function` 覆盖梯度计算逻辑: ```python class CustomFunction(torch.autograd.Function): @staticmethod def forward(ctx, x): ctx.save_for_backward(x) return x ** 2 @staticmethod def backward(ctx, grad_output): x, = ctx.saved_tensors # 定义梯度规则:假设手动修改梯度为原值的2倍 return grad_output * 2 * x # 原梯度为 2x,现在变为 4x x = torch.tensor([2.0], requires_grad=True) y = CustomFunction.apply(x) y.backward() print(x.grad) # 输出 tensor([8.]) (4*2=8) ``` --- #### **TensorFlow 实现** 1. **基础梯度计算** 使用 `tf.GradientTape` 记录计算过程: ```python import tensorflow as tf x = tf.Variable(2.0) with tf.GradientTape() as tape: y = x ** 3 # y = x^3 dy_dx = tape.gradient(y, x) # dy/dx = 3x^2 print(dy_dx) # 输出 tf.Tensor(12.0, shape=(), dtype=float32) ``` 2. **计算多个张量间的梯度** 若需同时计算多个输出对输入的梯度: ```python x = tf.Variable(2.0) with tf.GradientTape(persistent=True) as tape: y = x ** 2 z = tf.sin(y) dz_dx = tape.gradient(z, x) # dz/dx = 2x*cos(x^2) dy_dx = tape.gradient(y, x) # dy/dx = 2x print(dz_dx.numpy()) # -5.4679 (当x=2时,2*2*cos(4)=4*cos(4)) ``` 3. **自定义梯度** 使用 `@tf.custom_gradient` 装饰器定义梯度规则: ```python @tf.custom_gradient def custom_op(x): y = x ** 2 def grad_fn(dy): # 修改梯度为原始值的3倍 return dy * 3 * x # 原梯度为 2x,现在变为 6x return y, grad_fn x = tf.Variable(2.0) with tf.GradientTape() as tape: y = custom_op(x) dy_dx = tape.gradient(y, x) print(dy_dx.numpy()) # 输出 12.0 (6*2=12) ``` --- ### **关键区别与注意事项** | 框架 | 核心机制 | 自定义梯度方法 | |------------|------------------------|------------------------------------| | PyTorch | 动态计算图 | 继承 `torch.autograd.Function` | | TensorFlow | 静态/动态计算图(Eager)| 使用 `@tf.custom_gradient` 装饰器 | - **数学原理**:梯度计算本质上是计算偏导数 $\frac{\partial y}{\partial x}$,通过链式法则实现反向传播[^1][^2]。 - **调试技巧**:可通过 `torch.autograd.gradcheck`(PyTorch)或 `tf.test.compute_gradient`(TensorFlow)验证梯度正确性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值