additionLayer — 相加层

additionLayer 是一种在神经网络中按元素将多个输入相加的层。它可以用于将来自多个路径的特征图(feature maps)结合在一起。每个输入必须具有相同的维度。相加层的作用通常用于残差网络(ResNet)或其他需要在层之间进行特征融合的网络架构中。

创建 additionLayer

  1. 基础语法:

    layer = additionLayer(numInputs)
    

    这个命令会创建一个相加层,该层能够处理 numInputs 个输入,并按元素将它们相加。

  2. 指定层名称:

    layer = additionLayer(numInputs, 'Name', name)
    

    在这种情况下,你可以为相加层指定一个名称。name 是你为该层指定的名称,帮助在网络中识别该层。

主要属性

  1. NumInputs:输入的数量。

    • 类型:double
    • 描述:这是一个正整数,指定相加层可以接收的输入数目。输入数目必须大于或等于 2。
  2. Name:层的名称。

    • 类型:charstring
    • 描述:层的名称,默认为空字符串 ""。你可以通过指定此属性为自定义名称来标识层。
  3. InputNames:输入的名称。

    • 类型:cell
    • 描述:此属性表示输入层的名称。默认情况下,输入名称为 {'in1', 'in2', ..., 'inN'},其中 N 为输入的数量。
  4. NumOutputs:输出的数量。

    • 类型:double
    • 描述:此属性为只读,始终为 1,因为相加层只有一个输出。
  5. OutputNames:输出名称。

    • 类型:cell
    • 描述:此属性为只读,默认为 {'out'},表示相加层的输出名称。

示例:如何使用 additionLayer

创建并连接 additionLayer
% 创建一个包含两个输入的相加层
layer = additionLayer(2, 'Name', 'add');

% 创建一个神经网络
net = dlnetwork;

% 向网络中添加相加层
net = addLayers(net, layer);

% 创建两个 ReLU 层
layer1 = reluLayer('Name', 'relu1');
layer2 = reluLayer('Name', 'relu2');

% 将 ReLU 层连接到相加层的输入
net = addLayers(net, layer1);
net = connectLayers(net, 'relu1', 'add/in1');

net = addLayers(net, layer2);
net = connectLayers(net, 'relu2', 'add/in2');

% 可视化更新后的网络
plot(net);

在这个示例中,我们创建了一个包含两个输入的相加层,并连接了两个 ReLU 层。这两个 ReLU 层的输出会在相加层处被按元素相加。最后,通过 plot 函数可视化更新后的神经网络。

作用和原理

  1. 按元素相加:相加层会按元素将多个输入相加。所有输入的维度必须相同,网络会对输入进行逐元素求和。

  2. 常用于残差网络:相加层通常用于残差网络(ResNet)架构中,这种网络结构将前一层的输出与当前层的输出进行相加,允许信息在网络中更深层次地传播,避免梯度消失问题。

层输入和输出格式

相加层支持多种数据格式,例如:

  • “CB”(通道,批量)
  • “SCB”(空间,通道,批量)
  • “SSCB”(空间,空间,通道,批量)

相加层在网络中传递数据时,确保输入格式和输出格式的兼容性。

扩展功能

  • C/C++ 代码生成:你可以使用 MATLAB® Coder™ 生成相加层的 C 或 C++ 代码。
  • GPU 代码生成:使用 GPU Coder™ 生成 CUDA® 代码,为 NVIDIA® GPU 提供支持。

版本历史

  • R2017b:首次引入 additionLayer

总结

additionLayer 是一个用于按元素将多个输入相加的层。它在构建深度神经网络时非常有用,尤其是在需要将不同路径的输出组合起来时,如残差网络中的跳跃连接。通过使用 additionLayer,网络能够更有效地学习并改善训练过程中的梯度传播。

lstmLayer 详解

