主要内容

定义自定义深度学习中间层

提示

本主题介绍如何为您的问题定义自定义深度学习层。查看深度学习工具箱中的内置层列表™, 看见深度学习层列表

要了解如何定义自定义输出层,请参见定义自定义深度学习输出层

如果深度学习工具箱不提供任务所需的层,则可以使用本主题作为指南定义自己的自定义层。定义自定义层后,可以自动检查该层是否有效,GPU是否兼容,输出正确定义的梯度。

中间层架构

在训练期间,软件通过网络反复执行向前和向后传递。

在通过网络进行前进传递时,每层都会占用上一层的输出,应用函数,然后输出(向前传播)结果到下一个层。状态层,如LSTM层,也更新了图层状态。

层可以有多个输入或输出。例如,一个层可以X1., …,XN从前面的多个层转发输出Z1., …,ZM随后的层。

在网络的前向传递结束时,输出层计算损失L在预测之间Y目标是什么T

在网络的反向传递过程中,每一层取损耗相对于该层输出的导数,计算损耗的导数L然后向后传播结果。如果层具有可学习参数,则层还计算层权重的导数(可学习参数)。该层使用权重的导数来更新可学习参数。

下图描述了通过深神经网络的数据流程,并突出显示通过单个输入的层的数据流X单个输出Z,以及一个可学习的参数W

中间层模板

要定义自定义中间层,请使用此类定义模板。此模板概述了中间层类定义的结构。它概述了:

  • 可选属性块的层属性,可学习参数,和状态参数。有关更多信息,请参见中间层特性

  • 层构造函数。

  • 这个预测函数和可选的向前地作用有关详细信息,请参阅前进功能

  • 可选resetState用于具有状态属性的图层的函数。有关详细信息,请参阅重置状态函数

  • 可选落后的作用有关详细信息,请参阅后向函数

classdefmyLayer %&nnet.layer.Formattable(可选)属性%(可选)图层属性。%在此声明图层属性。终止属性(可学习)%(可选)层可学习参数。%在此声明可知参数。终止属性(州)%(可选)层状态参数。在这里声明状态参数。终止属性(可学习的,州)%(可选)嵌套dlnetwork对象都是可学习的参数和状态。%使用可学习和状态参数声明嵌套网络。终止方法函数tillay = mylayer()%(可选)创建一个myLayer。%该函数必须与类名相同。在这里定义层构造函数。终止函数[Z,状态]=预测(层,X)%在预测时通过层转发输入数据,并%输出结果和更新的状态。%%输入:%层-要向前传播的层% X -输入数据%产出:% Z -层前向函数的输出% state -(可选)更新的层状态。%% -对于有多个输入的层,将X替换为X1,…,XN,%n是输入的数量。%-对于具有多个输出的图层,将Z替换为%Z1,…,ZM,其中M是输出的数量。%-对于具有多个状态参数的图层,请替换状态% state1,…,状态K, 在哪里K我s the number of state%的参数。%在这里定义层预测函数。终止函数[Z,状态,内存]=转发(层,X)%(可选)在训练时通过图层转发输入数据%时间并输出结果、更新状态和内存%值。%%输入:%层-要向前传播的层% X -层输入数据%产出:% Z -层前向函数的输出% state -(可选)更新的层状态% memory -(可选)向后自定义的内存值%作用%% -对于有多个输入的层,将X替换为X1,…,XN,%n是输入的数量。%-对于具有多个输出的图层,将Z替换为%Z1,…,ZM,其中M是输出的数量。%-对于具有多个状态参数的图层,请替换状态% state1,…,状态K, 在哪里K我s the number of state%的参数。%定义层前进函数。终止函数层= resetState(层)%(可选)重置层状态。%在这里定义重置状态函数。终止函数[dLdX,dLdW,dLdSin]=向后(层,X,Z,dLdZ,dLdSout,内存)%(可选)反向传播损失的导数%功能通过层。%%输入:%图层-图层向后传播通过% X -层输入数据% Z -层输出数据% dLdZ -损耗对层的导数%输出% dLdSout -(可选)损失的衍生%到州输出%memory-前进功能的记忆值%产出:%DLDX  - 关于图层输入的损耗导数-(可选)损失的衍生%可学的参数% dLdSin -(可选)损失的衍生%状态输入%%-对于具有状态参数的图层,必须使用向后语法%同时包括dLdSout和dLdSin,或两者都不包括。%-对于具有多个输入的图层,将X和dLdX替换为% X1,…,XN和dLdX1,…,dLdXN,respectively, where N is%输入的数量。% -对于有多个输出的图层,将Z和dlZ替换为% Z1,…,ZM和dLdZ,.。。,dLdZM,其中M为%输出数量。%-对于具有多个可学习参数的图层,请替换%dLdW带dLdW1,…,dLdWP,其中P是%可学的参数。%-对于具有多个状态参数的图层,请替换dLdSin%使用dLdSin1、…、dLdSinK和% dLdSout1,…DldSoutK, respectively, where K is the number状态参数的%。%定义层面向后函数。终止终止终止

