深入、清晰、有例子、有对比地讲清楚 sequenceInputLayer
到底是什么、怎么用、有什么坑、在哪些场景下最关键。
sequenceInputLayer
?在 MATLAB 深度学习框架中,sequenceInputLayer
是序列模型的入口层,专为输入时间序列数据或**按时间变化的图像数据(视频、雷达、语音等)**而设计。
它的作用是:
layer = sequenceInputLayer(inputSize)
layer = sequenceInputLayer(12, ...
'Name', 'inputLayer', ...
'Normalization', 'zscore', ...
'MinLength', 20);
参数 | 解释 | 举例 |
---|---|---|
inputSize |
每个时间步的数据维度(即特征数) | 12 表示每个时间步是一个 12 维向量 |
Normalization |
输入归一化方式 | 'none' , 'zscore' , 'rescale-symmetric' 等 |
MinLength |
最小支持的时间步数 | 比如为 20,输入序列不能短于 20 步 |
Name |
层的命名 | 'inputLayer' 便于引用或调试 |
SplitComplexInputs |
复数数据支持 | 从 R2024a 开始可以直接传入复数 |
输入类型 | 输入维度 | 输入数据格式(dlnetwork) |
---|---|---|
向量序列 | inputSize = d |
[T × d] ,即 时间步 × 特征数 |
1D 图像序列 | [h, c] |
[H × C × T] |
2D 图像序列 | [h, w, c] |
[H × W × C × T] |
3D 图像序列 | [h, w, d, c] |
[H × W × D × C × T] |
你在用 trainnet
或 dlnetwork
训练时,数据格式必须匹配。
方式 | 含义 | 适用情况 |
---|---|---|
'none' |
不归一化 | 数据预处理已完成时使用 |
'zerocenter' |
减去均值 | 去除偏移量 |
'zscore' |
标准化为均值为0,方差为1 | 非常常用 |
'rescale-symmetric' |
映射到 [-1, 1] | 图像/语音信号常见 |
'rescale-zero-one' |
映射到 [0, 1] | 灰度图像、频谱等 |
function_handle |
自定义函数 | 高级场景,能做任意变换 |
如果你设置了 Normalization='zscore'
,可以再用 Mean
和 StandardDeviation
指定统计量,也可以让 MATLAB 自动学习。
MATLAB 默认:
trainnet
中自动计算 Mean
、Std
等;minibatchpredict
)中复用训练时的统计量;trainingOptions(..., 'ResetInputNormalization', false)
加快训练(避免重复计算);数据格式要正确!
dlnetwork
中:输入维度顺序 = [T x C]
trainNetwork
中是 [C x T]
卷积/池化层易导致时序长度变短,配合 MinLength
防止出错。
输入序列过短会报错!
复数数据支持(从 R2024a 起)
layers = [
sequenceInputLayer(12, 'Normalization', 'zscore')
lstmLayer(100, 'OutputMode', 'last')
fullyConnectedLayer(5)
softmaxLayer
classificationLayer];
这个网络可以用来处理每条序列为 12 维、输出 5 类的分类问题,比如语音情绪识别、传感器异常检测等。
场景 | 说明 |
---|---|
时间序列分类 | 股票涨跌、传感器报警、故障分类等 |
序列回归 | 温度预测、能耗预测等 |
视频识别 | 帧序列输入,每帧一个特征 |
EEG/EMG/ECG 分析 | 每个通道为一个特征,按时间变化 |
音频建模 | 语音情感识别、音频事件检测等 |
sequenceInputLayer
是构建一切时间序列神经网络的“数据入口”,解决了输入格式标准化 + 自动归一化 + 序列长度控制的问题,是 LSTM、GRU、TCN、1D-CNN 的“起点”。
当然可以!我们来详细聊一聊 MATLAB 中的 lstmLayer
,它是处理时间序列数据的关键组件之一,尤其适用于电力负荷预测、金融数据建模、语音识别等任务。
lstmLayer
?lstmLayer
是 MATLAB 中 长短期记忆网络(LSTM) 的实现形式,是一种循环神经网络(RNN)层,专门用于建模和预测时间序列中的长期依赖关系。它能够记住时间序列中的重要信息,并忘掉无用信息,从而解决传统 RNN 容易出现的梯度消失或爆炸问题。
layer = lstmLayer(numHiddenUnits)
或者带参数:
layer = lstmLayer(numHiddenUnits, 'Name', 'lstm1', 'OutputMode', 'last')
NumHiddenUnits
(必须指定)示例:
lstmLayer(100) % 使用100个隐藏单元
OutputMode
(非常关键)决定输出什么:
值 | 含义 | 应用场景 |
---|---|---|
'last' |
只输出最后一个时间步的输出 | 序列→标签/数值(分类、预测1个值) |
'sequence' |
输出完整时间序列 | 序列→序列(多步预测、序列标注) |
示例:
lstmLayer(100, 'OutputMode', 'sequence')
StateActivationFunction
控制内部状态更新方式(R2024a 起支持更多):
'tanh'
(默认)→ 平滑非线性'relu'
→ 更适合梯度传播'softsign'
→ 缓和梯度变化GateActivationFunction
控制 LSTM 的门控逻辑:
'sigmoid'
(默认):适合大部分情况'hard-sigmoid'
:线性化近似,计算更快HasStateInputs
/ HasStateOutputs
'InputWeightsInitializer', 'glorot' % 默认
'RecurrentWeightsInitializer', 'orthogonal'
'BiasInitializer', 'unit-forget-gate'
你也可以使用函数句柄传入自己的初始化函数。
LSTM 每一步通过四个“门”控制信息流:
状态更新方程:
c_t = f_t .* c_{t-1} + i_t .* g_t
h_t = o_t .* tanh(c_t)
layers = [
sequenceInputLayer(1) % 1个特征输入(负荷)
lstmLayer(100, 'OutputMode', 'last') % 输出最后一时刻的状态
fullyConnectedLayer(1) % 输出一个值
regressionLayer
];
这个网络会接收一个长度为96的负荷序列,输出预测值(比如第97时刻的负荷)。
"sequence"
trainingOptions(..., 'GradientThreshold', 1, ...)
防止爆炸。
layers = [
sequenceInputLayer(1)
lstmLayer(128, 'OutputMode','sequence')
lstmLayer(64, 'OutputMode','last')
fullyConnectedLayer(1)
regressionLayer
];
lstmLayer(100,'OutputMode','sequence')
dropoutLayer(0.2)
好的,我们来系统全面地讲讲 MATLAB 中的 lstmProjectedLayer
,从它的定义、结构、用途、优势、参数、原理再到实战建议,帮你彻底吃透这个 高效的 LSTM 压缩层。
lstmProjectedLayer
是 压缩版本的 LSTM 层,通过引入可训练的投影矩阵,大幅减少参数数量,同时保持输出维度不变,适合在模型部署、资源有限的环境中使用。
layer = lstmProjectedLayer(numHiddenUnits, outputProjectorSize, inputProjectorSize)
参数 | 含义 |
---|---|
numHiddenUnits |
LSTM 的隐藏单元个数,决定输出维度 |
outputProjectorSize |
输出投影维度,对隐藏状态 ht-1 进行降维的维度 |
inputProjectorSize |
输入投影维度,对输入 xt 进行降维的维度 |
layers = [
sequenceInputLayer(12)
lstmProjectedLayer(100, 25, 9, 'OutputMode','sequence')
fullyConnectedLayer(1)
regressionLayer
];
标准 LSTM 的输入权重和循环权重参数量很大:
4 × hiddenSize × inputSize
4 × hiddenSize²
如果我们:
那么 lstmProjectedLayer
就是绝佳选择!
假设:
xt
是输入,ht-1
是上一时刻隐藏状态Wx * xt + Rh * ht-1 + b
引入两个投影矩阵 Qi
、Qo
:
W' = W * Qi → [4*hiddenSize x inputProjectorSize]
x_proj = Qi' * xt
→ W * Qi * Qiᵗ * xt
R' = R * Qo
h_proj = Qo' * ht-1
→ R * Qo * Qoᵗ * ht-1
参数量从:
4*hiddenSize*inputSize + 4*hiddenSize²
降低为:
4*hiddenSize*inputProjectorSize + 4*hiddenSize*outputProjectorSize + inputSize*inputProjectorSize + hiddenSize*outputProjectorSize
通常可以压缩到原来的一半甚至更少!
场景 | 推荐理由 |
---|---|
部署到嵌入式设备 | 参数量小,模型轻便 |
训练数据少 | 降低过拟合风险 |
快速原型测试 | 节省训练和推理资源 |
构建更深层网络 | 降低整体模型负担 |
属性名 | 说明 |
---|---|
NumHiddenUnits |
隐藏单元数(输出通道数) |
OutputProjectorSize |
投影后隐藏状态维度 |
InputProjectorSize |
投影后输入维度 |
OutputMode |
'last' or 'sequence' |
InputWeights / RecurrentWeights |
投影后的权重矩阵 |
InputProjector / OutputProjector |
投影矩阵 Q |
Bias |
各门的偏置项 |
lstmLayer
对比对比项 | lstmLayer |
lstmProjectedLayer |
---|---|---|
参数量 | 大 | 小 |
输出维度 | numHiddenUnits |
一样 |
支持投影 | ❌ | ✅ |
控制粒度 | 只能改 hiddenSize | 可控制 hiddenSize + 投影维度 |
适合部署 | 一般 | 非常适合 |
版本要求 | R2017b+ | R2022b+ |
经验值推荐:
outputProjectorSize = floor(0.25 * numHiddenUnits);
inputProjectorSize = floor(0.75 * inputSize);
可以。建议加在 lstmProjectedLayer 之后,缓解过拟合:
lstmProjectedLayer(...)
dropoutLayer(0.2)
trainNetwork
自动识别 GPUanalyzeNetwork(layers)
查看参数数量差异trainNetwork
和 trainingOptions
接口都兼容
lstmProjectedLayer
是参数更少、效率更高、精度几乎无损的 LSTM,适合追求轻量化部署的任何时序建模任务。
如果你正在做电力负荷预测、风电预测或时间序列回归任务,我可以帮你:
layers
和 trainingOptions
配置XTrain
/ YTrain
数据处理方法好的,我们就来系统性、深入地聊聊 MATLAB 中的 bilstmLayer
——双向长短期记忆层(Bidirectional LSTM Layer)。
bilstmLayer
是一种循环神经网络(RNN)结构,它结合了两个 LSTM:
最终将这两个方向的隐藏状态 拼接 起来作为输出。这样,网络在每一个时间步都能访问序列中过去和未来的信息。
layer = bilstmLayer(numHiddenUnits)
其中 numHiddenUnits
是每个方向的隐藏单元数。
layer = bilstmLayer(100, 'OutputMode','last', 'Name','bilstm1')
参数 | 含义 | 示例值 |
---|---|---|
NumHiddenUnits |
每个方向的隐藏单元数量 | 64 |
OutputMode |
输出方式:'sequence' 或 'last' |
'last' |
Name |
层名称 | 'bilstm1' |
StateActivationFunction |
状态激活函数:'tanh' 、'relu' 、'softsign' (从 R2024b 开始) |
'tanh' |
GateActivationFunction |
门控激活函数:'sigmoid' 、'hard-sigmoid' |
'sigmoid' |
每个时间步 t
:
x1 →→→→→→→→→→→→→→→→→→→→→→→→→→
↑ ↓
│ │
Forward LSTM: h1,h2,...,hn Backward LSTM: hn,h(n-1),...,h1
最终输出 y_t = [h_t^forward ; h_t^backward]
注意:
2 * NumHiddenUnits
模式 | 输出内容 | 用途 |
---|---|---|
'sequence' |
所有时间步的输出,形状为 T × 2H |
用于序列标注(如每步分类) |
'last' |
只输出最后一步,形状为 1 × 2H |
用于整个序列分类(如情感分析) |
设:
D
H
(即每个方向的)项 | 公式 | 含义 |
---|---|---|
输入权重矩阵 | W : 8H × D |
因为是 2 个方向 × 4 个门 |
循环权重矩阵 | R : 8H × H |
每个门一个权重矩阵,共 8 个 |
偏置向量 | b : 8H × 1 |
同上,共 8 个偏置向量 |
总参数量:
8H * D + 8H * H + 8H = 8H(D + H + 1)
所以使用 BiLSTM 参数量会大约是单向 LSTM 的 2 倍。
应用方向 | bilstm 优势 |
---|---|
文本情感分析 | 可获取上下文语义,提高分类准确率 |
命名实体识别(NER) | 序列标注任务,后文对当前标签有辅助作用 |
生物序列建模 | 如 DNA/RNA,后续片段常对前序有关键影响 |
语音识别/语音情感 | 双向信息帮助理解语音的真实语义 |
时间序列预测(后验分析) | 可充分建模已知序列整体信息 |
inputSize = 12; % 每步输入的特征数
hiddenSize = 64;
numClasses = 5;
layers = [
sequenceInputLayer(inputSize)
bilstmLayer(hiddenSize, 'OutputMode','last')
fullyConnectedLayer(numClasses)
softmaxLayer
classificationLayer
];
输出维度说明:
2 * hiddenSize = 128
fullyConnectedLayer(5)
,映射为 5 类dropoutLayer
防过拟合;NumHiddenUnits
,防止过拟合;InputSize
为 "auto"
,MATLAB 会自动推断;层类型 | 双向 | 参数量 | 支持压缩 | 优势 |
---|---|---|---|---|
lstmLayer |
❌ | 中 | ✔ | 普通时序建模 |
bilstmLayer |
✅ | 多 | ❌ | 捕捉上下文双向依赖 |
lstmProjectedLayer |
❌ | 少 | ✔✔ | 轻量化部署、节省资源 |
bilstmLayer
是序列建模中的增强版 LSTM,适用于一切你希望模型“看前看后”的任务。虽然参数较多,但只要合理设计结构,能大幅提升模型表现力和泛化能力。
当然可以!下面我将从结构原理、工作机制、参数配置、使用方法、适用场景等方面全面系统地解析 MATLAB 中的 gruLayer
(Gated Recurrent Unit Layer)。这将帮助你从原理到实战全方位掌握它。
gruLayer
是什么?gruLayer
是 MATLAB 提供的门控循环单元层,用于构建 RNN 网络以处理时间序列或序列数据。
它属于 RNN 系列,与 lstmLayer
功能类似,但:
GRU 结构通过两个门来控制信息的保留与更新:
门控组件 | 作用 |
---|---|
更新门(Update gate)zₜ |
决定是否保留旧的隐藏状态 |
重置门(Reset gate)rₜ |
决定是否忘记旧状态 |
候选状态(Candidate state)gₜ |
当前时间步新生成的信息候选 |
更新门:
[
z_t = \sigma(W_z x_t + R_z h_{t-1} + b_z)
]
重置门:
[
r_t = \sigma(W_r x_t + R_r h_{t-1} + b_r)
]
候选状态:
[
g_t = \tanh(W_g x_t + r_t \circ (R_g h_{t-1}) + b_g)
]
最终隐藏状态(输出):
[
h_t = (1 - z_t) \circ h_{t-1} + z_t \circ g_t
]
其中:
gruLayer
参数详解layer = gruLayer(numHiddenUnits, Name=Value)
参数名 | 默认值 | 说明 |
---|---|---|
NumHiddenUnits |
必填 | GRU 输出的隐藏单元数量 |
OutputMode |
'sequence' |
'sequence' (逐步输出)或 'last' (最后一个) |
StateActivationFunction |
'tanh' |
用于生成候选状态的函数 |
GateActivationFunction |
'sigmoid' |
门控函数,一般用 sigmoid |
ResetGateMode |
'after-multiplication' |
控制重置门放置位置,默认兼容 cuDNN |
HasStateInputs/Outputs |
false |
是否输入输出状态(用于状态记忆) |
InputWeightsInitializer |
'glorot' |
初始化方法 |
BiasInitializer |
'zeros' |
偏置初始化方式 |
假设:
D
H
GRU 总共有 三个门控组件(r, z, g),所以参数尺寸如下:
参数名 | 尺寸 | 说明 |
---|---|---|
InputWeights |
3H × D |
输入权重(重置、更新、候选) |
RecurrentWeights |
3H × H |
循环权重 |
Bias |
3H × 1 或 6H × 1 |
视 ResetGateMode 而定 |
inputSize = 12;
numHiddenUnits = 100;
numClasses = 5;
layers = [
sequenceInputLayer(inputSize)
gruLayer(numHiddenUnits, OutputMode="last")
fullyConnectedLayer(numClasses)
softmaxLayer
classificationLayer
];
适用于:分类、预测、情感分析、信号识别、天气预报等时序任务。
特性 | GRU (gruLayer ) |
LSTM (lstmLayer ) |
BiLSTM (bilstmLayer ) |
---|---|---|---|
参数量 | 少 | 多 | 2 倍 LSTM |
训练速度 | 快 | 中 | 慢 |
表达能力 | 中 | 强 | 最强 |
是否含 Cell State | ❌ | ✅ | ✅ |
应用推荐 | 资源受限/快速部署 | 长依赖任务 | 文本语义、语音理解等双向场景 |
隐藏单元数建议:
防止过拟合:
加入 dropoutLayer
或 L2Regularization
梯度爆炸处理:
使用 gradientThreshold
配合 trainingOptions
批量归一化:
可搭配 layerNormalizationLayer
增强稳定性
layers = [
sequenceInputLayer(10)
gruLayer(128, OutputMode='sequence', Name='gru1')
dropoutLayer(0.3)
fullyConnectedLayer(1)
regressionLayer
];
应用场景:
ResetGateMode
ReLU
激活函数(状态)
gruLayer
是处理时间序列数据的高效、简洁工具,特别适合需要快速训练、部署资源有限的场景,是lstmLayer
的轻量替代者。
如果你在使用 GRU 层做具体项目(比如电力预测、语音识别、文本情感分析等),我可以帮你定制最合适的网络结构或调参方案。需要我出一个完整项目的结构框架或训练流程吗?
当然可以!下面是对 MATLAB 中 gruProjectedLayer
(GRU 投影层) 的全面详细讲解,它结合了 GRU 的时序建模能力 与 参数压缩的高效性,适合部署轻量化模型。
gruProjectedLayer
是什么?gruProjectedLayer
是 GRU 的压缩版本,在保留 GRU 表达能力的同时,用 投影矩阵(Projector
)减少模型参数量,提升内存效率和运行速度。
该层引入了两个投影矩阵:
InputProjector
:压缩输入维度OutputProjector
:压缩输出维度(隐藏状态)这样能达到:
传统 GRU 计算:
[
W x_t
]
投影 GRU 替换为:
[
W (Qx_t)
\quad\text{或}\quad (WQ)x_t
]
即将高维输入/输出通过投影矩阵 Q 降维处理:
D
降到 inputProjectorSize
H
降到 outputProjectorSize
总参数量:
3H×D + 3H×H + 3H
个参数3H×P_in + 3H×H + 3H + P_in×D + H×P_out
(P_in/P_out
为投影维度)典型压缩比可达 40%~80%
layer = gruProjectedLayer(numHiddenUnits, outputProjectorSize, inputProjectorSize, Name=Value)
参数 | 说明 |
---|---|
numHiddenUnits |
GRU 单元数,控制记忆能力 |
outputProjectorSize |
输出投影矩阵大小 |
inputProjectorSize |
输入投影矩阵大小 |
OutputMode |
"sequence" 或 "last" |
ResetGateMode |
重置门机制 |
StateActivationFunction |
"tanh" (默认)、"softsign" 、"relu" |
GateActivationFunction |
"sigmoid" 或 "hard-sigmoid" |
投影 GRU 层中参数包括:
参数 | 维度 | 说明 |
---|---|---|
InputWeights |
3H × P_in |
压缩输入后的权重 |
InputProjector |
P_in × D |
输入压缩矩阵 |
RecurrentWeights |
3H × H |
循环权重 |
OutputProjector |
H × P_out |
输出压缩矩阵 |
Bias |
3H × 1 (或 6H × 1 ) |
偏置项 |
压缩的关键在于:只需存储
W × Q
而不是整个W
layer = gruProjectedLayer(100, 30, 16, Name="grup");
inputSize = 12;
numHiddenUnits = 100;
outputProjectorSize = max(1, floor(0.25 * numHiddenUnits));
inputProjectorSize = max(1, floor(0.75 * inputSize));
layers = [
sequenceInputLayer(inputSize)
gruProjectedLayer(numHiddenUnits, outputProjectorSize, inputProjectorSize, OutputMode="last")
fullyConnectedLayer(9)
softmaxLayer
];
网络 | 参数量 | 说明 |
---|---|---|
gruLayer(100) |
约 34,800 | 标准 GRU |
gruProjectedLayer(100, 25, 9) |
约 14,000 | 压缩约 60% |
使用 analyzeNetwork(net)
可查看参数量对比图示。
✅ 非常适合以下任务中部署轻量化模型:
gruLayer
的区别总结特性 | gruLayer |
gruProjectedLayer |
---|---|---|
是否压缩 | 否 | ✅ |
参数量 | 多 | 少 |
输入输出维度是否压缩 | 否 | ✅ |
是否易部署 | 中等 | 高 |
预测精度 | 高 | 略降(通常可接受) |
引入时间 | R2020a | R2023b |
gruProjectedLayer
是适用于资源受限场景的高效 GRU 替代方案,在保留模型表达能力的同时显著减少存储与计算量,是模型压缩与部署的理想选择。
如果你正在构建一个 GRU 或投影 GRU 网络,我可以帮你根据数据维度设计最佳参数(如 projector size 比例、层堆叠方式等),是否需要我帮你出一个压缩模型的完整训练方案?
当然可以,我们来 深入全面讲讲 gruProjectedLayer
——这是 MATLAB 为神经网络压缩与轻量化设计的一个高效组件,尤其适合你处理序列任务时对资源节省、模型部署有需求的场景。
gruProjectedLayer
是一个带有输入/输出投影机制的 GRU 层,用更少的参数完成与传统 GRU 相似的时间序列建模任务。
标准的 gruLayer
模型参数数量很大,尤其在输入维度 D
或隐藏单元数 H
较多时:
3 * (H * D + H * H + H)
3 * (H * P_in + H * H + H) + P_in * D + H * P_out
P_in
: 输入投影维度(inputProjectorSize
)P_out
: 输出投影维度(outputProjectorSize
)✨ 压缩比可达 40-80%,尤其适合:
gruProjectedLayer
和传统 GRU 不同的是,引入了两个可学习的线性投影矩阵:
组成 | 作用 |
---|---|
InputProjector (Q₁) | 将高维输入 x 投影到低维空间 |
OutputProjector (Q₂) | 将隐藏状态的输出再投影以减少下游参数量 |
InputWeights (W) | 在投影空间中执行计算 |
RecurrentWeights ® | 和传统 GRU 相同 |
Bias | 可选偏置项 |
流程如下:
x (D维输入)
↓ 投影 (Q₁)
Q₁x (P_in维)
↓ 权重乘 (W)
WQ₁x (H维)
↓ GRU公式处理
↓
h_t (H维隐藏状态)
↓ 投影 (Q₂)
Q₂h_t → 输出
layer = gruProjectedLayer(numHiddenUnits, outputProjectorSize, inputProjectorSize, Name=Value)
参数 | 类型 | 作用 |
---|---|---|
numHiddenUnits |
int | GRU 的隐藏状态单元数 |
outputProjectorSize |
int | 输出维度压缩后的大小 |
inputProjectorSize |
int | 输入压缩维度 |
OutputMode |
"sequence" / "last" |
是否输出每一步或最后一步 |
StateActivationFunction |
"tanh" / "softsign" / "relu" |
状态更新激活函数 |
GateActivationFunction |
"sigmoid" / "hard-sigmoid" |
门控函数 |
ResetGateMode |
"after-multiplication" (默认) |
GRU重置门工作机制 |
inputSize = 12;
numHiddenUnits = 100;
outputProjectorSize = 25;
inputProjectorSize = 9;
layer = gruProjectedLayer(numHiddenUnits, outputProjectorSize, inputProjectorSize, ...
Name="gru_proj", OutputMode="last");
layers = [
sequenceInputLayer(inputSize)
gruProjectedLayer(100, 25, 9, OutputMode="last")
fullyConnectedLayer(5)
softmaxLayer
];
net_standard = dlnetwork([
sequenceInputLayer(12)
gruLayer(100, OutputMode="last")
fullyConnectedLayer(9)
softmaxLayer
]);
net_proj = dlnetwork([
sequenceInputLayer(12)
gruProjectedLayer(100, 25, 9, OutputMode="last")
fullyConnectedLayer(9)
softmaxLayer
]);
analyzeNetwork(net_standard)
analyzeNetwork(net_proj) % 查看压缩比例
优势 | 描述 |
---|---|
参数量大幅减少 | 例如从 34k 减少到 14k |
⚡ 训练更快,占用更少内存 | 非常适合多模型并行训练 |
适合部署到边缘设备 | 节省内存资源 |
保持表达能力 | 投影后隐藏单元数不变,保持下游结构兼容性 |
层名称 | 是否压缩 | 输入是否压缩 | 输出是否压缩 | 参数量 | 输出维度 |
---|---|---|---|---|---|
gruLayer |
否 | 否 | 否 | 高 | numHiddenUnits |
gruProjectedLayer |
✅ 是 | ✅ 是 | ✅ 是 | 低 | outputProjectorSize |
compressNetworkUsingProjection
函数结合使用实现自动压缩outputProjectorSize = 0.25 * hiddenUnits
inputProjectorSize = 0.5~0.75 * inputSize
gruProjectedLayer
= GRU + 投影压缩,是一种兼顾性能与效率的解决方案,适合以下应用:
✅ 电力负荷预测
✅ 语音识别
✅ 医疗时间序列分析
✅ 移动端边缘部署
✅ 多模型高并发系统
如果你有具体的数据维度、输入形状,我可以帮你定制一套压缩参数选择方案,或搭建完整的压缩训练流程。要试试看吗?
当然可以!我们现在详细来聊一聊 MATLAB 中的 convolution1dLayer
,也就是 一维卷积层,它是处理 时间序列、音频信号、文本数据等 1D 输入 的强力工具。
convolution1dLayer
是一种滑动窗口式的特征提取层,它在时间或空间维度上滑动一组可训练滤波器,挖掘局部模式和结构。
layer = convolution1dLayer(filterSize, numFilters)
参数名 | 说明 |
---|---|
filterSize |
卷积核的宽度(窗口大小) |
numFilters |
卷积核的数量(即输出通道数) |
layer = convolution1dLayer(3, 64); % 使用 64 个 1x3 卷积核
参数名 | 默认值 | 说明 |
---|---|---|
Stride |
1 | 步长 |
Padding |
[0 0] / 'same' / 'causal' |
控制边缘填充 |
DilationFactor |
1 | 控制空洞卷积,扩展感受野 |
NumChannels |
'auto' |
输入通道数 |
WeightsInitializer |
'glorot' |
权重初始化方法 |
BiasInitializer |
'zeros' |
偏置初始化方法 |
Weights , Bias |
[] | 可手动设定权重与偏置初值 |
Name |
“” | 层名称 |
类似于滑动窗口:
对于每个时间步 ( t ),输出值是输入片段 ( x_{t:t+f-1} ) 与卷积核 ( w ) 的点积,再加上偏置 ( b ):
y t = w ⋅ x t : t + f − 1 + b y_t = w \cdot x_{t:t+f-1} + b yt=w⋅xt:t+f−1+b
多个滤波器并行工作,输出为多个特征图(channels)
通常与如下层组合:
layers = [
sequenceInputLayer(3) % 输入通道数为 3
convolution1dLayer(5, 32, Padding='same') % 输出32个特征图
reluLayer
globalMaxPooling1dLayer
fullyConnectedLayer(10)
softmaxLayer
];
输入类型 | 格式 | 卷积维度 |
---|---|---|
时间序列(标准) | [C, B, T] (channel, batch, time) |
时间维 |
1D 图像 | [S, C, B] (spatial, channel, batch) |
空间维 |
1D 图像序列 | [S, C, B, T] |
空间维 |
输出尺寸受以下因素控制:
OutputLength = ⌊ InputLength + P L + P R − D ⋅ ( F − 1 ) − 1 S + 1 ⌋ \text{OutputLength} = \left\lfloor \frac{\text{InputLength} + P_L + P_R - D \cdot (F - 1) - 1}{S} + 1 \right\rfloor OutputLength=⌊SInputLength+PL+PR−D⋅(F−1)−1+1⌋
其中:
任务类型 | 建议参数 |
---|---|
电力负荷预测 | filterSize=7~15,padding=‘same’ |
文本/词嵌入分类 | filterSize=3/5/7,多核组合(TextCNN) |
语音/音频处理 | dilationFactor > 1 扩大感受野 |
替代 RNN 建模 | 多层堆叠 conv1d + globalMaxPooling1dLayer |
1D 卷积常作为 RNN 的前置特征提取器:
layers = [
sequenceInputLayer(12)
convolution1dLayer(3, 64, Padding='same')
reluLayer
gruLayer(100)
fullyConnectedLayer(5)
softmaxLayer
];
优势 | 局限 |
---|---|
并行计算快 | 只能捕捉局部依赖 |
参数少易训练 | 不擅长长序列依赖 |
可堆叠抽象特征 | 不如 RNN 有时间意识 |
属性 | 说明 |
---|---|
类型 | 一维卷积神经网络层 |
输入 | 序列数据(向量或时序) |
输出 | 多通道特征图 |
核心用途 | 局部特征提取 |
常配合 | ReLU、Pooling、LSTM、GRU、FC |
如果你有具体的时间序列或信号数据,我可以帮你设计一套基于 convolution1dLayer
的网络架构,或者比较它与 LSTM、GRU 的效果差异。你希望我怎么继续?比如来一个电力预测示例?
当然可以!下面我将从概念、用法、结构原理、参数解释、典型应用场景、示例代码六个方面,带你深入理解 MATLAB 中的 transposedConv1dLayer
—— 一维转置卷积层。
transposedConv1dLayer
是 用于一维数据上采样(即增大特征图长度)的深度学习层。
⚠️ 它并不是真正的“反卷积”,也不是经典的反变换操作,而是:
在卷积计算的“矩阵乘法视角”下,标准卷积的“转置操作”
用于将低分辨率特征图还原为高分辨率,是很多 生成型模型和解码器网络的核心组件。
layer = transposedConv1dLayer(filterSize, numFilters)
filterSize
:卷积核长度numFilters
:输出通道数(feature maps)layer = transposedConv1dLayer(11, 96, ...
Stride=2, ...
Cropping="same", ...
Name="upSampleLayer");
标准卷积通常:
转置卷积则:
其本质操作包括:
L out = Stride ⋅ ( L in − 1 ) + K − C L_{\text{out}} = \text{Stride} \cdot (L_{\text{in}} - 1) + K - C Lout=Stride⋅(Lin−1)+K−C
其中:
参数 | 类型 | 说明 |
---|---|---|
filterSize |
int | 卷积核长度 |
numFilters |
int | 输出通道数 |
Stride |
int (默认1) | 上采样倍数 |
Cropping |
int / vector / "same" |
输出长度调整方式 |
NumChannels |
"auto" / int |
输入通道数 |
WeightsInitializer |
字符串或函数 | 权重初始化方法 |
BiasInitializer |
字符串或函数 | 偏置初始化方法 |
encoder ➝ transposedConv1dLayer ➝ decoder
layers = [
sequenceInputLayer(1, Name="input")
convolution1dLayer(3, 16, Stride=2, Padding="same", Name="encoderConv")
reluLayer
transposedConv1dLayer(3, 8, Stride=2, Cropping="same", Name="decoderDeconv")
reluLayer
convolution1dLayer(3, 1, Padding="same", Name="reconstruction")
];
你可以配合 dlnetwork
和 trainnet
使用,还可以使用 analyzeNetwork(layers)
检查结构。
✅ 优点 | ⚠️ 注意点 |
---|---|
1. 上采样有学习能力,可优化 | 输出尺寸受 stride & crop 强烈影响 |
2. 常用于生成网络中,如 GAN 解码器 | 不是传统意义的“反卷积” |
3. 可控制输出分辨率 | 不注意 padding/cropping 容易出错 |
如果你告诉我你的任务(如时间序列预测、异常检测、信号合成等),我可以推荐一个更适合的转置卷积结构或训练示例。
是否想结合实际数据来看下 transposedConv1dLayer
怎么用?我可以帮你搭个 demo
当然可以,我们来详细聊聊 maxPooling1dLayer
——它是 MATLAB 中用于处理一维序列(如时间序列、音频信号等)中的下采样(Downsampling)操作的一种经典层,在深度学习中经常被用于减少特征维度、控制过拟合、提取主要特征等。
maxPooling1dLayer
?maxPooling1dLayer
是一种 一维最大池化层(1D Max Pooling Layer)。它的核心作用是:
将时间序列分成若干窗口,然后对每个窗口内的数值取最大值,从而提取出更显著的特征并压缩数据长度。
它的池化方式只在一维上滑动窗口,适用于如风速预测、电力数据、传感器信号、音频、文本等一维数据。
参数 | 含义 | 示例 |
---|---|---|
PoolSize |
每个池化窗口的长度(必选) | maxPooling1dLayer(2) |
Stride |
窗口移动的步长(默认 = PoolSize) | Stride = 1 |
Padding |
是否对序列首尾补零,防止边缘信息丢失 | "same" / [1 1] |
Name |
层名 | "pool1" |
layer = maxPooling1dLayer(2); % 池化窗口大小为2,默认stride=2
带上更多参数:
layer = maxPooling1dLayer(3, "Stride", 1, "Padding", "same", "Name", "pool1");
PoolSize = 2
)输入序列:[4, 3, 2, 5, 6]
池化操作(非重叠,stride=2):
窗口1:4, 3 → max = 4
窗口2:2, 5 → max = 5
输出为 [4, 5]
若用 "Stride", 1
,窗口重叠:
窗口1:4, 3 → 4
窗口2:3, 2 → 3
窗口3:2, 5 → 5
窗口4:5, 6 → 6
输出为 [4, 3, 5, 6]
对比项 | maxPooling1dLayer |
dropoutLayer / spatialDropoutLayer |
---|---|---|
功能 | 特征压缩、最大值选取 | 随机失活神经元,增强泛化能力 |
是否随机 | ❌ 非随机,确定性 | ✅ 随机遮挡 |
可用于时间序列 | ✅ 非常适合 | ✅(Dropout 需配合注意时间依赖) |
layers = [
sequenceInputLayer(1)
convolution1dLayer(3, 16, "Padding", "same")
reluLayer
maxPooling1dLayer(2, "Stride", 2)
fullyConnectedLayer(1)
regressionLayer];
应用场景 | 建议使用方式 |
---|---|
时间序列降采样 | 使用 PoolSize=2 , Stride=2 |
保留全部序列长度 | 使用 "Padding","same" , Stride=1 |
替代 Dropout 稍微压缩特征 | 可尝试 Stride=1 的 max pooling |
maxPooling1dLayer
的堆叠你可以在不同残差块之间加 max pooling:
conv → norm → relu → pool → conv → norm → relu → pool
用于进一步提炼时间特征。
maxPooling1dLayer
是处理时间序列的好帮手,擅长“保留重要特征”与“特征压缩”。如果你想我 帮你把 maxPooling1dLayer
正确地集成进 TCN 架构函数里,或者整合成一个完整的网络结构,我可以马上动手。要不要我帮你搞定?
averagePooling1dLayer
是 MATLAB 中用于执行一维平均池化操作的层,它主要用于深度学习模型中的下采样过程。池化操作通过将输入数据划分为多个池化区域,并计算每个区域的平均值来减少数据的维度。具体来说,averagePooling1dLayer
会在输入数据的特定维度上执行池化操作。
C
(通道)、B
(批次)和 T
(时间)三个维度),池化操作会在 T
(时间)维度上进行。S
(空间)、C
(通道)和 B
(批次)三个维度),池化操作会在 S
(空间)维度上进行。S
、C
、B
和 T
四个维度),池化操作会在 S
(空间)维度上进行。PoolSize
:
Stride
:
Padding
:
"same"
:将输入填充到输出大小为 ceil(inputSize / stride)
。如果步幅是1,则输出和输入的大小相同。[l r]
:在输入的左侧添加 l
个元素,在右侧添加 r
个元素。PaddingValue
:
0
或 "mean"
,分别表示用零填充或用池化区域的均值填充。PaddingMode
:
manual
(手动填充)或 same
(自动填充)。Name
:
layer = averagePooling1dLayer(3);
这会创建一个池化大小为3的 1-D 平均池化层。
layer = averagePooling1dLayer(3, Padding=1, Stride=2);
这会创建一个池化大小为3,步幅为2,填充为1的 1-D 平均池化层。
averagePooling1dLayer
layers = [
sequenceInputLayer(12, MinLength=40)
convolution1dLayer(11, 96)
reluLayer
averagePooling1dLayer(3)
convolution1dLayer(11, 96)
reluLayer
globalMaxPooling1dLayer
fullyConnectedLayer(10)
softmaxLayer];
在这里,averagePooling1dLayer(3)
层被添加到了一个层数组中,通常用于构建一个完整的神经网络模型。该模型包含了输入层、卷积层、激活函数层、池化层、全连接层等。
时间序列分析:
averagePooling1dLayer
通过在时间维度上进行池化,有助于降低数据的维度并提取数据的主要特征。自然语言处理(NLP):
图像处理:
averagePooling1dLayer
层使用 dlarray
对象传递数据。每个 dlarray
对象代表数据的多个维度,并使用字符串表示每个维度的含义:
"SCB"
:表示空间、通道和批次维度(例如 1-D 图像数据)。"CBT"
:表示通道、批次和时间维度(例如 时间序列数据)。"SCBT"
:表示空间、通道、批次和时间维度(例如 1-D 图像序列数据)。假设你有一个大小为 [1 1 6]
的输入数据,并且使用 averagePooling1dLayer(3)
,步幅为1。池化操作将输入数据划分为三个池化区域,并计算每个区域的平均值。
例如,输入数据为 [1 2 3 4 5 6]
,池化区域大小为3,步幅为1,那么输出将是每个池化区域的平均值,即 [2 3 4 5]
。
averagePooling1dLayer
是一种用于一维数据池化的深度学习层,常用于减少数据的空间或时间维度,从而降低计算复杂度并提取关键特征。它支持灵活的池化区域大小、步幅和填充方式,适用于时间序列、NLP 和图像等多种应用场景。
globalMaxPooling1dLayer
是 MATLAB 中的一种深度学习层,用于执行一维全局最大池化(Global Max Pooling)操作。它通过在输入数据的时间维度或空间维度上输出每个池化区域的最大值来进行下采样。全局最大池化特别适合用来减少数据的维度,同时保留最显著的特征。
T
),也就是说,池化层会在每个时间步上提取最大值。S
),也就是说,池化层会在每个空间位置提取最大值。S
),提取每个空间位置的最大值。全局池化的目的是将输入数据的一个维度(通常是时间或空间维度)压缩为单一的最大值,这有助于保留关键信息而减少计算量。
输入数据:
globalMaxPooling1dLayer
接受一个或多个输入数据。输入数据可以有不同的维度,具体取决于任务的类型。例如,对于时间序列数据,输入可能包含 C
(通道)、B
(批次)和 T
(时间)三个维度;对于图像数据,输入可能包含 S
(空间)、C
(通道)和 B
(批次)三个维度。
池化操作:
层会在输入数据的指定维度上进行池化,计算每个池化区域中的最大值。例如,如果输入是时间序列数据,池化操作会在时间维度(T
)上进行,而对每个通道和批次,输出将是该时间序列的最大值。
Name
:
""
(空字符串)。你可以为层指定一个自定义名称。NumInputs
:
globalMaxPooling1dLayer
,始终是 1,因为该层只接受一个输入。InputNames
:
{'in'}
,表示输入数据。NumOutputs
:
OutputNames
:
{'out'}
。globalMaxPooling1dLayer
创建基本的全局最大池化层:
layer = globalMaxPooling1dLayer;
这将创建一个默认的全局最大池化层。
指定名称创建层:
layer = globalMaxPooling1dLayer(Name='MaxPoolingLayer');
这将创建一个全局最大池化层,并为该层指定名称 'MaxPoolingLayer'
。
globalMaxPooling1dLayer
你可以将 globalMaxPooling1dLayer
层添加到一个层数组中,通常用于构建神经网络。例如:
layers = [
sequenceInputLayer(12, MinLength=20) % 输入层,输入大小为 12
convolution1dLayer(11, 96) % 1-D 卷积层,卷积核大小为 11,输出通道数为 96
reluLayer % ReLU 激活函数层
globalMaxPooling1dLayer % 1-D 全局最大池化层
fullyConnectedLayer(10) % 全连接层,输出大小为 10
softmaxLayer % Softmax 层,用于分类
];
在这个例子中,globalMaxPooling1dLayer
被用作卷积层之后,激活函数层之前的一个下采样层。全局最大池化层会提取输入数据中每个时间或空间维度的最大值,并将其作为该维度的特征。
globalMaxPooling1dLayer
支持多种输入输出格式,取决于数据的维度。常见的输入输出格式如下:
输入格式 | 输出格式 |
---|---|
“SCB” (空间、通道、批次) | “SCB” (空间、通道、批次) |
“CBT” (通道、批次、时间) | “CB” (通道、批次) |
“SCBT” (空间、通道、批次、时间) | “SCBT” (空间、通道、批次、时间) |
“SB” (空间、批次) | “SB” (空间、批次) |
时间序列数据处理:
globalMaxPooling1dLayer
非常适合处理时间序列数据,特别是在需要从时间序列中提取最显著的特征时。例如,金融数据预测、气象数据分析、语音识别等领域。图像数据处理:
globalMaxPooling1dLayer
来减少数据的维度,提取图像的最重要特征。序列分类任务:
C/C++ 代码生成:
GPU 代码生成:
globalMaxPooling1dLayer
是一个用于一维数据的池化层,特别适用于提取时间序列数据或图像数据中的最显著特征。它通过全局最大池化操作对数据进行降维处理,帮助模型专注于最重要的局部特征,并提高计算效率。
flattenLayer
是 MATLAB 中深度学习模型的一个层,专门用于将输入数据的空间维度压缩成通道维度。这一操作通常用于将卷积层的输出(高维数据)转换为全连接层所需的一维格式。该层在卷积神经网络(CNN)和其他深度学习网络中,尤其是在处理图像、视频或其他多维数据时,扮演着至关重要的角色。
flattenLayer
的主要功能是对输入数据进行“扁平化”,即将空间或其他多维度的输入折叠为单一的通道维度。它通过将空间维度(如图像的高度和宽度)与通道维度(如图像的颜色通道)合并来实现这一点。这个过程常见于卷积神经网络(CNN)的最后几层,用于将卷积层输出的多维数据转换为全连接层所需的线性数据。
假设输入数据是一个形状为 H×W×C×N×S
的五维数组,其中:
H
是图像的高度,W
是图像的宽度,C
是通道数,N
是批次大小,S
是时间序列或其他维度(例如图像序列中的时间维度)。在经过 flattenLayer
后,输出数据的形状将从 H×W×C×N×S
变成 (H*W*C)×N×S
,即将空间维度(高度和宽度)与通道维度合并成一个维度。
flattenLayer
默认创建 flattenLayer
:
layer = flattenLayer;
这将创建一个没有名称的默认 flattenLayer
。
指定名称创建 flattenLayer
:
layer = flattenLayer('Name', 'flatten1');
这将创建一个名为 'flatten1'
的 flattenLayer
,你可以使用此名称在网络中进行引用。
Name
:
""
。你可以为层指定一个自定义名称,便于在网络中标识该层。NumInputs
:
flattenLayer
只接受一个输入。InputNames
:
{'in'}
,表示输入数据的名称。NumOutputs
:
OutputNames
:
{'out'}
,表示输出数据的名称。flattenLayer
支持多种输入输出格式,通常是通过 dlarray
对象传递给后续层。以下是一些常见的输入输出格式:
输入格式 | 输出格式 |
---|---|
“CB”(通道、批量) | “CB”(通道、批量) |
“SCB”(空间、通道、批量) | “SSCB”(空间、空间、通道、批量) |
“CBT”(通道、批量、时间) | “CBT”(通道、批量、时间) |
“SCBT”(空间、通道、批量、时间) | “SSCBT”(空间、空间、通道、批量、时间) |
“CU”(通道、未指定) | “CU”(通道、未指定) |
这些格式指定了数据维度的顺序。flattenLayer
会将输入数据的空间维度(如 H
和 W
)与通道维度(C
)进行合并,最终输出的数据将具有 (H * W * C)
维度。
卷积神经网络(CNN):
flattenLayer
常常用于将卷积层的输出数据展平为一维数据。卷积层输出的数据通常是多维的,包含空间维度和通道维度,而全连接层要求输入的数据是一维的。flattenLayer
将这些多维数据展平成一维,以便传递到全连接层进行分类或回归任务。视频分类:
flattenLayer
可以用于将每一帧图像的特征向量展平,以便进一步处理。视频数据通常有时间维度(即帧数),通过 flattenLayer
,我们可以将每一帧图像的数据展平为一个一维向量,然后对整个视频进行分类。序列建模:
flattenLayer
可以帮助将时间步的数据展平,从而使得下游的全连接层可以直接处理这些数据。C/C++ 代码生成:
flattenLayer
和整个神经网络模型部署到硬件平台。GPU 代码生成:
flattenLayer
是在 MATLAB R2019a 中首次引入的。flattenLayer
支持复数值输入和输出,可以进行复数运算,并输出复数数据。以下是使用 flattenLayer
的示例,展示了如何在神经网络中使用它:
% 创建一个简单的卷积神经网络
layers = [
imageInputLayer([28 28 1]) % 输入层,28x28的单通道图像
convolution2dLayer(3, 8) % 卷积层,3x3的卷积核,8个输出通道
reluLayer % ReLU 激活函数
flattenLayer % 扁平化层,将卷积层输出展平
fullyConnectedLayer(10) % 全连接层,10个输出节点(对应于10个类别)
softmaxLayer % Softmax 层,用于多分类
classificationLayer]; % 分类层
% 查看网络结构
lgraph = layerGraph(layers);
plot(lgraph);
在这个例子中,flattenLayer
被添加到卷积层和全连接层之间,用于将卷积层输出的三维数据(高度、宽度和通道)展平为一维数据,方便全连接层进行处理。
flattenLayer
是一个用于将高维数据(如图像、视频或多维序列数据)展平为一维数据的深度学习层。它常用于卷积神经网络(CNN)中,将卷积层的多维输出转换为适合全连接层处理的格式。通过将空间维度和通道维度折叠在一起,flattenLayer
可以有效地为后续的网络层准备输入数据。
wordEmbeddingLayer
是 MATLAB 中用于深度学习的一个层,专门用于将词汇索引映射到词向量(词嵌入)。它通常用于长短期记忆网络(LSTM)等序列建模任务中,将单词的索引转换为可以捕捉词义的密集向量。该层通过训练来学习词嵌入,可以将输入的文本数据转化为适合模型训练的表示。
wordEmbeddingLayer
的核心功能是将词汇的索引映射到对应的词向量。它将每个词汇(由其索引表示)转换为一个固定维度的向量,这些向量在训练过程中会被学习,从而捕捉词汇之间的语义关系。
词嵌入:通过该层,模型可以将每个词的索引映射到一个高维的向量空间中,每个词的向量表示其在语义空间中的位置。词向量通常能捕捉到词与词之间的相似性,类似的词会被映射到相似的向量。
训练过程:在训练过程中,wordEmbeddingLayer
会根据网络的损失函数学习到每个词的向量表示。这些表示会随着网络的训练逐渐优化。
Dimension
:词向量的维度(即每个词的嵌入向量的大小)。
Dimension = 300
表示每个词将用一个 300 维的向量来表示。NumWords
:词汇表的大小,即模型可以处理的唯一词汇的数量。
NumWords
,则超出词汇表的词将被映射到一个单独的向量(通常称为“out-of-vocabulary”词汇)。NumWords = 5000
表示词汇表最多包含 5000 个词。OOVMode
:如何处理超出词汇表的词汇(Out-of-Vocabulary, OOV):
"map-to-last"
(默认值):将 OOV 词映射到最后一个嵌入向量。"error"
:当遇到 OOV 词时抛出错误。适用于一些已经有 OOV token(如 BERT)模型。WeightsInitializer
:初始化词嵌入向量的方式。常见的初始化方式包括:
'narrow-normal'
:从均值为 0,标准差为 0.01 的正态分布中独立采样。'glorot'
:Glorot 初始化(也叫 Xavier 初始化),适用于神经网络的权重初始化。'he'
:He 初始化,适用于更深的神经网络。'orthogonal'
:正交初始化,生成正交矩阵来初始化权重。'zeros'
或 'ones'
:将权重初始化为全零或全一。function handle
:使用自定义函数初始化权重。Weights
:存储词嵌入的权重矩阵。通常,权重矩阵是一个 [Dimension, NumWords]
的矩阵,每列对应一个词汇的词向量。
NumWords + 1
来包括超出词汇表的 OOV 词汇,矩阵的大小为 [Dimension, NumWords+1]
。WeightLearnRateFactor
:学习率因子,用于调整该层的学习速率。通常可以设置为 1
,表示该层的学习率与全局学习率相同。
WeightL2Factor
:L2 正则化因子,用于对词嵌入进行 L2 正则化,防止过拟合。
wordEmbeddingLayer
layer = wordEmbeddingLayer(dimension, numWords)
这将创建一个 wordEmbeddingLayer
,其中:
dimension
是每个词的向量维度。numWords
是词汇表的大小。layer = wordEmbeddingLayer(dimension, numWords, 'OOVMode', 'error')
通过这种方式,你可以设置 OOVMode
为 "error"
,当遇到超出词汇表的词时抛出错误。
dimension = 300; % 每个词的向量维度
numWords = 5000; % 词汇表大小
layer = wordEmbeddingLayer(dimension, numWords);
这会创建一个词嵌入层,每个词由 300 维的向量表示,且词汇表最多包含 5000 个词。
inputSize = 1; % 输入是每个词的索引
embeddingDimension = 300;
numWords = 5000;
numHiddenUnits = 200;
numClasses = 10;
layers = [
sequenceInputLayer(inputSize)
wordEmbeddingLayer(embeddingDimension, numWords)
lstmLayer(numHiddenUnits, 'OutputMode', 'last')
fullyConnectedLayer(numClasses)
softmaxLayer
];
这个例子展示了如何将 wordEmbeddingLayer
用于 LSTM 网络。首先,输入层接收词的索引,接着通过 wordEmbeddingLayer
将这些索引转换为词向量,然后输入到 LSTM 层进行处理,最终通过全连接层和 Softmax 层输出分类结果。
emb = fastTextWordEmbedding; % 加载预训练的 fastText 词向量
words = emb.Vocabulary;
dimension = emb.Dimension;
numWords = numel(words);
layer = wordEmbeddingLayer(dimension, numWords, 'Weights', word2vec(emb, words)');
在这个例子中,我们使用 fastTextWordEmbedding
加载预训练的词嵌入,并使用 word2vec
函数将其加载到 wordEmbeddingLayer
中。这样,我们可以将预训练的词嵌入作为初始化权重。
C/C++ 代码生成:
wordEmbeddingLayer
支持通过 MATLAB Coder™ 生成 C 和 C++ 代码。这对于将模型部署到嵌入式设备或其他硬件平台很有用。GPU 代码生成:
wordEmbeddingLayer
。OOVMode
属性,允许更灵活地处理超出词汇表的词汇(OOV)。wordEmbeddingLayer
是一个强大的层,用于将文本中的词汇映射到高维空间中的词向量。这些词向量在深度学习训练过程中不断优化,捕捉到词汇之间的语义关系。它广泛应用于各种自然语言处理(NLP)任务中,特别是在需要处理序列数据的任务(如情感分析、文本分类、机器翻译等)中。
在 MATLAB 中,定义自定义循环深度学习层允许您创建不属于 MATLAB 深度学习工具箱内置层的特殊层。循环神经网络(RNN)和长短期记忆(LSTM)网络等需要的功能可以通过创建自定义层来实现。自定义层使您能够灵活地添加新的神经网络操作或实现标准操作的变种,以满足特定任务的需求。
定义自定义循环深度学习层通常包括以下几个步骤:
首先,为您的自定义层指定一个名称,并为该层创建一个类。类名应该与文件名相匹配。层可以是一个标准的 RNN 层(如 LSTM),也可以是自定义的变种(如带有 “peephole” 的 LSTM)。例如,您可以为 peephole LSTM
创建一个类名为 peepholeLSTMLayer
。
classdef peepholeLSTMLayer < nnet.layer.Layer & nnet.layer.Formattable
% 定义层类,继承自 nnet.layer.Layer 并且支持格式化输入输出
定义层的属性,包括:
properties
% 普通层属性
NumHiddenUnits
OutputMode
end
properties (Learnable)
% 可学习的参数(例如权重和偏置)
InputWeights
RecurrentWeights
PeepholeWeights
Bias
end
properties (State)
% 状态参数(例如隐藏状态和细胞状态)
HiddenState
CellState
end
构造函数用于初始化层的基本属性,如隐藏单元的数量、输出模式(例如返回整个序列还是最后一个时间步)。您还可以设置其他可选参数(例如层名称)。
methods
function layer = peepholeLSTMLayer(numHiddenUnits, args)
% PEEPHOLELSTMLAYER 构造函数
arguments
numHiddenUnits
args.Name = "";
args.OutputMode = "sequence";
end
layer.NumHiddenUnits = numHiddenUnits;
layer.Name = args.Name;
layer.OutputMode = args.OutputMode;
% 设置层描述
layer.Description = "Peephole LSTM with " + numHiddenUnits + " hidden units";
end
end
初始化函数用于设置学习参数(如权重、偏置)和状态参数(如隐藏状态、细胞状态)。例如,可以使用 Xavier 或 Glorot 初始化法来初始化权重。
function layer = initialize(layer, layout)
% 初始化层的学习和状态参数
numHiddenUnits = layer.NumHiddenUnits;
% 获取输入数据的通道数
idx = finddim(layout, "C");
numChannels = layout.Size(idx);
% 初始化输入权重
if isempty(layer.InputWeights)
sz = [4 * numHiddenUnits, numChannels];
layer.InputWeights = initializeGlorot(sz, 4 * numHiddenUnits, numChannels);
end
% 初始化递归权重
if isempty(layer.RecurrentWeights)
sz = [4 * numHiddenUnits, numHiddenUnits];
layer.RecurrentWeights = initializeOrthogonal(sz);
end
% 初始化 "peephole" 权重
if isempty(layer.PeepholeWeights)
sz = [3 * numHiddenUnits, 1];
layer.PeepholeWeights = initializeGlorot(sz, 3 * numHiddenUnits, 1);
end
% 初始化偏置
if isempty(layer.Bias)
layer.Bias = initializeUnitForgetGate(numHiddenUnits);
end
% 初始化状态(隐藏状态和细胞状态)
if isempty(layer.HiddenState)
layer.HiddenState = zeros(numHiddenUnits, 1);
end
if isempty(layer.CellState)
layer.CellState = zeros(numHiddenUnits, 1);
end
end
initializeGlorot
、initializeOrthogonal
和 initializeUnitForgetGate
是初始化权重的辅助函数。您可以自定义这些函数来选择合适的初始化方法。前向传播函数定义了如何计算从输入到输出的数据流动。例如,peephole LSTM
层的前向传播会执行各个门(输入门、遗忘门、输出门)和细胞状态的更新。
function [Y, cellState, hiddenState] = predict(layer, X)
% 前向传播函数
numHiddenUnits = layer.NumHiddenUnits;
miniBatchSize = size(X, finddim(X, "B"));
numTimeSteps = size(X, finddim(X, "T"));
if layer.OutputMode == "sequence"
Y = zeros(numHiddenUnits, miniBatchSize, numTimeSteps, "like", X);
Y = dlarray(Y, "CBT");
end
X = stripdims(X);
WX = pagemtimes(layer.InputWeights, X) + layer.Bias;
% 初始化状态
hiddenState = layer.HiddenState;
cellState = layer.CellState;
for t = 1:numTimeSteps
Rht = layer.RecurrentWeights * hiddenState;
pict = layer.PeepholeWeights(1:numHiddenUnits) .* cellState;
pfct = layer.PeepholeWeights(numHiddenUnits+1:2*numHiddenUnits) .* cellState;
it = sigmoid(WX(1:numHiddenUnits, :, t) + Rht(1:numHiddenUnits) + pict);
ft = sigmoid(WX(numHiddenUnits+1:2*numHiddenUnits, :, t) + Rht(numHiddenUnits+1:2*numHiddenUnits) + pfct);
gt = tanh(WX(2*numHiddenUnits+1:3*numHiddenUnits, :, t) + Rht(2*numHiddenUnits+1:3*numHiddenUnits));
cellState = gt .* it + cellState .* ft;
ot = sigmoid(WX(3*numHiddenUnits+1:4*numHiddenUnits, :, t) + Rht(3*numHiddenUnits+1:4*numHiddenUnits) + cellState);
hiddenState = tanh(cellState) .* ot;
if layer.OutputMode == "sequence"
Y(:, :, t) = hiddenState;
end
end
if layer.OutputMode == "last"
Y = dlarray(hiddenState, "CB");
end
end
resetState
函数用于重置隐藏状态和细胞状态。对于循环层,状态通常需要在每个训练周期开始时进行重置。
function layer = resetState(layer)
% 重置状态
numHiddenUnits = layer.NumHiddenUnits;
layer.HiddenState = zeros(numHiddenUnits, 1);
layer.CellState = zeros(numHiddenUnits, 1);
end
反向传播函数用于计算损失对输入数据和可学习参数的梯度。如果使用 dlarray
对象并且前向传播函数支持自动微分,则反向传播函数是可选的。
function [dLdX, dLdW, dLdSin] = backward(layer, X, Y, dLdY, dLdSout, memory)
% 反向传播
end
最终,您可以将 peephole LSTM
层与其他标准层结合,构建一个复杂的深度学习网络,并进行训练和预测。
如果您的自定义层支持 dlarray
对象,那么它自然支持 GPU 加速。如果需要,您还可以通过将输入和输出数据指定为 gpuArray
类型,进一步加速计算。
您可以像使用其他标准层一样使用自定义层。例如,使用 peephole LSTM
层进行序列分类任务:
inputSize = 12;
numHiddenUnits = 100;
numClasses = 9;
layers = [
sequenceInputLayer(inputSize)
peepholeLSTMLayer(numHiddenUnits, OutputMode="last")
fullyConnectedLayer(numClasses)
softmaxLayer
classificationLayer];
options = trainingOptions("adam", "ExecutionEnvironment", "cpu", "MiniBatchSize", 27);
net = trainNetwork(XTrain, TTrain, layers, options);
通过定义自定义循环深度学习层,您可以在 MATLAB 中实现自定义的 RNN、LSTM 或其他变种。这些层可以用于复杂的时间序列建模任务,并且支持 GPU 加速、自动微分和自定义初始化方法。通过这一功能,您可以灵活地构建和扩展深度学习模型。