lstmLayer 是 MATLAB 深度学习工具箱中的一个层,用于实现 长短期记忆网络(LSTM, Long Short-Term Memory)。LSTM 是一种循环神经网络(RNN)的变体,能够有效地捕捉时间序列数据中的长期依赖关系。LSTM 通过引入记忆单元(Cell State)和门控机制(输入门、遗忘门和输出门)解决了传统 RNN 在训练过程中遇到的梯度消失问题。

在 MATLAB 中,lstmLayer 是用于实现 LSTM 层的核心组件,可以用于时间序列分析、语音识别、自然语言处理等任务。

lstmLayer 的作用

LSTM 层的作用是从输入的序列数据中学习隐藏状态(hidden state),并根据学习到的记忆单元(cell state)对每个时间步的输入进行处理。LSTM 层的设计使其能够记住时间步之间的长期依赖关系,从而适用于长时间序列的学习。

lstmLayer 主要属性

  1. NumHiddenUnits:指定 LSTM 层的隐藏单元数量,也就是网络中记忆单元的数量。该值决定了 LSTM 层的容量,隐藏单元越多,模型可以学习的表示就越丰富。

    • 类型:正整数
    • 影响:影响 LSTM 层的输出大小,隐藏单元越多,输出的表示能力越强。
  2. OutputMode:控制 LSTM 层的输出行为,指定是否输出每个时间步的隐藏状态(完整序列)或仅输出序列的最后一个时间步的隐藏状态。

    • “sequence”(默认):输出整个序列的隐藏状态。
    • “last”:只输出序列的最后一个时间步的隐藏状态,通常用于序列分类等任务。
    • 类型:字符串
  3. StateActivationFunction:定义用于更新隐藏状态和记忆单元的激活函数。默认使用 tanh 激活函数,也可以选择 softsignrelu(自 R2024a 起)。

    • “tanh”:标准的超bolic tangent 函数。
    • “softsign”:软符号函数。
    • “relu”(R2024a 起):ReLU 激活函数。
    • 类型:字符串
  4. GateActivationFunction:定义用于计算 LSTM 层门控部分(输入门、遗忘门、输出门)的激活函数。通常为 sigmoid,但也可以选择 hard-sigmoid

    • “sigmoid”:常见的 Sigmoid 激活函数,输出范围为 0 到 1。
    • “hard-sigmoid”:硬 Sigmoid 激活函数,计算更快,但精度稍差。
    • 类型:字符串
  5. HasStateInputs:指示是否需要额外的状态输入。默认情况下,LSTM 层只有一个输入,in。如果设置为 1,则 LSTM 层会接受三个输入,分别是 in(输入数据)、hidden(上一时间步的隐藏状态)和 cell(上一时间步的记忆状态)。

    • 类型:布尔值(0 或 1)
  6. HasStateOutputs:指示是否输出状态值。如果设置为 1,LSTM 层将输出三个值:out(当前输出)、hidden(当前隐藏状态)和 cell(当前记忆单元)。

    • 类型:布尔值(0 或 1)
  7. InputSize:LSTM 层的输入大小,可以是具体的整数值(表示特征数量),也可以是 "auto"(自动推断输入大小)。

    • 类型:整数或字符向量
  8. InputWeightsRecurrentWeights:LSTM 层的输入权重和递归权重矩阵。这些是网络训练时会更新的可学习参数。

    • 类型:矩阵
  9. Bias:LSTM 层的偏置项。偏置项对每个门控进行调整,也是训练时可学习的参数。

    • 类型:数值向量

lstmLayer 工作流程

LSTM 层通过四个主要的门控机制和隐藏单元来处理时间序列数据:

  1. 遗忘门(Forget Gate):控制遗忘上一时间步的多少信息。它基于当前输入和上一时间步的隐藏状态来决定哪些信息需要被遗忘。

  2. 输入门(Input Gate):决定哪些新的信息可以被加入到记忆单元中。通过 sigmoidal 激活函数决定哪些部分是重要的,然后通过 tanh 函数生成候选的记忆更新。

  3. 记忆单元状态(Cell State):记忆单元是 LSTM 的核心,负责在时间步之间传递信息。它会更新并保留重要的长期信息。

  4. 输出门(Output Gate):决定当前时间步的输出,并结合当前的记忆单元状态计算新的隐藏状态。