格式化输入和输出

使用dlarray通过允许您标记尺寸,对象使高维数据更容易。例如,您可以使用使用的标记对应于空间,时间,频道和批处理尺寸的维度标记“S”,“T”,“C”,“B”标签,分别。对于未指定尺寸和其他尺寸,请使用“U”标签。为dlarray通过特定尺寸运行的对象功能,可以通过格式化维度标签来指定维度标签dlarray对象,或使用数据格式选项。

使用格式化的dlarray自定义层中的对象还允许您定义输入和输出具有不同格式的图层,例如置换,添加或删除尺寸的图层。例如,您可以定义一层,该图层以格式为输入的百分比图像“SSCB”(空间、空间、通道、批次)并输出具有以下格式的序列的小批次“认知行为治疗”(通道、批次、时间)。使用格式化dlarray对象还允许您定义可以对具有不同输入格式的数据进行操作的层,例如,支持带有格式的输入的层万博1manbetx“SSCB”(空间、空间、通道、批次)和“认知行为治疗”(通道、批量、时间)。

如果不指定反向函数,则该层函数默认接收无格式dlarray对象作为输入。指定图层接收的格式化dlarray对象作为输入,也作为格式化的输出dlarray对象,也从nnet.layer.Formattable定义自定义图层时初始化。

有关如何使用格式化输入定义自定义图层的示例,请参阅定义带有格式化输入的自定义深度学习层

中间层特性

属性中声明图层属性属性类定义的部分。

默认情况下,自定义中间层具有这些特性。不要在中声明这些属性属性部分。

所有物 描述
的名字 层名,指定为字符向量或字符串标量。为数组输入,列车网络,assembleNetwork,layerGraph,dlnetwork.函数自动为层分配名称的名字着手''
描述

层的单行描述,指定为字符串标量或字符向量。当图层显示在图形中时,将显示此说明大堆

如果未指定图层描述,则软件将显示图层类名。

类型

层的类型,指定为字符向量或字符串标量。的价值类型当图层显示在图形中时显示大堆

如果不指定层类型,则软件将显示层类名称。

numinputs. 层的输入数,指定为正整数。如果未指定此值,则软件会自动设置numinputs.到了名称的数量输入名称. 默认值为1.。
输入名称 输入图层名称,指定为字符向量的单元格数组。如果未指定此值,则numinputs.大于1,然后软件自动设置输入名称{“三机”,…,“客栈”}, 在哪里N等于numinputs.. 默认值为{'在'}
NumOutputs 层的输出数,指定为正整数。如果您不指定此值,则软件将自动设置NumOutputs到了名称的数量OutputNames. 默认值为1.。
OutputNames 层的输出名称,指定为字符向量的单元数组。如果未指定此值,则NumOutputs大于1,然后软件自动设置OutputNames{'out1',…,'outM'}, 在哪里M等于NumOutputs. 默认值为{“出”}

如果该层没有其他属性,则可以省略属性部分。

提示

如果你正在创建一个有多个输入的图层,那么你必须设置numinputs.输入名称属性在层构造函数中。如果你正在创建一个有多个输出的图层,那么你必须设置NumOutputsOutputNames属性在层构造函数中。例如,请参见定义具有多个输入的自定义深度学习层

可学的参数

