在 MATLAB Function 模块中使用全局数据

全局共享数据

何时需要使用全局数据?

如果出现以下情况,您可能需要在 MATLAB Function 模块中使用全局数据:

  • 您有多个使用全局变量的 MATLAB® 函数,并且您要从 MATLAB Function 模块中调用这些函数。

  • 您有一个使用了大量全局数据的现有模型,您要在此模型中添加一个 MATLAB Function 模块,但不希望使用额外的输入和输出使模型变得混乱。

  • 您希望将数据可见性的作用域限定在模型的某些部分。

在 MATLAB Function 模块中使用全局数据

在 Simulink® 中,您可以使用数据存储内存来存储全局数据。数据存储内存可以通过 Data Store Memory 模块或 Simulink.Signal 对象来实现。如何存储全局数据取决于全局变量的数量和作用域。有关详细信息,请参阅局部和全局数据存储选择如何存储全局数据

MATLAB 全局数据如何与数据存储内存关联

在 Simulink 中的 MATLAB 函数中,全局声明不是映射到 MATLAB 全局工作区。而是在 MATLAB Function 模块中注册全局数据,从而将数据映射到数据存储内存。这种区别使得 MATLAB 函数中的全局数据能够与 Simulink 求解器进行互操作,并在被误用时提供诊断功能。

全局变量将基于层次结构解析为模型中具有相同名称的最近的数据存储内存。根据您的模型层次结构,出现在两个不同 MATLAB Function 模块中的同一个全局变量可能会被解析到不同的数据存储内存。您可以利用此功能将数据可见性的作用域限定到某个子系统。

如何在 MATLAB Function 模块中使用全局变量

要在 MATLAB Function 模块或此模块调用的任何代码中使用全局数据,必须:

  1. MATLAB Function 模块中或在 MATLAB Function 模块调用的任何代码中声明一个全局变量。

  2. MATLAB Function 模块中注册一个与全局变量具有相同名称的 Data Store Memory 模块或 Simulink.Signal 对象。

有关详细信息,请参阅使用 Data Store Memory 模块存储数据使用 Simulink.Signal 对象存储数据

选择如何存储全局数据

下表总结了是使用 Data Store Memory 模块还是 Simulink.Signal 对象。

如果您要...使用...有关详细信息,请参阅...
在不使用模型引用的单个模型中使用少量全局变量。Data Store Memory 模块。

注意

使用 Data Store Memory 模块会将数据的作用域扩大到整个模型。

使用 Data Store Memory 模块存储数据
在不使用模型引用的单个模型中使用大量全局变量。在模型工作区定义的 Simulink.Signal 对象。Simulink.Signal 对象具有以下优势:
  • 不必在模型中添加大量 Data Store Memory 模块。

  • 可从 MAT 文件中加载 Simulink.Signal 对象。

使用 Simulink.Signal 对象存储数据
可在多个模型(包括引用模型)之间共享数据。在基础工作区中定义的 Simulink.Signal 对象

注意

如果同时使用 Data Store Memory 模块和 Simulink.Signal,请注意,使用 Data Store Memory 模块会将数据的作用域扩大到整个模型。

使用 Simulink.Signal 对象存储数据

使用 Data Store Memory 模块存储数据

此模型说明 MATLAB Function 模块如何使用存储在 Data Store Memory 模块 A 中的全局数据。

  1. 打开 dsm_demo.mdl 模型。

