主要内容

定义定制的深度学习层代码生成

如果深入学习工具箱™不提供层你需要为你的分类或回归问题,那么您可以定义自己的自定义层使用这个例子作为参考。一个内置的图层列表,看到深度学习层的列表

定义一个自定义的深度学习层,您可以使用提供的模板在这个例子中,需要通过以下步骤:

  1. 名字一层一层——给一个名称,这样您就可以在MATLAB中使用它®

  2. 声明层属性指定图层的属性,包括可学的参数和状态参数。

  3. 创建一个构造函数(可选)——指定层如何构造和初始化它的属性。如果你不指定一个构造函数,那么在创建、软件初始化的名字,描述,类型属性与[]并设置输入和输出层的数量为1。

  4. 创建初始化函数(可选)——指定如何初始化可学的,当软件初始化网络状态参数。如果你不指定一个初始化函数,那么这个软件不初始化参数初始化网络。

  5. 创建向前函数——指定数据传递通过层(向前传播)在预测时间和培训时间。

  6. 创建重置状态函数(可选)——指定如何重置状态参数。

  7. 创建一个反向功能(可选)——指定的衍生品损失对输入数据和可学的参数(向后传播)。如果你不指定一个落后的函数,那么远期功能必须支持金宝appdlarray对象。

要创建一个自定义层支持代码生成:金宝app

  • 层必须指定编译指示% # codegen层定义。

  • 的输入预测必须:

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

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

  • 的输出预测必须是一致的维度和批量大小的输入层。

  • Nonscalar属性必须有类型单一、双或字符数组。

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

代码生成与二维图像或特征输入支持金宝app过渡层。代码生成与国家不支持层属性(属性与属性金宝app状态)。

这个例子展示了如何创建一个PReLU层[1],这是一层可学的参数,并使用它在一个卷积神经网络。PReLU层执行一个阈值操作,为每个通道,任何输入值小于零乘以一个标量学习训练时间。值小于零,PReLU层应用缩放系数 α 每个通道的输入。这些系数形式可学的参数,这层在训练学习。

这图[1]比较了ReLU和PReLU层功能。

并排的情节ReLU和PReLU激活功能。y的值大于零,两个函数线性。y的值小于零,ReLU函数返回0和PReLU函数尺度线性缩放系数。

过渡层模板

中间一层模板复制到一个新文件在MATLAB。这个模板提供了一个中间的结构层类定义。概述:

  • 可选属性块层属性,可学的参数和状态参数。

  • 层构造函数。

  • 可选初始化函数。

  • 预测功能和可选的向前函数。

  • 可选resetState功能层与国家性质。

  • 可选落后的函数。

classdefmyLayer < nnet.layer.Layer%……% & nnet.layer。为mattable ... % (Optional)% & nnet.layer。Acceleratable %(可选)属性%(可选)层属性。%声明层属性。结束属性(可学的)%(可选)层可学的参数。%这里声明可学的参数。结束属性(状态)%(可选)层状态参数。%申报状态参数。结束属性(可学的,状态)%(可选)嵌套dlnetwork对象都可学的%参数和状态参数。%声明嵌套网络可学的和状态参数。结束方法函数层= myLayer ()%(可选)创建一个myLayer。%这个函数必须具有相同的名称作为类。%定义层构造器函数。结束函数层=初始化(层、布局)%(可选)初始化层可学的和状态参数。%%的输入:%初始化层-层%布局-数据布局,指定为一个networkDataLayout%的对象%%输出:%层-层初始化%%,与多个输入层,取代布局% layout1,…,layoutN, where N is the number of inputs.%定义层的初始化函数。结束函数[Z,状态]=预测(层,X)%前进通过层预测时间和输入数据%输出结果和状态更新。%%的输入:%层-层向前传播% X -输入数据%输出:% Z -输出层的功能%——(可选)更新层状态%%,与多个输入层,取代X X1,…, XN,% N是输入的数量。%,与多个输出层,取代Z% Z1,…,Z米,在那里米我s the number of outputs.%——层具有多个状态参数,更换状态% state1,…,状态K,在那里K我s the number of state%的参数。%定义层预测函数。结束函数向前(Z、状态、内存)=(层,X)%(可选)正向输入数据通过层培训%的时间和输出结果,更新后的状态,和记忆%值。%%的输入:%层-层向前传播% X -层输入数据%输出:% Z -输出层的功能%——(可选)更新层状态%的记忆——自定义(可选的)内存值落后%的功能%%,与多个输入层,取代X X1,…, XN,% N是输入的数量。%,与多个输出层,取代Z% Z1,…,Z米,在那里米我s the number of outputs.%——层具有多个状态参数,更换状态% state1,…,状态K,在那里K我s the number of state%的参数。%定义层函数。结束函数层= resetState(层)%(可选)设置层的状态。%定义重置状态函数。结束函数[dLdX, dLdW dLdSin] =向后(层,X, Z, dLdZ dLdSout,内存)%(可选)向后传播损失的导数%通过层功能。%%的输入:%层-层反向传播% X -层输入数据% Z -层输出数据% dLdZ -导数的损失对层%输出% dLdSout——(可选)损失的导数%状态输出%的记忆——记忆值函数%输出:% dLdX -导数的损失对输入层% dLdW——(可选)的导数对损失%可学的参数% dLdSin——(可选)的导数对损失%状态输入%%——层与状态参数,必须向后语法%包括dLdSout和dLdSin,或没有。%,与多个输入层,X和dLdX替换% X1,…,XN和dLdX1,...,dLdXN, respectively, where N is%的数量输入。%,与多个输出层,Z和dlZ替换% Z1,…,Z米和dLdZ,...,dLdZM, respectively, where M is the%的输出。%——层具有多个可学的参数,替换%与dLdW1 dLdW,…,dLdWP, where P is the number of%可学的参数。%——层具有多个状态参数,取代dLdSin%和dLdSout dLdSin1,……、dLdSinK和% dLdSout1,…,dldSoutK, respectively, where K is the number%的状态参数。%定义层向后函数。结束结束结束