声明层可学习参数属性(可学的)类定义的部分。您可以指定数字数组或dlnetwork.对象作为可学习参数。如果dlnetwork.对象同时具有可学习参数和状态参数(例如dlnetwork.对象中包含LSTM层),则必须在属性(可学习、状态)部分。如果层没有可学习的参数,那么你可以省略属性与之有关的部分可学属性

可选地,您可以指定学习率因子和可学习参数的L2因子。默认情况下,每个可学习参数的学习率因子和L2因子设置为1.。对于内置层和自定义层,您可以使用以下函数设置和获取学习速率因子和L2正则化因子。

函数 描述
setLearnRateFactor 设置可学习参数的学习速率因子。
setl2factor. 设置一个可学习参数的L2正则化因子。
getLearnRateFactor 获取学习速率因子的学习参数。
getl2factor. 获取Legable参数的L2正则化因子。

要指定可学习参数的学习率因子和L2因子,请使用语法层= setLearnRateFactor(层、parameterName值)layer=setL2Factor(图层、参数名称、值)分别地

要得到一个可学习参数的学习率因子和L2因子的值,使用语法parameterName getLearnRateFactor(层)getl2factor(图层,parametername)分别。

例如,此语法使用名称设置可学习参数的学习速率因子“阿尔法”0.1

一层一层= setLearnRateFactor (,“阿尔法”,0.1);

状态参数

对于有状态层,例如循环层,在财产(州)类定义的部分。为dlnetwork.既有可学习参数又有状态参数的对象(例如dlnetwork.对象中包含LSTM层),则必须在属性(可学习、状态)部分如果图层没有状态参数,则可以忽略属性与之有关的部分状态属性

如果图层具有状态参数,则前向功能也必须返回更新的图层状态。有关更多信息,请参见前进功能

要指定自定义重置状态函数,请包括语法的函数层= resetState(层)在课堂定义中。有关更多信息,请参见重置状态函数

前进功能

有些层在训练和预测过程中表现不同。例如,dropout层只在训练期间执行dropout,在预测期间没有影响。一个层使用两个函数之一来执行向前传递:预测向前地.如果前进通过在预测时间,则该图层使用预测作用如果在训练时向前传球,则该层使用向前地函数。如果不需要两个不同的函数来表示预测时间和训练时间,则可以省略向前地函数。在本例中,层使用预测在训练时间。

如果图层具有状态参数,则转发函数还必须以数字数组的形式返回更新后的图层状态参数。

如果您同时定义了自定义向前地函数和自定义落后的函数,则forward函数必须返回内存输出

这个预测函数语法取决于层的类型。

  • Z =预测(层,X)转发输入数据X通过该层并输出结果Z, 在哪里只有一个输入,一个输出。

  • [Z,状态]=预测(层,X)也输出更新的状态参数状态, 在哪里只有一个状态参数。

您可以调整具有多个输入、多个输出或多个状态参数的层的语法:

  • 对于有多个输入的层,替换X具有x1,...,xn, 在哪里N是输入的数量。这个numinputs.属性必须匹配N

  • 对于有多个输出的层,替换Z具有Z1,…,ZM评选, 在哪里M是输出的数量。这个NumOutputs属性必须匹配M

  • 对于具有多个状态参数的层,替换状态具有state1,…,stateK, 在哪里K是状态参数的数目。

提示

如果到图层的输入数可以变化,则使用变长度输入宗量而不是X1,…,XN.在这种情况下,变长度输入宗量是输入的单元格数组,其中varargin {i}对应于xi.

如果输出的数量可能不同,则使用varargout而不是Z1,…,锌.在这种情况下,varargout是输出的单元阵列,其中varargout {j}对应于ZJ.

提示

如果自定义图层具有dlnetwork.对象的可学习参数,然后在预测自定义层的函数,使用预测函数dlnetwork..使用dlnetwork.对象预测功能确保软件使用正确的层操作进行预测。

这个向前地函数语法取决于图层的类型:

  • z =前进(图层,x)转发输入数据X通过该层并输出结果Z, 在哪里只有一个输入,一个输出。

  • [Z,状态]=正向(层,X)也输出更新的状态参数状态, 在哪里只有一个状态参数。

  • (__、内存)=(层,X)转发也返回自定义的内存值落后的函数使用任何前面的语法。如果层都有自定义向前地函数和自定义落后的函数,则forward函数必须返回一个内存值。