公式如下:

  • 遗忘门:( f_t = \sigma(W_f \cdot [h_{t-1}, x_t] + b_f) )
  • 输入门:( i_t = \sigma(W_i \cdot [h_{t-1}, x_t] + b_i) )
  • 候选记忆:( \tilde{C}t = \tanh(W_C \cdot [h{t-1}, x_t] + b_C) )
  • 更新记忆单元:( C_t = f_t * C_{t-1} + i_t * \tilde{C}_t )
  • 输出门:( o_t = \sigma(W_o \cdot [h_{t-1}, x_t] + b_o) )
  • 隐藏状态:( h_t = o_t * \tanh(C_t) )

创建 lstmLayer 示例

创建一个具有 100 个隐藏单元的 LSTM 层:

layer = lstmLayer(100, 'Name', 'lstm1');

如果要设置输出模式为 last,并指定其他属性:

layer = lstmLayer(100, 'OutputMode', 'last', 'Name', 'lstm1');

典型的 LSTM 网络应用

LSTM 层在序列任务中非常有效,典型的应用场景包括:

  1. 时间序列预测:例如股票市场预测、气候变化预测等。
  2. 自然语言处理:包括语言模型、文本生成、机器翻译等。
  3. 语音识别:用于从语音信号中提取特征并进行分类。
  4. 视频分析:例如动作识别、视频分类等。

LSTM 网络的训练示例

以下是一个典型的 LSTM 网络训练示例,适用于序列分类任务:

inputSize = 12;  % 输入的特征数量
numHiddenUnits = 100;  % LSTM 层的隐藏单元数量
numClasses = 9;  % 类别数量

layers = [
    sequenceInputLayer(inputSize)  % 序列输入层
    lstmLayer(numHiddenUnits, 'OutputMode', 'last')  % LSTM 层
    fullyConnectedLayer(numClasses)  % 全连接层
    softmaxLayer];  % Softmax 层

% 设置训练选项
options = trainingOptions('adam', ...
    'MaxEpochs', 200, ...
    'InitialLearnRate', 0.01, ...
    'Shuffle', 'every-epoch', ...
    'GradientThreshold', 1, ...
    'Verbose', false, ...
    'Plots', 'training-progress');

% 假设XTrain和TTrain是训练数据和标签
net = trainNetwork(XTrain, TTrain, layers, options);

总结

LSTM 层在深度学习中非常有用,特别适合处理需要长期依赖的序列数据。通过其门控机制,LSTM 层能够在长时间序列中有效地捕获重要信息,广泛应用于时间序列预测、自然语言处理、语音识别等任务。LSTM 层的强大能力在于它能够记住信息并防止梯度消失,使得它成为深度学习中的重要工具。

selfAttentionLayer 详解

selfAttentionLayer 是 MATLAB 深度学习工具箱中的一种用于计算 自注意力机制(Self-Attention) 的层。自注意力层通过计算输入数据中每个元素与其他元素的关系(即它们之间的依赖),来生成加权表示。这种机制在处理序列数据(如自然语言处理、时间序列等)时特别有效。

自注意力机制(Self-Attention)

自注意力机制是深度学习中一种重要的技术,它通过计算输入序列中不同位置之间的关系来学习更丰富的表示。传统的循环神经网络(RNN)和卷积神经网络(CNN)在处理长序列时可能会遇到梯度消失的问题,而自注意力机制可以有效捕捉长距离的依赖关系,尤其在 Transformer 模型中得到了广泛应用。

selfAttentionLayer 中,层将输入数据转换为 查询(Query)键(Key)值(Value),然后通过计算这些查询、键和值之间的相似性来得到注意力权重,最后将这些权重应用于值,得到加权后的输出。

