当你用一个定制的训练循环训练一个深度学习模型时,软件会最小化关于可学习参数的损失。为了使损失最小化,该软件使用了损失相对于可学习参数的梯度。要使用自动微分来计算这些梯度,必须定义一个模型梯度函数。
一个例子展示了如何训练深度学习模型与dlnetwork
对象,看到使用自定义训练循环训练网络.有关演示如何训练定义为函数的深度学习模型的示例,请参见利用模型函数训练网络.
dlnetwork
对象如果你有一个深度学习模型被定义为dlnetwork
对象,然后创建一个模型梯度函数dlnetwork
对象作为输入。
对于指定为的模型dlnetwork
对象,创建窗体的函数gradients = modelGradients(dlnet,dlX,T)
,在那里dlnet
就是网络,dlX
是网络输入,T
包含目标和梯度
包含返回的渐变。可选地,您可以将额外的参数传递给gradients函数(例如,如果损失函数需要额外的信息),或者返回额外的参数(例如,用于绘制训练进度的指标)。
例如,该函数返回指定对象的梯度和交叉熵损失dlnetwork
对象dlnet
,输入数据dlX
,及目标T
.
函数[gradients, loss] = modelGradients(dlnet, dlX, T)通过dlnetwork对象转发数据。dlY = forward(dlnet,dlX);计算损失。损失=交叉熵(dlY,T);计算梯度。Gradients = dlgradient(loss,dlnet);结束
如果你有一个定义为函数的深度学习模型,那么创建一个模型梯度函数,将模型可学习参数作为输入。
对于指定为函数的模型,请创建该形式的函数gradients = modelGradients(参数,dlX,T)
,在那里参数
包含可学习参数,dlX
为模型输入,T
包含目标和梯度
包含返回的渐变。可选地,您可以将额外的参数传递给gradients函数(例如,如果损失函数需要额外的信息),或者返回额外的参数(例如,用于绘制训练进度的指标)。
例如,该函数返回深度学习模型函数的梯度和交叉熵损失模型
使用指定的可学习参数参数
,输入数据dlX
,及目标T
.
函数[gradients, loss] = modelGradients(parameters, dlX, T)通过模型函数转发数据。dlY =模型(参数,dlX);计算损失。损失=交叉熵(dlY,T);计算梯度。Gradients = dlgradient(损失,参数);结束
若要使用自动微分来评估模型梯度,请使用dlfeval
函数,它计算启用了自动区分的函数。的第一个输入dlfeval
,传递指定为函数句柄的模型梯度函数。对于下面的输入,传递模型梯度函数所需的变量。的输出dlfeval
函数,指定与模型梯度函数相同的输出。
例如,评估模型梯度函数modelGradients
与一个dlnetwork
对象dlnet
,输入数据dlX
,及目标T
,并返回模型梯度和损失。
[gradients, loss] = dlfeval(@modelGradients,dlnet,dlX,T);
类似地,计算模型梯度函数modelGradients
使用由结构指定的具有可学习参数的模型函数参数
,输入数据dlX
,及目标T
,并返回模型梯度和损失。
[gradients, loss] = dlfeval(@modelGradients,parameters,dlX,T);
要使用梯度更新可学习参数,可以使用以下函数。
函数 | 描述 |
---|---|
adamupdate |
使用自适应矩估计更新参数(Adam) |
rmspropupdate |
使用均方根传播(RMSProp)更新参数 |
sgdmupdate |
使用随机动量梯度下降(SGDM)更新参数 |
dlupdate |
使用自定义函数更新参数 |
例如,更新a的可学习参数dlnetwork
对象dlnet
使用adamupdate
函数。
[dlnet,trailingAvg,trailingAvgSq] = adamupdate(dlnet,gradients,...trailingAvg trailingAverageSq,迭代);
梯度
模型的输出是梯度函数,和trailingAvg
,trailingAvgSq
,迭代
类是否需要超参数adamupdate
函数。
类似地,更新模型函数的可学习参数参数
使用adamupdate
函数。
[parameters,trailingAvg,trailingAvgSq] = adamupdate(参数,梯度,...trailingAvg trailingAverageSq,迭代);
梯度
模型的输出是梯度函数,和trailingAvg
,trailingAvgSq
,迭代
类是否需要超参数adamupdate
函数。
当使用自定义训练循环训练深度学习模型时,评估模型梯度并更新每个小批的可学习参数。
方法的示例dlfeval
而且adamupdate
自定义训练循环中的函数。
迭代= 0;%遍历epoch。为epoch = 1:numEpochs在小批上循环。为i = 1:numIterationsPerEpoch迭代=迭代+ 1;准备小批量。%……评估模型梯度。[gradients, loss] = dlfeval(@modelGradients,dlnet,dlX,T);更新可学习参数。[parameters,trailingAvg,trailingAvgSq] = adamupdate(参数,梯度,...trailingAvg trailingAverageSq,迭代);结束结束
一个例子展示了如何训练一个深度学习模型dlnetwork
对象,看到使用自定义训练循环训练网络.有关演示如何训练定义为函数的深度学习模型的示例,请参见利用模型函数训练网络.
如果模型梯度函数的实现有问题,则调用dlfeval
可以抛出错误。有时候,当你使用dlfeval
函数时,不清楚抛出错误的是哪一行代码。为了帮助定位错误,您可以尝试以下方法。
方法直接调用模型梯度函数(也就是说,不使用dlfeval
函数),并生成预期大小的输入。如果任何一行代码抛出错误,则错误消息将提供额外的详细信息。注意,当您不使用dlfeval
函数的任何调用dlgradient
函数抛出错误。
生成图像输入数据。X = rand([28 28 1 100],“单一”);dlX = dlarray(dlX);生成单热编码目标数据。T = repmat(眼睛)“单一”), 10 [1]);[gradients, loss] = modelGradients(dlnet,dlX,T);
使用生成的预期大小的输入手动运行模型梯度函数中的代码,并检查输出和任何抛出的错误消息。
例如,考虑下面的模型梯度函数。
函数[gradients, loss] = modelGradients(dlnet, dlX, T)通过dlnetwork对象转发数据。dlY = forward(dlnet,dlX);计算损失。损失=交叉熵(dlY,T);计算梯度。Gradients = dlgradient(loss,dlnet);结束
运行以下代码检查模型梯度函数。
生成图像输入数据。X = rand([28 28 1 100],“单一”);dlX = dlarray(dlX);生成单热编码目标数据。T = repmat(眼睛)“单一”), 10 [1]);%检查向前通过。dlY = forward(dlnet,dlX);检查损失计算。损失=交叉熵(dlX,T)