您可以调整具有多个输入、多个输出或多个状态参数的层的语法:

  • 对于有多个输入的层,替换X具有x1,...,xn, 在哪里N是输入的数量。这个numinputs.属性必须匹配N

  • 对于有多个输出的层,替换Z具有Z1,…,ZM评选, 在哪里M是输出的数量。这个NumOutputs属性必须匹配M

  • 对于具有多个状态参数的层,替换状态具有state1,…,stateK, 在哪里K是状态参数的数目。

提示

如果到图层的输入数可以变化,则使用变长度输入宗量而不是X1,…,XN.在这种情况下,变长度输入宗量是输入的单元格数组,其中varargin {i}对应于xi.

如果输出的数量可能不同,则使用varargout而不是Z1,…,锌.在这种情况下,varargout是输出的单元阵列,其中varargout {j}对应于ZJ.

提示

如果自定义图层具有dlnetwork.对象的可学习参数,然后在向前地自定义层的函数,使用向前地委员会的职能dlnetwork.对象。使用dlnetwork.对象向前地功能可确保软件使用正确的图层操作进行培训。

输入尺寸取决于数据类型和连接层的输出:

层的输入 输入大小 观察维度
特征向量 C-经过-N, 在哪里C对应于通道数和N是观察人数。 2.
二维图像 H-经过-W-经过-C-经过-N, 在哪里H,W,C分别对应图像的高度、宽度和通道数量,和N是观察人数。 4.
三维图像 H-经过-W-经过-D-经过-C-经过-N, 在哪里H,W,D,C分别为三维图像通道的高度、宽度、深度和数量N是观察人数。 5.
矢量序列 C-经过-N-经过-s, 在哪里C是序列的特征数,N是观察的次数,和s为序列长度。 2.
二维图像序列 H-经过-W-经过-C-经过-N-经过-s, 在哪里H,W,C对应于图像的频道的高度,宽度和数量,N是观察的次数,和s为序列长度。 4.
三维图像序列 H-经过-W-经过-D-经过-C-经过-N-经过-s, 在哪里H,W,D,C分别对应于三维图像的高度、宽度、深度和通道数,N是观察的次数,和s为序列长度。 5.

对于输出序列的层,层可以输出任意长度的序列或无时间维度的输出数据。在训练输出序列的网络时,请注意列车网络函数时,输入序列和输出序列的长度必须匹配。

自定义层转发函数的输出必须不复杂。如果预测向前地自定义层的功能涉及复杂的数字,在返回它们之前将所有输出转换为实际值。使用复杂数字预测向前地自定义图层的功能可能导致复杂的可学习参数。如果您使用的是自动微分(换句话说,您没有为自定义层编写反向函数),则在函数计算开始时将所有可学习的参数转换为实际值。这样做可以确保自动生成的反向函数的输出不复杂。

重置状态函数

什么时候DAGNetwork系列网络对象包含具有状态参数的图层,可以使用predictAndUpdateStateclassifyandupdateState.功能。您可以使用resetState函数。

这个resetState函数DAGNetwork,系列网络,dlnetwork.默认情况下,对象对带有状态参数的自定义层没有影响。的层行为定义resetState函数用于网络对象,定义可选层resetState在重置状态参数的图层定义中的功能。

这个resetState函数必须具有语法层= resetState(层),其中返回的层重置了状态属性。

后向函数

层向后函数计算损失相对于输入数据的导数,然后将结果输出(向后传播)到前一层。如果层有可学习的参数(例如,层权重),那么落后的还计算了学习参数的衍生产品。当使用列车网络函数时,该层在向后传递过程中使用这些导数自动更新可学习参数。

定义向后函数是可选的。如果不指定向后函数,则层向前函数支持万博1manbetxdlarray对象,然后软件使用自动微分自动确定向后函数。有关支持的函数的列表万博1manbetxdlarray对象,看到Dlarray支持的函数列表万博1manbetx.当你想:

  • 使用特定的算法来计算导数。

  • 使用转发功能中不支持的操作万博1manbetxdlarray物体。

自定义层与学习dlnetwork.对象不支持自定义后向功能。万博1manbetx