selfAttentionLayer 主要属性

  1. NumHeads:注意力头的数量。自注意力机制通过多头机制并行计算多个注意力权重,每个头独立计算,最终将结果合并。NumHeads 决定了注意力头的数量。

    • 类型:正整数
  2. NumKeyChannels:查询和键的通道数。查询(Query)和键(Key)用于计算注意力权重,值(Value)则是根据这些权重进行加权的结果。

    • 类型:正整数
  3. NumValueChannels:值的通道数。值是经过加权后的输入数据。默认情况下,这个值与 NumKeyChannels 相同。

    • 类型:正整数或 "auto"(自动)
  4. OutputSize:输出通道的数量。即层的输出的通道数,可以设为与输入相同或者指定一个新的输出通道数量。

    • 类型:正整数或 "auto"
  5. HasPaddingMaskInput:是否具有填充掩码输入。如果设置为 1,则该层会接受一个额外的输入 mask,它表示哪些输入是填充部分,哪些是有效部分。

    • 类型:布尔值(0 或 1)
  6. AttentionMask:用于防止某些键值对之间的注意力交互。它有两个选项:

    • “none”:不限制任何位置之间的注意力交互。
    • “causal”:阻止时间步 M 对时间步 NN > M)的注意力。这个设置常用于自回归模型(如文本生成)。
    • 类型:字符串
  7. DropoutProbability:注意力分数的丢弃概率。在训练期间,部分注意力分数将被随机置为零,从而提高模型的泛化能力。

    • 类型:介于 0 和 1 之间的实数(例如:0.1)
  8. HasScoresOutput:是否返回注意力分数。设置为 1 时,除了输出数据,还会返回注意力权重(也称为注意力分数)。

    • 类型:布尔值(0 或 1)
  9. InputSize:输入通道的数量,决定输入数据的特征数量。

    • 类型:正整数或 "auto"

selfAttentionLayer 工作流程

  1. 计算查询、键和值:输入数据被转化为查询(Q)、键(K)和值(V),这些转换通过训练中的学习权重矩阵完成。

  2. 计算注意力权重:通过计算查询和键的点积得到注意力权重,并使用 Softmax 函数归一化。

  3. 应用注意力权重:将注意力权重应用于值(V),得到加权的输出。

  4. 合并多个头的输出:如果使用多头注意力机制,多个头的输出将会被拼接在一起,然后通过线性变换得到最终输出。

公式

  1. 单头注意力
    [
    \text{attention}(Q, K, V) = \text{dropout}(\text{softmax}(QK^T) + M) V
    ]

    • ( Q ) 表示查询(Query)。
    • ( K ) 表示键(Key)。
    • ( V ) 表示值(Value)。
    • ( M ) 是掩码,用于防止某些位置之间的注意力交互。
    • ( p ) 是丢弃概率。
  2. 多头注意力
    [
    \text{multiheadSelfAttention}(X) = \text{concatenate}(head_1, \ldots, head_h) W_O
    ]

    • 其中每个头 ( i ) 通过不同的权重矩阵进行计算:
      [
      head_i = \text{selfAttention}(X W_{Q_i}, X W_{K_i}, X W_{V_i})
      ]
    • 最终将各个头的输出拼接并通过 ( W_O ) 线性变换得到最终输出。

创建 selfAttentionLayer 示例

下面是创建一个具有 8 个注意力头和 256 个键通道的自注意力层的示例:

layer = selfAttentionLayer(8, 256);

您还可以设置 NumValueChannels 和其他参数:

layer = selfAttentionLayer(8, 256, 'NumValueChannels', 256, 'DropoutProbability', 0.1);

应用示例

自注意力层通常用于以下任务:

  • 文本分类:处理和分类自然语言文本。
  • 机器翻译:通过自注意力机制处理输入序列,并生成翻译。
  • 图像处理:例如图像的区域注意力建模。
  • 语音识别:学习语音数据中不同部分之间的依赖关系。

总结