名字层和指定父类

首先,为层指定一个名称。在第一行的类文件,替换现有的名字myLayercodegenPreluLayer描述层和添加评论。

classdefcodegenPreluLayer < nnet.layer.Layer& nnet.layer.Formattable%示例自定义PReLU层codegen支持。金宝app结束

如果你不指定一个落后的函数,那么层函数,默认情况下,接收无格式dlarray对象作为输入。指定层接收到格式化dlarray对象作为输入和输出格式dlarray对象,也继承了nnet.layer.Formattable类在定义自定义层。

层不需要formattable输入,所以删除可选nnet.layer.Formattable超类。

classdefcodegenPreluLayer < nnet.layer.Layer%示例自定义PReLU层codegen支持。金宝app结束

接下来,重命名myLayer构造函数(第一个函数方法部分),具有相同的名称作为层。

方法函数层= codegenPreluLayer ()……结束结束

保存层

层类文件保存在一个新文件命名codegenPreluLayer.m。文件名称必须匹配层名称。使用层,必须保存文件在当前文件夹或文件夹在MATLAB的道路。

指定代码生成编译指示

添加% # codegen指令(或编译指示)图层定义表明你打算为这一层生成代码。添加这个指令指示MATLAB代码分析器来帮助您诊断和解决侵犯,导致错误在代码生成。

classdefcodegenPreluLayer < nnet.layer.Layer%示例自定义PReLU层codegen支持。金宝app% # codegen结束

声明属性和可学的参数

声明的层属性属性部分,清单中声明可学的参数属性(可学的)部分。

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

财产 描述
的名字 图层名称,指定为一个特征向量或字符串标量。为数组输入,trainNetwork,assembleNetwork,layerGraph,dlnetwork函数自动分配名称层的名称
描述

一行的描述层,指定为字符串标量或特征向量。这个描述层显示在一个时出现数组中。

如果你不指定层的描述,然后软件显示层的类名。

类型

层的类型,指定为一个特征向量或字符串标量。的价值类型当层显示在一个出现数组中。

如果你不指定层类型,那么软件显示层的类名。

NumInputs 输入层的数量,指定为一个正整数。如果不指定这个值,则软件自动设置NumInputs人名的数目InputNames。默认值是1。
InputNames 输入层的名称,指定为一个单元阵列的特征向量。如果不指定这个值NumInputs大于1,那么软件自动设置InputNames{“三机”,…,“客栈”},在那里N等于NumInputs。默认值是{'在'}
NumOutputs 输出层的数量,指定为一个正整数。如果不指定这个值,则软件自动设置NumOutputs人名的数目OutputNames。默认值是1。
OutputNames 输出层的名称,指定为一个单元阵列的特征向量。如果不指定这个值NumOutputs大于1,那么软件自动设置OutputNames{着干活,…,“outM”},在那里等于NumOutputs。默认值是{“出”}

如果层没有其他属性,那么您可以省略的属性部分。

提示

如果你创建一个与多个输入层,然后你必须设置NumInputsInputNames属性层构造函数。如果你创建一个和多个输出层,然后你必须设置NumOutputsOutputNames属性层构造函数。例如,看到的定义定制的深度学习与多个输入层

支持代金宝app码生成:

  • Nonscalar属性必须有类型单一、双或字符数组。

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

PReLU层不需要任何额外的属性,所以你可以删除属性部分。