要定义自定义向后函数,请创建一个名为落后的

这个落后的函数语法取决于层的类型。

  • dLdX=向后(层、X、Z、dLdZ、内存)返回衍生品dLdX相对于层输入的损耗,其中只有一个输入和一个输出。Z对应forward函数输出和dLdZ对应于损失对的导数Z.函数的输入内存对应forward函数的内存输出。

  • [dLdX, dLdW] =向后(层,X, Z, dLdZ,内存)还返回衍生工具dLdW关于可学习参数的损失,其中只有一个可学习的参数。

  • [DLDX,DLDSIN] =向后(图层,x,z,dldz,dldsout,内存)还返回衍生工具dLdSin使用任何先前的语法计算与状态输入相关的损失,其中有一个状态参数和dLdSout对应于损耗相对于层状态输出的导数。

  • [dLdX,dLdW,dLdSin]=向后(层,X,Z,dLdZ,dLdSout,内存)还返回衍生工具dLdW对可学习参数的损失,并返回导数dLdSin使用任何先前的语法,与层状态输入有关的损失,其中具有单个状态参数和单个可学习参数。

您可以调整具有多个输入,多个输出,多种学习参数或多个状态参数的图层的语法:

  • 对于有多个输入的层,替换XdLdX具有x1,...,xndLdX1,…,dLdXN分别在哪里N为输入的个数。

  • 对于有多个输出的层,替换ZdLdZ具有Z1,…,ZM评选dldz1,...,dldzm分别在哪里M是输出的数量。

  • 对于具有多个可学习参数的层,替换dLdW具有dLdW1,…,dLdWP, 在哪里P为可学习参数的个数。

  • 对于具有多个状态参数的层,替换dLdSindLdSout具有dLdSin1,…,dLdSinKdLdSout1,…,dLdSoutK分别在哪里K是状态参数的数目。

为了防止在前向传递和后向传递之间保存未使用的变量,从而减少内存使用,可以将相应的输入参数替换为~

提示

如果输入的数量落后的可以改变,然后使用变长度输入宗量而不是后面的输入参数.在这种情况下,变长度输入宗量是输入的单元格数组,其中N元素对应于N层输入,下一个M元素对应于M图层输出,下一个M各要素对应于损失的衍生工具M图层输出,下一个K元素对应于K与资产相关的损失衍生工具K状态输出,最后一个元素对应于内存

如果输出的数量可能不同,则使用varargout而不是输出参数。在这种情况下,varargout是输出的单元格数组,其中第一个N元素对应于N损失的衍生品相对于N层输入,下一个P各要素对应于损失的衍生工具P可学习的参数,以及下一个K各要素对应于损失的衍生工具K状态输入。

价值观XZ与前进功能中的相同。尺寸dLdZ和的尺寸一样吗Z

的维度和数据类型dLdX与的维度和数据类型相同X.数据的维度和数据类型dLdW与的维度和数据类型相同W

要计算损失的导数,可以使用链式法则:

L X ( ) = J L Z J Z J X ( )

L W = J L Z J Z J W

当使用列车网络函数,图层使用衍生物自动更新可读参数dLdW在向后传球时。

有关如何定义自定义向后函数的示例,请参见指定自定义层向后函数

自定义图层反向功能的输出不得复杂。如果向后函数涉及复数,则在返回前将向后函数的所有输出转换为实数。

GPU兼容性

如果层向前函数完全支持万博1manbetxdlarray对象,则该层是GPU兼容的。否则,为了与GPU兼容,层函数必须支持输入和返回输出类型万博1manbetxgpuArray(并行计算工具箱)

许多MATLAB®内置函数支持万博1manbetxgpuArray(并行计算工具箱)dlarray输入参数。有关支持的功能列表万博1manbetxdlarray对象,看到Dlarray支持的函数列表万博1manbetx.有关在GPU上执行的函数列表,请参阅在GPU上运行MATLAB函数(并行计算工具箱)要使用GPU进行深度学习,您还必须拥有受支持的GPU设备。有关支持的设备的信息,请参阅万博1manbetxGPU通万博1manbetx过发布支持(并行计算工具箱)有关在MATLAB中使用gpu的更多信息,请参见MATLAB中的GPU计算(并行计算工具箱)