在这里插入图片描述

  • 双击 MATLAB Function 模块打开 MATLAB Function 模块编辑器。

    MATLAB Function 模块代码声明全局变量 A。模块在每次执行期间修改 A 的值。

    function y = fcn
    %#codegen
    global A;
    A = A+1;
    y = A;
    

  • 确保全局变量已注册到 MATLAB Function 模块。

    1. MATLAB Function 模块编辑器中,选择 Edit Data 以打开 Ports and Data Manager 对话框。

    2. 在 Ports and Data Manager 中,选择左窗格中的数据 A。该数据使用与全局变量相同的名称。

    3. 数据的 Scope 设置为 Data Store Memory

    另请参阅Ports and Data Manager

  • 双击 Data Store Memory 模块 A。在 Block Parameters 对话框中,您可以看到 Data store name A 与全局变量名称相匹配。该模块的初始值为 25

    当您将 Data Store Memory 添加到您的模型时:

    1. Data store name 设置为与 MATLAB Function 模块代码中的全局变量的名称相匹配。

    2. Data type 设置为明确的数据类型。数据类型不能为 auto

    3. 设置 Signal type 并指定 Initial value

  • 对模型进行仿真。

    MATLAB Function 模块每次执行时都会读取存储在 A 中的全局数据的初始值,并更新 A 的值。

  • 使用 Simulink.Signal 对象存储数据

    此模型说明 MATLAB Function 模块如何使用存储在 Simulink.Signal 对象 A 中的全局数据。

    1. 打开 simulink_signal_local 模型。

    在这里插入图片描述

    模型在模型工作区中使用 Simulink.Signal 对象。

    注意

    要将全局数据用于多个模型,请在基础工作区创建一个 Simulink.Signal 对象。

  • 确保将 Simulink.Signal 对象添加到 Model Explorer。

    1. 从模型菜单中选择 View > Model Explorer

    2. 在 Model Explorer 的左窗格中,选择 simulink_signal_local 模型的模型工作区。

      Contents 窗格显示模型工作区中的数据。

    3. 点击 Simulink.Signal 对象 A

      在右窗格中,确保 Model Explorer 显示 A 的下列属性。

      属性
      Data typedouble
      Complexityreal
      Dimensions1
      Initial value 5

    另请参阅使用 Model Explorer 进行搜索和编辑

  • 双击 MATLAB Function 模块以打开其编辑器。

    MATLAB Function 模块每次执行时都会修改全局数据 A 的值。

    function y = fcn
    %#codegen
    global A;
    A = A+1;
    y = A;
    

  • 确保将 Simulink.Signal 对象注册到 MATLAB Function 模块。

    1. MATLAB Function 模块编辑器中,选择 Edit Data 以打开 Ports and Data Manager 对话框。

    2. 在 Ports and Data Manager 中,选择左窗格中的数据 A。该数据使用与全局变量相同的名称。

    3. 将数据的 Scope 设置为 Data Store Memory

    另请参阅Ports and Data Manager

  • 对模型进行仿真。

    MATLAB Function 模块每次执行时都会读取存储在 A 中的全局数据的初始值,并更新 A 的值。

  • 使用数据存储诊断检测内存访问问题

    您可以配置模型提供运行时和编译时诊断,以免发生数据存储问题。诊断在 Configuration Parameters 对话框以及 Data Store Memory 模块的参数对话框中提供。这些诊断仅适用于 Data Store Memory 模块,不适用于 Simulink.Signal 对象。有关使用数据存储诊断的详细信息,请参阅数据存储诊断

    注意

    如果您向函数传递数据存储内存数组,A=foo(A) 这样的优化可能会导致代码生成软件将整个数组内容都标记为已读或已写,即使只访问了一些元素。

    在 MATLAB Function 模块中使用共享数据的限制

    Data Store Memory 支持不适用于:

    • MATLAB 结构体

    • 可变大小数据

    相关示例

    详细信息

    reference : https://ww2.mathworks.cn/help/simulink/ug/using-global-data-with-the-matlab-function-block.html

  • 8
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在ResNet结构加入SE模块,可以按照以下步骤进行: 1. 定义SE模块,该模块包含一个全局平均池化层、一个全连接层、一个ReLU激活函数、一个全连接层和一个Sigmoid激活函数。可以参考以下代码实现: ```matlab function layers = seBlock(numChannels, reductionRatio, layerNamePrefix) layers = [ globalAveragePooling2dLayer('Name', [layerNamePrefix, 'se_global_pool']) fullyConnectedLayer(reductionRatio*numChannels, 'Name', [layerNamePrefix, 'se_fc1']) reluLayer('Name', [layerNamePrefix, 'se_relu']) fullyConnectedLayer(numChannels, 'Name', [layerNamePrefix, 'se_fc2']) sigmoidLayer('Name', [layerNamePrefix, 'se_sigmoid']) ]; end ``` 2. 在ResNet的每个残差块之后添加SE模块。可以通过在ResNet的每个残差块的最后添加一个SE模块的方式来实现。可以参考以下代码实现: ```matlab function lgraph = addSEBlock(lgraph, numChannels, reductionRatio, layerNamePrefix, blockName) seLayers = seBlock(numChannels, reductionRatio, layerNamePrefix); lgraph = addLayers(lgraph, seLayers); lgraph = connectLayers(lgraph, [blockName, '/relu_out'], [layerNamePrefix, 'se_global_pool']); lgraph = connectLayers(lgraph, [layerNamePrefix, 'se_sigmoid'], [blockName, '/prod']); end ``` 3. 修改ResNet的每个残差块,以实现SE模块的连接。可以参考以下代码实现: ```matlab function lgraph = addSEToResNet(lgraph, numChannels, reductionRatio, layerNamePrefix, blockName) seBlockName = [blockName, '_SE']; lgraph = addSEBlock(lgraph, numChannels, reductionRatio, layerNamePrefix, seBlockName); lgraph = connectLayers(lgraph, [blockName, '/relu_out'], [seBlockName, '/prod_in']); lgraph = connectLayers(lgraph, [seBlockName, '/sigmoid'], [blockName, '/add']); end ``` 4. 使用MATLAB内置的ResNet-50网络作为基础模型,并在其添加SE模块。可以参考以下代码实现: ```matlab net = resnet50; inputLayerName = 'input'; outputLayerName = 'fc1000'; numChannels = 2048; reductionRatio = 16; layerNamePrefix = 'se_'; blockNames = {'res2a', 'res2b', 'res2c', 'res3a', 'res3b1', 'res3b2', 'res3b3', 'res4a', 'res4b1', 'res4b2', 'res4b3', 'res4b4', 'res4b5', 'res4b6', 'res4b7', 'res4b8', 'res4b9', 'res4b10', 'res4b11', 'res4b12', 'res4b13', 'res4b14', 'res4b15', 'res4b16', 'res5a', 'res5b', 'res5c'}; for i = 1:numel(blockNames) blockName = blockNames{i}; net = addLayers(net, seBlock(numChannels, reductionRatio, [layerNamePrefix, blockName])); net = connectLayers(net, [blockName, '/relu_out'], [layerNamePrefix, blockName, '/prod_in']); net = connectLayers(net, [layerNamePrefix, blockName, '/sigmoid'], [blockName, '/add']); end ``` 需要注意的是,在添加SE模块时,需要确保SE模块的代码和ResNet代码之间的接口兼容,避免出现不兼容的情况导致程序无法正常运行。另外,如果SE模块使用了C或者C++代码,需要使用MATLAB提供的MEX函数将C/C++代码转换为MATLAB可调用的函数。详细的使用方法可以参考MATLAB官方文档。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值