selfAttentionLayer 是深度学习中处理序列数据的重要工具,特别是在 NLP 和序列建模任务中。它能够有效地捕捉长距离依赖关系,并通过多头机制提高模型的表达能力。通过合理配置该层的超参数(如注意力头的数量、丢弃概率等),可以进一步提升模型的性能。

fullyConnectedLayer 详解

fullyConnectedLayer 是一种常见的神经网络层,它对输入数据进行线性变换,通过乘以权重矩阵并加上偏置向量,生成输出。所有神经元与前一层的所有神经元相连接,因此它也称为“全连接层”。这种层用于将从前面层提取的特征结合起来,通常用于网络的最后部分以输出最终结果。

fullyConnectedLayer 主要功能

  1. 乘以权重矩阵:输入数据与该层的权重矩阵进行点乘操作。
  2. 加上偏置:将偏置向量加到结果中,以生成每个神经元的激活值。
  3. 生成输出:输出的大小由用户指定的 OutputSize 确定。

创建 fullyConnectedLayer

layer = fullyConnectedLayer(outputSize)
  • outputSize:指定输出大小(即神经元的数量)。例如,如果是分类问题,则通常为类别的数量。

还可以使用名称-值对来设置其他可选属性:

layer = fullyConnectedLayer(outputSize, 'Name', 'fc1')

可选属性

  • WeightsInitializer:权重初始化方法(默认为 glorot),可以选择:

    • "glorot":使用 Glorot 初始化器(也称为 Xavier 初始化器)。
    • "he":使用 He 初始化器。
    • "orthogonal":正交初始化。
    • "narrow-normal":从均值为0,标准差为0.01的正态分布中独立采样。
    • "zeros""ones":将权重初始化为零或一。
    • 自定义函数:您也可以通过函数句柄指定自定义的权重初始化方法。
  • BiasInitializer:偏置初始化方法,默认初始化为零。也可以使用类似的初始化方法,如 "ones""narrow-normal" 或自定义函数。

  • WeightLearnRateFactorBiasLearnRateFactor:权重和偏置的学习率因子,可以通过这些因子来控制该层权重和偏置的学习速率。

  • WeightL2FactorBiasL2Factor:控制 L2 正则化的因子,用于惩罚大权重,防止过拟合。

示例

  1. 创建一个输出大小为 10 的全连接层

    layer = fullyConnectedLayer(10)
    
  2. 设置自定义初始化函数

    weightsInitializationFcn = @(sz) rand(sz) * 0.0001;
    biasInitializationFcn = @(sz) rand(sz) * 0.0001;
    
    layer = fullyConnectedLayer(10, ...
        'WeightsInitializer', weightsInitializationFcn, ...
        'BiasInitializer', biasInitializationFcn)
    
  3. 加载并使用外部预设权重和偏置

    load FCWeights.mat   % 假设该文件包含 W 和 b 变量
    layer = fullyConnectedLayer(10, 'Weights', W, 'Bias', b)
    

输入输出

  • 输入fullyConnectedLayer 接受一个输入,该输入可以是任意前一层的输出,通常是一个多维数组。输入的大小应该与前一层的输出维度相匹配。
  • 输出:输出的大小由 outputSize 确定。如果是图像数据,通常会展平图像,然后进行全连接操作。如果是序列数据(如时间步长),全连接层会独立地在每个时间步上操作。

算法

fullyConnectedLayer 的核心算法可以简单描述为:

[
y = W \cdot x + b
]

其中:

  • ( y ) 是输出。
  • ( W ) 是权重矩阵。
  • ( x ) 是输入向量。
  • ( b ) 是偏置向量。

应用场景

  1. 分类任务:全连接层通常用于网络的最后一层,将提取的特征映射到类标签。
  2. 回归任务:用于生成连续的输出。
  3. 特征融合:在深度神经网络中,通过全连接层融合来自不同层的信息。

总结

fullyConnectedLayer 是深度神经网络中非常基础且关键的组件,通常在分类、回归等任务的最后一层使用。通过灵活的初始化和学习速率调整,它可以在各种深度学习模型中发挥重要作用。

Logo

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。

更多推荐