如果深度学习工具箱™不提供您的分类或回归问题所需的层,那么您可以使用本示例作为指南定义自己的自定义层。有关内置层的列表,请参见深度学习层列表.
要定义一个自定义的深度学习层,你可以使用本例中提供的模板,它将带你通过以下步骤:
命名层-给层一个名字,这样你就可以在MATLAB中使用它®.
声明层属性-指定层的属性和哪些参数是在训练中学习的。
创建构造函数(可选)-指定如何构造层和初始化它的属性。如果没有指定构造函数,则在创建时,软件将初始化的名字
,描述
,类型
属性与[]
并设置层输入和输出的数量为1。
创建前向函数——指定数据在预测时间和训练时间如何通过层(前向传播)。
创建向后函数(可选)—指定损失相对于输入数据和可学习参数的导数(向后传播)。如果不指定向后函数,则向前函数必须支持万博1manbetxdlarray
对象。
要创建一个支持代码生成的自定义层:万博1manbetx
层必须指定pragma% # codegen
在层定义中。
的输入预测
必须:
一致的维度。每个输入必须具有相同数量的维度。
批量大小一致。每个输入必须具有相同的批大小。
的输出预测
尺寸和批大小必须与层输入一致。
非标量属性必须具有单、双或字符数组类型。
标量属性必须具有数字、逻辑或字符串类型。
代码生成只支持带有二维图像输入的万博1manbetx中间层。
这个例子展示了如何创建一个PReLU层[1],这是一个具有可学习参数的层,并将其用于卷积神经网络。PReLU层执行一个阈值操作,其中对于每个通道,任何小于零的输入值乘以训练时学到的标量。对于小于零的值,PReLU层应用缩放系数 每个输入通道。这些系数形成了一个可学习的参数,该参数在训练过程中被层学习。
这图[1]比较ReLU和PReLU层函数。
复制层与可学习的参数模板到一个新的文件在MATLAB。此模板概述了具有可学习参数的层的结构,并包括定义层行为的函数。
classdefmyLayer < nnet.layer.Layer% & net.layer. format(可选)属性%(可选)图层属性。%图层属性到这里。结束属性(可学的)%(可选)层可学习参数。%图层学习参数到这里。结束方法函数层= myLayer ()%(可选)创建一个myLayer。%该函数必须与类名相同。%层构造函数在这里。结束函数[Z1,…,Zm] = predict(layer, X1,…,Xn)%在预测时间通过层转发输入数据%输出结果。%%的输入:% layer -要转发的层% X1,…,Xn- Input data%输出:% Z1,…,Z米- Outputs of layer forward function%用于预测的层前向函数在这里。结束函数(Z1,…,Zm评选、内存)=前进(层,X1,…,Xn)%(可选)在训练时通过层转发输入数据%时间并输出结果和一个内存值。%%的输入:% layer -要转发的层% X1,…,Xn- Input data%输出:% Z1,…,Z米- Outputs of layer forward function% memory -自定义向后传播的内存值%用于训练的图层正向功能在这里。结束函数[dLdX1,…,dLdXn, dLdW1,…,dLdWk] =...向后(层,X1,…,Xn Z1,…,Zm评选,dLdZ1,…,dLdZm,内存)%(可选)反向传播损失的导数%函数通过层。%%的输入:%图层-图层向后传播通过% X1,…,Xn- Input data% Z1,…,Z米- Outputs of layer forward function% dLdZ1,…,dLdZm - Gradients propagated from the next layers% memory - forward函数的内存值%输出:% dLdX1,…,dLdXn - Derivatives of the loss with respect to the%的输入% dLdW1,…,dLdWk - Derivatives of the loss with respect to each%可学的参数%图层向后函数在这里。结束结束结束
首先,给图层命名。在类文件的第一行中,替换现有的名称myLayer
与codegenPreluLayer
并添加一个注释来描述这个层。
classdefcodegenPreluLayer < nnet.layer.Layer%示例自定义PReLU层与代码生成支持。万博1manbetx...结束
接下来,重命名myLayer
函数中的第一个函数方法
Section),以便它与图层具有相同的名称。
方法函数layer = codegenPreluLayer()…结束...结束
将层类文件保存在一个名为codegenPreluLayer.m
.文件名必须与层名匹配。要使用该层,必须将文件保存在当前文件夹或MATLAB路径上的文件夹中。
添加% # codegen
指令(或pragma)到层定义,以指示您打算为该层生成代码。添加此指令将指示MATLAB代码分析器帮助您诊断和修复在代码生成期间导致错误的违规。
classdefcodegenPreluLayer < nnet.layer.Layer%示例自定义PReLU层与代码生成支持。万博1manbetx% # codegen...结束
属性中声明图层属性属性
节中列出可学习参数并声明它们属性(可学的)
部分。
默认情况下,自定义中间层有这些属性。
财产 | 描述 |
---|---|
的名字 |
层名,指定为字符向量或字符串标量。若要在层图中包含层,必须指定非空的唯一层名。如果你用层和的名字 被设置为'' ,然后软件在训练时自动为该层分配一个名称。 |
描述 |
层的一行描述,指定为字符向量或字符串标量。该描述出现在层显示在 |
类型 |
层的类型,指定为字符向量或字符串标量。的价值类型 当层显示在层 数组中。如果不指定层类型,则软件将显示层类名称。 |
NumInputs |
层的输入数,指定为正整数。如果您不指定此值,则软件将自动设置NumInputs 到名字的数量InputNames .默认值为1。 |
InputNames |
输入图层名称,指定为字符向量单元格数组。如果不指定该值和NumInputs 大于1,则软件自动设置InputNames 来{“三机”,…,“客栈”} ,在那里N 等于NumInputs .默认值为{'在'} . |
NumOutputs |
层的输出数,指定为正整数。如果您不指定此值,则软件将自动设置NumOutputs 到名字的数量OutputNames .默认值为1。 |
OutputNames |
层的输出名称,指定为字符向量的单元格数组。如果不指定该值和NumOutputs 大于1,则软件自动设置OutputNames 来{着干活,…,“outM”} ,在那里米 等于NumOutputs .默认值为{“出”} . |
如果该层没有其他属性,则可以省略属性
部分。
提示
如果你正在创建一个有多个输入的图层,那么你必须设置NumInputs
或InputNames
属性在层构造函数中。如果你正在创建一个有多个输出的图层,那么你必须设置NumOutputs
或OutputNames
属性在层构造函数中。例如,请参见定义自定义深度学习层与多个输入.
要支持万博1manbetx代码生成:
非标量属性必须具有单、双或字符数组类型。
标量属性必须为数字或具有逻辑或字符串类型。
PReLU层不需要任何额外的属性,所以您可以删除属性
部分。
PReLU层只有一个可学习的参数,缩放系数一个.属性中声明这个可学习参数属性(可学的)
分段并调用参数α
.
属性(可学的)%层可学习的参数%比例系数α结束
创建构造层和初始化层属性的函数。指定创建层所需的任何变量作为构造函数的输入。
PReLU层构造函数需要两个输入参数:预期输入数据的通道数量和层名。通道的数量指定了可学习参数的大小α
.指定两个命名的输入参数numChannels
和的名字
在codegenPreluLayer
函数。在函数的顶部添加注释,解释函数的语法。
函数layer = codegenPreluLayer(numChannels, name)% layer = codegenPreluLayer(numChannels)创建一个PReLU层% numChannels通道并指定层名。...结束
不支持代码生成万博1manbetx参数
块。
在构造函数中初始化层属性,包括可学习的参数。取代的评论%层构造函数在这里
使用初始化层属性的代码。
设置的名字
属性设置为输入参数的名字
.
%设置图层名称。层。的名字=的名字;
给层一个单行描述通过设置描述
属性的层。将描述设置为描述图层的类型和大小。
%设置图层描述。层。描述=“PReLU与“+ numChannels +“通道”;
对于PReLU层,当输入值为负时,该层将输入的每个通道乘以对应的通道α
.初始化可学习参数α
作为大小为1 × 1 × -的随机向量numChannels
.第三个维度指定为尺寸numChannels
,层可以使用前向函数中输入的元素乘。α
是图层对象的属性,所以你必须将矢量赋给层。α
.
%初始化缩放系数。层。α=rand([1 1 numChannels]);
查看已完成的构造函数。
函数layer = codegenPreluLayer(numChannels, name)% layer = codegenPreluLayer(numChannels, name)创建一个PReLU% layer用于使用numChannels通道和指定的2-D图像输入%层名。%设置图层名称。层。的名字=的名字;%设置图层描述。层。描述=“PReLU与“+ numChannels +“通道”;%初始化缩放系数。层。α=rand([1 1 numChannels]);结束
使用这个构造函数,命令codegenPreluLayer(“prelu”)
创建一个带有三个通道和名称的PReLU层“prelu”
.
创建用于预测时间和训练时间的层前向函数。
创建一个名为预测
将数据向前传播到预测的时间并输出结果。
的语法预测
是(Z1,…,Zm评选)=预测(层,X1,…,Xn)
,在那里X1,…,Xn
是n
层的输入和Z1,…,Zm评选
是米
层输出。的值n
和米
必须对应于NumInputs
和NumOutputs
层的属性。
提示
如果输入的数量预测
可以变化,然后使用变长度输入宗量
而不是X1,…,Xn
.在这种情况下,变长度输入宗量
输入的单元格数组在哪里变长度输入宗量{我}
对应于西
.如果输出的数量可以变化,则使用varargout
而不是Z1,…,Zm评选
.在这种情况下,varargout
输出的单元格数组在哪里varargout {j}
对应于Zj
.
因为PReLU层只有一个输入和一个输出,for的语法预测
对于PReLU层是Z =预测(层,X)
.
代码生成只支持2-D图像输入的自万博1manbetx定义中间层。的输入是h——- - - - - -w——- - - - - -c——- - - - - -N数组,h,w,c分别对应图像的高度、宽度和通道数量,和N为观察次数。观察维度为4。
对于代码生成支持,所有层输入必须具有相同万博1manbetx的维数和批大小。
默认情况下,该层使用预测
作为训练时的正向函数。要在训练时使用不同的前向函数,或保留自定义后向函数所需的值,还必须创建名为向前
.该软件不生成代码向前
函数,但必须与代码生成兼容。
的向前
函数将数据向前传播到层培训时间并输出一个内存值。
的语法向前
是(Z1,…,Zm评选、内存)=前进(层,X1,…,Xn)
,在那里X1,…,Xn
是n
层的输入,Z1,…,Zm评选
是米
层的输出,内存
是记忆层。
提示
如果输入的数量向前
可以变化,然后使用变长度输入宗量
而不是X1,…,Xn
.在这种情况下,变长度输入宗量
输入的单元格数组在哪里变长度输入宗量{我}
对应于西
.如果输出的数量可以变化,则使用varargout
而不是Z1,…,Zm评选
.在这种情况下,varargout
输出的单元格数组在哪里varargout {j}
对应于Zj
为j
= 1,…,NumOutputs
和varargout {NumOutputs + 1}
对应于内存
.
PReLU运算由
在哪里 是非线性激活的输入吗f频道我, 是控制负部分斜率的系数。下标我在 表示非线性激活可以在不同的通道上变化。
在预测
.在预测
,输入X
对应于x在方程。输出Z
对应于
.
在函数的顶部添加注释,解释函数的语法。
提示
如果使用函数预分配数组,例如0
,则必须确保这些数组的数据类型与层函数输入一致。要创建与另一个数组具有相同数据类型的零数组,请使用“喜欢”
选择0
.例如,初始化一个大小为零的数组深圳
使用与数组相同的数据类型X
,使用Z = 0(深圳,“喜欢”,X)
.
实现落后的
当forward函数完全支持时,函数是可选的万博1manbetxdlarray
输入。对于代码生成支持,万博1manbetx预测
函数还必须支持数字输入。万博1manbetx
计算PReLU操作的输出的一种方法是使用以下代码。
Z = max(X,0) +图层。α。*分钟(0,X);
.*
操作时,可以使用bsxfun
函数来代替。Z = max(X,0) + bsxfun(@times,图层。α,最小值(0,X));
bsxfun
不支持万博1manbetxdlarray
输入。来实现预测
函数,它支持代码生成和万博1manbetxdlarray
输入,使用一个如果
声明的isdlarray
函数选择输入类型的适当代码。
函数Z =预测(层,X)% Z = predict(layer, X)将输入数据X通过%层并输出结果Z。如果isdlarray(X) Z = max(X,0) + layer。α。*分钟(0,X);其他的Z = max(X,0) + bsxfun(@times,图层。α,最小值(0,X));结束结束
因为预测
功能完全支持万博1manbetxdlarray
对象,定义落后的
函数是可选的。获取支持的函数列表万博1manbetxdlarray
对象,看到支持dlarray的函数列表万博1manbetx.
查看已完成的层类文件。
classdefcodegenPreluLayer < nnet.layer.Layer%示例自定义PReLU层与代码生成支持。万博1manbetx% # codegen属性(可学的)%层可学习的参数%比例系数α结束方法函数layer = codegenPreluLayer(numChannels, name)% layer = codegenPreluLayer(numChannels, name)创建一个PReLU% layer用于使用numChannels通道和指定的2-D图像输入%层名。%设置图层名称。层。的名字=的名字;%设置图层描述。层。描述=“PReLU与“+ numChannels +“通道”;%初始化缩放系数。层。α=rand([1 1 numChannels]);结束函数Z =预测(层,X)% Z = predict(layer, X)将输入数据X通过%层并输出结果Z。如果isdlarray(X) Z = max(X,0) + layer。α。*分钟(0,X);其他的Z = max(X,0) + bsxfun(@times,图层。α,最小值(0,X));结束结束结束结束
检查自定义层的代码生成兼容性codegenPreluLayer
.
定义一个具有代码生成支持的自定义PReLU层。万博1manbetx要创建这个图层,保存文件codegenPreluLayer.m
在当前文件夹中。
创建该层的实例并使用checkLayer
.指定有效的输入大小作为对层的典型输入的单个观察的大小。该层需要4-D阵列输入,其中前三个维度对应于前一层输出的高度、宽度和通道数量,第四个维度对应于观测值。
指定观察输入的典型大小,并设置“ObservationDimension”
选项4。要检查代码生成兼容性,请设置“CheckCodegenCompatibility”
选项真正的
.
层= codegenPreluLayer (20,“prelu”);validInputSize = [24 24 20];validInputSize checkLayer(层,“ObservationDimension”4“CheckCodegenCompatibility”,真正的)
跳过GPU测试。没有找到兼容的GPU设备。运行nnet.checklayer.TestLayerWithoutBackward .......... ........完成nnet.checklayer.TestLayerWithoutBackward __________测试摘要:18通过,0失败,0不完整,4跳过。时间:0.77122秒。
该函数不检测层的任何问题。
[1] "深入研究整流器:在图像网分类上超越人类水平的表现"2015 IEEE计算机视觉国际会议(ICCV)1026 - 34。智利圣地亚哥:IEEE, 2015。https://doi.org/10.1109/ICCV.2015.123。