PReLU层只有一个可学的参数,比例系数一个。宣布这可学的参数属性(可学的)节和调用参数α

属性(可学的)%层可学的参数%比例系数α结束

创建构造函数

创建的函数结构层和初始化层属性。指定任何变量需要创建构造函数作为输入层。

PReLU层构造函数需要两个输入参数:渠道的数量预期的输入数据和图层名称。渠道指定的数量的大小可学的参数α。指定两个输入参数命名numChannels的名字codegenPreluLayer函数。添加一个评论的函数,函数的语法解释道。

函数层= codegenPreluLayer (numChannels、名称)% = codegenPreluLayer层(numChannels)创建一个PReLU层% numChannels渠道和指定图层名称。结束

代码生成不支持金宝app参数块。

初始化层属性

初始化图层属性,包括可学的参数,构造函数。取代的评论%层构造函数初始化的代码层属性。

设置的名字属性输入参数的名字

%设置图层名称。层。的名字=的名字;

通过设置给图层一行描述描述层的属性。设置描述描述层的类型和它的大小。

%设置层描述。层。描述=“PReLU与“+ numChannels +“通道”;

PReLU层,输入值为负时,层乘以每个通道的输入相应的渠道α。初始化可学的参数α作为一个随机向量的大小1-by-1-by -numChannels。与指定的三维尺寸numChannels,层可以使用element-wise乘法输入的函数。α层对象的一个属性,所以你必须分配向量layer.Alpha

%初始化比例系数。layer.Alpha=rand([1 1 numChannels]);

把构造函数完成。

函数层= codegenPreluLayer (numChannels、名称)% = codegenPreluLayer层创建一个PReLU (numChannels、名称)%层二维图像输入与numChannels渠道和指定%图层名称。%设置图层名称。层。的名字=的名字;%设置层描述。层。描述=“PReLU与“+ numChannels +“通道”;%初始化比例系数。layer.Alpha=rand([1 1 numChannels]);结束

使用此构造函数,该命令codegenPreluLayer (“prelu”)创建一个PReLU层有三个渠道和名称“prelu”

创建向前函数

在预测创建层转发功能使用时间和培训时间。

创建一个函数命名预测通过层传播数据的转发预测的时间并输出结果。

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

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

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

你可以调整层的语法与多个输入,多个输出,或多个状态参数:

  • 与多个输入层,取代XX1,…, XN,在那里N输入的数量。的NumInputs属性必须匹配N

  • 与多个输出层,取代ZZ1,…, ZM评选,在那里是输出的数量。的NumOutputs属性必须匹配

  • 层具有多个状态参数,替换状态state1,…, stateK,在那里K是状态参数的数量。

提示

如果输入层可以不同的数量,然后使用变长度输入宗量而不是X1,…, XN。在这种情况下,变长度输入宗量是一个单元阵列的输入,在哪里变长度输入宗量{我}对应于

如果输出的数量可以改变,那么使用varargout而不是Z1、…、锌。在这种情况下,varargout是一个单元阵列的输出,在哪里varargout {j}对应于Zj

因为PReLU层只有一个输入和一个输出的语法预测PReLU层Z =预测(层,X)

与二维图像输入代码生成支持定制的金宝app中间层次。的输入是h——- - - - - -w——- - - - - -c——- - - - - -N数组,h,w,c对应的高度、宽度和通道的图像,分别N是观测的数量。观察维度是4。

对于代码生成的支持,所有层的输入必须有相金宝app同数量的维度和批量大小。

默认情况下,该层使用预测函数在训练时间。使用不同的函数在训练时间,或保留值所需的向后一个自定义函数,您还必须创建一个函数命名向前。软件不生成代码向前但它必须生成代码兼容的函数。

向前通过层功能传播数据转发培训时间同时输出一个内存值。

向前函数的语法取决于类型的层:

  • Z =前进(层,X)将输入数据转发X通过层和输出结果Z,在那里只有一个输入和一个输出。

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

  • (__、内存)=(层,X)转发也为一个自定义的内存返回一个值落后的函数使用任何以前的语法。如果层有一个定制的向前功能和自定义落后的函数,那么这个函数必须返回一个内存值。

你可以调整层的语法与多个输入,多个输出,或多个状态参数:

  • 与多个输入层,取代XX1,…, XN,在那里N输入的数量。的NumInputs属性必须匹配N

  • 与多个输出层,取代ZZ1,…, ZM评选,在那里是输出的数量。的NumOutputs属性必须匹配

  • 层具有多个状态参数,替换状态state1,…, stateK,在那里K是状态参数的数量。

提示

如果输入层可以不同的数量,然后使用变长度输入宗量而不是X1,…, XN。在这种情况下,变长度输入宗量是一个单元阵列的输入,在哪里变长度输入宗量{我}对应于