代码生成兼容性

要创建支持代码生成的自定义图层,请执行以下操作:万博1manbetx

  • 图层必须指定pragma% # codegen在图层定义中。

  • 的输入预测必须是:

    • 一致的维度。每个输入必须具有相同数量的维度。

    • 批量大小一致。每个输入必须具有相同的批大小。

  • 输出预测尺寸和批次大小必须与图层输入一致。

  • 非标量属性的类型必须为single、double或character数组。

  • 标量属性必须具有数字、逻辑或字符串类型。

代码生成只支持带有二维图像或特征万博1manbetx输入的中间层。代码生成不支持带有状态属性的层(属性带属性)万博1manbetx状态).

有关如何创建支持代码生成的自定义层的示例,请参见万博1manbetx定义用于代码生成的自定义深度学习层

网络构成

要创建自定义图层,它本身定义了图层图,可以声明一个dlnetwork.对象作为属性(可学的)层定义的部分。这种方法被称为网络的作文.你可以使用网络合成:

  • 创建表示可学习层块的单个自定义层,例如,剩余块。

  • 创建具有控制流的网络,例如,具有可以根据输入数据动态地改变的部分的网络。

  • 创建一个带有循环的网络,例如,一个带有将输出反馈回自身的部分的网络。

对于具有学习和状态参数的嵌套网络,例如,具有批量归一化或LSTM层的网络,请在其中声明网络属性(可学习、状态)层定义的部分。

GPU兼容性

如果层向前函数完全支持万博1manbetxdlarray对象,则该层是GPU兼容的。否则,为了与GPU兼容,层函数必须支持输入和返回输出类型万博1manbetxgpuArray(并行计算工具箱)

许多MATLAB内置函数支持万博1manbetxgpuArray(并行计算工具箱)dlarray输入参数。有关支持的功能列表万博1manbetxdlarray对象,看到Dlarray支持的函数列表万博1manbetx.有关在GPU上执行的函数列表,请参阅在GPU上运行MATLAB函数(并行计算工具箱)要使用GPU进行深度学习,您还必须拥有受支持的GPU设备。有关支持的设备的信息,请参阅万博1manbetxGPU通万博1manbetx过发布支持(并行计算工具箱)有关在MATLAB中使用gpu的更多信息,请参见MATLAB中的GPU计算(并行计算工具箱)

层有效性检查

如果你创建一个自定义的深度学习层,那么你可以使用检查层函数检查该层是否有效。该函数检查层的有效性、GPU兼容性、正确定义的梯度和代码生成兼容性。检查层是否有效,使用如下命令:

checkLayer(层,validInputSize)
在哪里是该层的实例,有效输入大小指定层的有效输入大小的向量或单元格数组。要用多重观察进行检查,请使用观察层选项。要检查代码生成兼容性,请设置CheckCodegenCompatibility选项1.(对)。对于较大的输入大小,渐变检查运行时间较长。要加快测试速度,请指定较小的有效输入大小。

有关更多信息,请参见检查自定义图层的有效性

检查自定义层的有效性检查层

检查自定义层的层有效性preluLayer

自定义图层preluLayer,作为支持文件附于此示例,将PReLU操作应用于输入数据。要访问此层,万博1manbetx请将此示例作为实时脚本打开。

创建图层的实例,并使用检查层.将有效输入大小指定为对层的典型输入的单个观察的大小。该层需要4-D阵列输入,其中前三个维度对应于前一层输出的高度、宽度和通道数量,第四个维度对应于观测值。

指定观察输入的典型大小并设置观察层选项4。

层=预铺层(20);validInputSize=[24 20];检查层(层,有效输入大小,观测维度=4)
跳过GPU测试。没有找到兼容的GPU设备。跳过代码生成兼容性测试。要检查代码生成层的有效性,请指定“CheckCodegenCompatibility”和“ObservationDimension”选项。运行nnet.checklayer.TestLayerWithoutBackward .......... ........完成net.checklayer. testlayerwithoutbackward __________测试摘要:18通过,0失败,0不完整,10跳过。时间:1.9312秒。

在这里,函数不会检测到层的任何问题。

另见

|||||||||

相关的话题