使用自动微分的自定义训练和计算
自动区分功能使创建自定义训练循环,自定义层和其他深度学习自定义更加容易。
通常,自定义深度学习培训的最简单方法是创建dlnetwork。在网络中包括所需的层。然后,通过使用某种梯度下降来在自定义循环中执行训练,其中梯度是目标函数的梯度。目标函数可以是分类误差,交叉熵或网络权重的任何其他相关标量函数。请参见具有dlarray支持的功能列表。
此示例是自定义训练循环的高级版本。在此,f 是目标函数,例如损失,g是目标函数相对于网络中权重的梯度net。该 update函数表示某种类型的梯度下降。
% High-level training loopn = 1;while (n < nmax)[f,g] = dlfeval(@model,net,dlX,t);net = update(net,g);n = n + 1;end
可以使用 dlfeval计算对象和梯度的数值,如果想要自动计算微分,dlX必须是一个dlarray类型。
dlX = dlarray(X);
目标函数dlgradient调用计算梯度。该dlgradient调用必须在要dlfeval评估的函数内部 。
function [f,g] = model(net,dlX,T)% Calculate objective using supported functions for dlarrayy = forward(net,dlX);f = fcnvalue(y,T); % crossentropy or similarg = dlgradient(f,net.Learnables); % Automatic gradientend
对于使用一个例子dlnetwork用一个简单的 dlfeval- dlgradient-dlarray 语法,请参阅梯度-CAM揭示了为什么深度学习决策背后。有关使用自定义训练循环的更复杂示例,请参阅训练生成对抗网络(GAN)。有关使用自动微分的自定义训练的更多详细信息,请参阅定义自定义训练循环,损失函数和网络。
使用 dlgradient和dlfeval来求解自动微分
要使用自动微分,必须dlgradient在函数内部调用并使用评估函数dlfeval。表示将导数作为dlarray对象的点,该对象管理数据结构并启用评估跟踪。例如,Rosenbrock函数是用于优化的常见测试函数。
function [f,grad] = rosenbrock(x)f = 100*(x(2) - x(1).^2).^2 + (1 - x(1)).^2;grad = dlgradient(f,x);end
计算在x0 = [–1,2]处的Rosenbrock函数的值和梯度。启用自动分化在Rosenbrock函数,通过 x0作为dlarray。
x0 = dlarray([-1,2]);[fval,gradval] = dlfeval(@rosenbrock,x0)
fval =
1x1 dlarray
104
gradval =
1x2 dlarray
396 200
有关使用自动微分的示例,请参阅Grad-CAM揭示了深度学习决策背后的原因。
导数轨迹
为了从数值上评估梯度dlarray,如自动微分背景中所述,构造一个用于反向模式微分的数据结构。此数据结构是微分计算的 轨迹。使用自动微分和派生跟踪时,请记住以下准则:
不要
dlarray在目标函数计算中引入新的内容,并尝试针对该对象进行区分。例如:function [dy,dy1] = fun(x1)x2 = dlarray(0);y = x1 + x2;dy = dlgradient(y,x2); % Error: x2 is untraceddy1 = dlgradient(y,x1); % No error even though y has an untraced portionend
不要
extractdata与跟踪参数一起使用。这样做会破坏跟踪。例如:fun = @(x)dlgradient(x + atan(extractdata(x)),x);% Gradient for any point is 1 due to the leading 'x' term in fun.dlfeval(fun,dlarray(2.5))
ans =
1x1 dlarray
1
- 但是,您可以用来
extractdata从一个依赖变量中引入一个新的独立变量。 仅使用支持的功能。请参见具有dlarray支持的功能列表。要使用不受支持的函数f,请尝试使用受支持的函数实现f。
自动微分的特征
您只能对标量值函数使用自动微分来评估梯度。中间计算可以具有任意数量的变量,但是最终函数值必须为标量。如果需要取向量值函数的导数,则一次取一个分量的导数。在这种情况下,请考虑将“
dlgradient'RetainData'名称/值”对参数设置为true。- 调用以
dlgradient评估特定点的导数。当没有理论值时,软件通常会对导数的值进行任意选择。例如,relu函数relu(x) = max(x,0)不可在上微分x = 0。但是,dlgradient返回导数的值。x = dlarray(0);y = dlfeval(@(t)dlgradient(relu(t),t),x)
y =
1x1 dlarray
0
在附近点eps处的值是不同的
x = dlarray(eps);y = dlfeval(@(t)dlgradient(relu(t),t),x)
y =
1x1 dlarray
1
当前,dlarray不允许高阶导数。换句话说,您不能通过调用dlgradient 两次来计算二阶导数。