如果输出的数量可以改变,那么使用varargout而不是Z1、…、锌。在这种情况下,varargout是一个单元阵列的输出,在哪里varargout {j}对应于Zj

PReLU操作是由

f ( x ) = { x 如果 x > 0 α x 如果 x 0

在哪里 x 是输入的非线性激活吗f频道, α 是负的斜率系数控制的部分。下标 α 表明,非线性激活不同在不同的频道。

实现这个操作预测。在预测,输入X对应于x在方程。输出Z对应于 f ( x )

添加一个评论的函数,函数的语法解释道。

提示

如果你preallocate数组使用等功能0,那么你必须确保这些数组的数据类型是一致的输入层功能。创建一个数组相同数据类型的零作为另一个数组,使用“喜欢”选择0。例如,初始化一个数组大小的0深圳具有相同数据类型的数组X,使用Z = 0(深圳,“喜欢”,X)

实现落后的当远期功能完全支持功能是可选的金宝appdlarray输入。对于代码生成支持,金宝app预测函数也必须支持数字输入。金宝app

一种方法计算出的输出PReLU操作是使用下面的代码。

Z = max (X, 0) +层。α。*分钟(0,X);
因为通过代码生成不支持隐式的扩张金宝app。*操作,您可以使用bsxfun函数来代替。
Z = max (X, 0) + bsxfun (@times层。α,最小值(0,X));
然而,bsxfun不支持金宝appdlarray输入。来实现预测函数,它同时支持代码生成和金宝appdlarray输入,使用一个如果声明的isdlarray函数来选择适当的类型的输入的代码。

函数Z =预测(层,X)% Z =预测(层,X)将输入数据转发X通过% Z层和输出结果。如果isdlarray (X) Z = max (X, 0) +层。α。*分钟(0,X);其他的Z = max (X, 0) + bsxfun (@times层。α,最小值(0,X));结束结束

因为预测功能完全支持金宝appdlarray对象,定义落后的函数是可选的。支持的功能列表金宝appdlarray对象,看到与dlarray支持函数的列表金宝app

完成一层

视图层完成类文件。

classdefcodegenPreluLayer < nnet.layer.Layer%示例自定义PReLU层codegen支持。金宝app% # codegen属性(可学的)%层可学的参数%比例系数α结束方法函数层= codegenPreluLayer (numChannels、名称)% = codegenPreluLayer层创建一个PReLU (numChannels、名称)%层二维图像输入与numChannels渠道和指定%图层名称。%设置图层名称。层。的名字=的名字;%设置层描述。层。描述=“PReLU与“+ numChannels +“通道”;%初始化比例系数。layer.Alpha=rand([1 1 numChannels]);结束函数Z =预测(层,X)% Z =预测(层,X)将输入数据转发X通过% Z层和输出结果。如果isdlarray (X) Z = max (X, 0) +层。α。*分钟(0,X);其他的Z = max (X, 0) + bsxfun (@times层。α,最小值(0,X));结束结束结束结束

检查自定义层的代码生成的兼容性

检查自定义的代码生成兼容层codegenPreluLayer

自定义图层codegenPreluLayer,附加到这个例子作为支持文件,PReLU操作适用于输入数据。金宝app进入这一层,打开这个例子作为一个活的脚本。

创建一个实例层的使用和检查它的有效性checkLayer。指定大小的有效输入大小一个观察典型的输入层。预计4 - d数组输入层,前三个维度对应高度,宽度,和前面的通道数层输出,和第四维对应于观测。

指定一个观察的典型输入的大小和设置“ObservationDimension”选项4。检查代码生成兼容性,设置CheckCodegenCompatibility选项真正的。的checkLayer函数不检查功能不兼容的代码生成。检查自定义层定义支持代码生成,第一次使用金宝app代码生成准备应用。更多信息,请参阅检查代码通过使用代码生成工具(MATLAB编码器)

层= codegenPreluLayer (20,“prelu”);validInputSize =(24日24日20);checkLayer(层、validInputSize ObservationDimension = 4, CheckCodegenCompatibility = true)
跳过GPU测试。不兼容的GPU设备发现。nnet.checklayer运行。TestLayerWithoutBackward .......... ..........……nnet.checklayer完成。TestLayerWithoutBackward __________测试总结:23日通过,5 0失败,0不完整,跳过。时间:0.67454秒。

层的功能没有发现任何问题。

引用

[1]“深深入整流器:超越人类表现ImageNet分类。”2015年IEEE计算机视觉国际会议(ICCV)1026 - 34。圣地亚哥,智利:IEEE 2015。https://doi.org/10.1109/ICCV.2015.123。

另请参阅

|||||||||

相关的话题