主要内容

dlgradient

使用自动区分计算自定义训练循环的梯度

描述

使用dlgradient使用自定义训练循环的自动微分计算导数。

提示

对于大多数深度学习任务,你可以使用预先训练好的网络,并使其适应你自己的数据。有关演示如何使用迁移学习重新训练卷积神经网络来对一组新图像进行分类的示例,请参见训练深度学习网络对新图像进行分类.或者,您可以从头创建和训练网络layerGraph对象具有trainNetwork而且trainingOptions功能。

如果trainingOptions函数没有为您的任务提供所需的训练选项,那么您可以使用自动区分创建自定义训练循环。要了解更多信息,请参见为自定义训练循环定义深度学习网络

例子

dydx1,…,dydxk] = dlgradient(yx1,…,xk的渐变y关于变量x1通过xk

调用dlgradient从传递给的函数内部dlfeval.看到使用自动分化计算梯度而且在深度学习工具箱中使用自动区分

dydx1,…,dydxk] = dlgradient(yx1,…,xk名称,值返回渐变并使用一个或多个名称-值对指定其他选项。例如,dydx = dlgradient(y,x,'RetainData',true)使梯度保留中间值,以便在后续中重用dlgradient调用。这种语法可以节省时间,但会占用更多内存。有关更多信息,请参见提示

例子

全部折叠

Rosenbrock函数是用于优化的标准测试函数。的rosenbrock.mHelper函数计算函数值,并使用自动微分来计算其梯度。

类型rosenbrock.m
函数[y,就要]=。(x) y = 100 * (x - x(1)(2)。^ 2)。^2 + (1 - x(1)) ^2;Dydx = dlgradient(y,x);结束

求Rosenbrock函数及其在该点处的梯度[1,2],创建dlarray然后调用dlfeval在函数句柄上@rosenbrock

X0 = dlarray([-1,2]);[fval,gradval] = dlfeval(@rosenbrock,x0)
Fval = 1x1 dlarray 104
梯度= 1x2 dlarray 396 200

或者,将Rosenbrock函数定义为两个输入的函数,x1和x2

类型rosenbrock2.m
函数[y,dydx1,dydx2] = rosenbrock2(x1,x2) y = 100*(x2 - x1.^2)。^2 + (1 - x1) ^2;[dydx1,dydx2] = dlgradient(y,x1,x2);结束

调用dlfeval评估rosenbrock2在两个dlarray表示输入的参数1而且2

X1 = dlarray(-1);X2 = dlarray(2);[fval,dydx1,dydx2] = dlfeval(@rosenbrock2,x1,x2)
Fval = 1x1 dlarray 104
Dydx1 = 1x1 dlarray 396
Dydx2 = 1x1 dlarray 200

绘制单位正方形中几个点的Rosenbrock函数的梯度。首先,初始化表示计算点和函数输出的数组。

[X1 X2] = meshgrid(linspace(0,1,10));X1 = dlarray(X1(:));X2 = dlarray(X2(:));Y = dlarray(零(大小(X1)));Dydx1 = y;Dydx2 = y;

计算循环中的函数。使用以下方法绘制结果箭袋

i = 1:长度(X1) [Y (i), DYDX1(我),DYDX2 (i)) = dlfeval (@rosenbrock2, X1 (i), X2(我));结束箭袋(extractdata (X1)、extractdata (X2)、extractdata (DYDX1) extractdata (DYDX2))包含(x1的) ylabel (“x2”

图中包含一个轴对象。axis对象包含一个quiver类型的对象。

使用dlgradient而且dlfeval计算一个包含复数的函数的值和梯度。您可以计算复杂的梯度,或者将梯度限制为实数。

定义函数complexFun,在本例的末尾列出。这个函数实现了以下复杂的公式:

f x 2 + 3. x

定义函数gradFun,在本例的末尾列出。这个函数调用complexFun并使用dlgradient计算结果相对于输入的梯度。对于自动微分,要微分的值-即从输入计算的函数值-必须是一个实标量,因此函数在计算梯度之前取结果的实部分的和。该函数返回函数值的实部和梯度,梯度可以是复数。

定义复平面上在-2和-2之间的采样点 和2 并转换为dlarray

函数res = linspace(- 2,100);x = functionRes + 1i*functionRes.';X = dlarray(X);

计算每个样本点的函数值和梯度。

[y, grad] = dlfeval(@gradFun,x);Y = extractdata(Y);

定义要显示梯度的样本点。

gradientRes = linspace(-2,2,11);xGrad = gradientRes + 1i*gradientRes.';

提取这些样本点的梯度值。

[~,gradPlot] = dlfeval(@gradFun,dlarray(xGrad));gradPlot = extractdata(gradPlot);

画出结果。使用显示亮度图像来表示复平面上的函数值。使用箭袋来显示梯度的方向和大小。

显示亮度图像((2,2),(2,2),y);轴xycolorbar举行箭袋(真实(xGrad),图像放大(xGrad),真正的(gradPlot),图像放大(gradPlot),“k”);包含(“真正的”) ylabel (“虚”)标题(“实际价值与梯度”"Re$(f(x)) = $ Re$((2+3i)x)$"“翻译”“乳胶”

函数的梯度在整个复平面上是相同的。提取由自动微分计算的梯度值。

研究生(1,1)
Ans = 1×1 dlarray 2.0000 - 3.0000i

经检验,该函数的复导数具有该值

df x dx 2 + 3.

然而,函数Re( f x )不是解析的,因此没有定义复导数。对于MATLAB中的自动微分,微分的值必须总是实数,因此函数永远不能是复解析的。相反,导数的计算是这样的,返回的梯度指向最陡峭的上升方向,如图所示。这是通过解释函数Re来实现的 f x C R作为函数Re f x R + x R × R R

函数y = complexFun(x) y = (2+3i)*x;结束函数[y,grad] = gradFun(x) y = complexFun(x);Y = real(Y);Grad = dlgradient(sum(y,“所有”), x);结束

输入参数

全部折叠

要微分的变量,指定为标量dlarray对象。分化,y一定是的跟踪函数dlarray输入(见追踪dlarray),并且必须由受支持的函数组成万博1manbetxdlarray(见支持dlarray的函数列表万博1manbetx).

变量微分必须为实数,即使当名称-值选项“AllowComplex”设置为真正的

例子:100*(x(2) - x(1) ^2)²+ (1 - x(1))²

例子:relu (X)

数据类型:||逻辑

函数中的变量,指定为dlarray对象,包含的单元格数组、结构或表dlarray对象,或此类参数的任何组合。例如,参数可以是单元格数组,其中包含包含结构的单元格数组dlarray对象。

如果你指定x1,…,xk作为一个表,表必须包含以下变量:

  • -层名,指定为字符串标量。

  • 参数—参数名称,指定为字符串标量。

  • 价值参数的值,指定为包含dlarray

例子:Dlarray ([1 2;3 4])

数据类型:||逻辑|结构体|细胞
复数支持:万博1manbetx是的

名称-值参数

指定可选参数对为Name1 = Value1,…,以=家,在那里的名字参数名称和价值对应的值。名称-值参数必须出现在其他参数之后,但对的顺序无关紧要。

在R2021a之前,使用逗号分隔每个名称和值,并将其括起来的名字在报价。

例子:dydx = dlgradient(y,x,'RetainData',true)使梯度保留中间值,以便在后续中重用dlgradient调用

标记,在函数调用期间保留跟踪数据,指定为真正的.当这个论证是,一个dlarray在计算导数后立即丢弃导数跟踪。当这个论证是真正的,一个dlarray类的末尾保留导数跟踪dlfeval函数调用dlgradient.的真正的设置仅当dlfevalCall包含多个dlgradient调用。的真正的设置会导致软件使用更多内存,但可以节省时间时,多次dlgradient调用至少使用相同跟踪的一部分。

“EnableHigherDerivatives”真正的,则保留中间值“RetainData”期权没有作用。

例子:dydx = dlgradient(y,x,'RetainData',true)

数据类型:逻辑

标志,以启用高阶导数,指定为以下之一:

  • 真正的-启用高阶导数。方法的后续调用可在进一步计算中使用返回的梯度dlgradient函数。如果“EnableHigherDerivatives”真正的,则保留中间值“RetainData”期权没有作用。

  • -禁用高阶导数。不要追踪向后的传球。当您只需要计算一阶导数时,请使用此选项,因为这通常更快,需要的内存更少。

当使用dlgradient函数在AcceleratedFunction对象,默认值为真正的.否则,默认值为

有关如何训练需要计算高阶导数的模型的示例,请参见:

数据类型:逻辑

标志允许在函数中使用复杂变量和复杂渐变,指定为以下之一:

  • 真正的-允许复杂变量的功能和复杂的梯度。函数中的变量可以指定为复数。即使所有变量都是实数,梯度也可能很复杂。要求导的变量必须是实数。

  • 不允许使用复杂的变量和渐变。变量要求导,函数中的任何变量都必须是实数。渐变总是真实的。中间值仍然可能是复杂的。

变量微分必须为实数,即使当名称-值选项“AllowComplex”设置为真正的

数据类型:逻辑

输出参数

全部折叠

梯度,返回为adlarray对象,或包含的单元格数组、结构或表dlarray对象,或此类参数的任何组合。的大小和数据类型dydx1,…,dydxk是否与相关输入变量的值相同x1,…,xk

限制

  • dlgradient函数在使用时不支持计算高阶导数万博1manbetxdlnetwork包含具有自定义向后函数的自定义层的对象。

  • dlgradient函数在使用时不支持计算高阶导数万博1manbetxdlnetwork包含以下层的对象:

    • gruLayer

    • lstmLayer

    • bilstmLayer

  • dlgradient函数不支持计算依赖于以下函数的高阶导万博1manbetx数:

    • 格勒乌

    • lstm

    • 嵌入

    • 刺激

    • interp1

更多关于

全部折叠

追踪dlarray

在函数的计算过程中,adlarray内部记录在跟踪,使反向模式自动区分。跟踪发生在dlfeval调用。看到自动判别背景

提示

  • 一个dlgradient调用必须在函数内部。若要获得梯度的数值,必须使用dlfeval,函数的实参必须是adlarray.看到在深度学习工具箱中使用自动区分

  • 为了能够正确地评估渐变,y参数必须仅使用for支持的函数万博1manbetxdlarray.看到支持dlarray的函数列表万博1manbetx

  • 如果你设置“RetainData”到的名称-值对参数真正的时,软件保留跟踪dlfeval函数调用,而不是在导数计算后立即擦除轨迹。这种保存会导致后续的dlgradient在同一时间内调用dlfeval调用的执行速度更快,但会使用更多内存。例如,在训练对抗网络时“RetainData”设置是有用的,因为两个网络在训练过程中共享数据和功能。看到训练生成对抗网络(GAN)

  • 当您只需要计算一阶导数时,请确保“EnableHigherDerivatives”选择是因为这通常更快,需要更少的内存。

  • 复梯度是用维廷格导数计算的。梯度定义在函数的实部的增加方向上求导。这是因为要微分的变量——例如损失——必须是实数,即使函数很复杂。

扩展功能

版本历史

R2019b引入