序列输入层:深入解析与应用
1. 序列输入层概述
序列输入层用于将序列数据输入到神经网络中。它为神经网络处理随时间或其他顺序排列的数据提供了基础,是构建处理序列数据网络的重要组成部分。
1.1 创建序列输入层
创建序列输入层有两种主要的语法形式:
-
layer = sequenceInputLayer(inputSize)
:创建一个序列输入层并设置
InputSize
属性。
-
layer = sequenceInputLayer(inputSize,Name,Value)
:使用名称 - 值对设置可选的
MinLength
、
Normalization
、
Mean
和
Name
属性,可以指定多个名称 - 值对,每个属性名需用单引号括起来。
1.2 序列输入层的属性
1.2.1 输入大小(InputSize)
输入大小可以是正整数或正整数向量,根据不同的输入类型有不同的表示:
| 输入类型 | InputSize 表示 |
| ---- | ---- |
| 向量序列输入 | 对应特征数量的标量 |
| 1 - D 图像序列输入 | 包含两个元素的向量
[h c]
,其中
h
是图像高度,
c
是图像通道数 |
| 2 - D 图像序列输入 | 包含三个元素的向量
[h w c]
,其中
h
是图像高度,
w
是图像宽度,
c
是图像通道数 |
| 3 - D 图像序列输入 | 包含四个元素的向量
[h w d c]
,其中
h
是图像高度,
w
是图像宽度,
d
是图像深度,
c
是图像通道数 |
1.2.2 最小序列长度(MinLength)
输入数据的最小序列长度,默认为 1。在训练或进行预测时,如果输入数据的时间步少于
MinLength
,软件将抛出错误。在创建在时间维度上对数据进行下采样的网络时,需要确保网络支持训练数据和预测数据。一些深度学习层要求输入有最小序列长度,例如 1 - D 卷积层要求输入的时间步至少与滤波器大小相同。为防止卷积和池化层改变数据大小,可以将层的
Padding
选项设置为
"same"
或
"causal"
。
1.2.3 数据归一化(Normalization)
每次数据通过输入层前向传播时应用的数据归一化方式,有以下几种可选:
-
'zerocenter'
:减去
Mean
指定的均值。
-
'zscore'
:减去
Mean
指定的均值并除以
StandardDeviation
。
-
'rescale - symmetric'
:使用
Min
和
Max
指定的最小值和最大值将输入重新缩放到
[-1, 1]
范围。
-
'rescale - zero - one'
:使用
Min
和
Max
指定的最小值和最大值将输入重新缩放到
[0, 1]
范围。
-
'none'
:不进行输入数据归一化。
- 函数句柄:使用指定的函数对数据进行归一化,函数形式必须为
Y = func(X)
,其中
X
是输入数据,
Y
是归一化后的数据。
1.2.4 归一化维度(NormalizationDimension)
归一化维度有以下几种可选:
-
'auto'
:如果训练选项为
false
且指定了任何归一化统计量(
Mean
、
StandardDeviation
、
Min
或
Max
),则在与统计量匹配的维度上进行归一化;否则,在训练时重新计算统计量并应用通道级归一化。
-
'channel'
:通道级归一化。
-
'element'
:元素级归一化。
-
'all'
:使用标量统计量对所有值进行归一化。
1.2.5 均值(Mean)
用于零中心和 z - 分数归一化的均值,可以是数值数组或空数组。如果指定了
Mean
属性,
Normalization
必须为
'zerocenter'
或
'zscore'
。如果
Mean
为空,
trainNetwork
函数将计算均值并忽略填充值。在使用自定义训练循环训练
dlnetwork
对象或使用
assembleNetwork
函数组装网络而不进行训练时,必须将
Mean
属性设置为数值标量或数值数组。
1.2.6 标准差(StandardDeviation)
用于 z - 分数归一化的标准差,可以是数值数组、数值标量或空数组。如果指定了
StandardDeviation
属性,
Normalization
必须为
'zscore'
。如果
StandardDeviation
为空,
trainNetwork
函数将计算均值并忽略填充值。在使用自定义训练循环训练
dlnetwork
对象或使用
assembleNetwork
函数组装网络而不进行训练时,必须将
StandardDeviation
属性设置为数值标量或数值数组。
1.2.7 最小值(Min)
用于重新缩放的最小值,可以是数值数组或空数组。如果指定了
Min
属性,
Normalization
必须为
'rescale - symmetric'
或
'rescale - zero - one'
。如果
Min
为空,
trainNetwork
函数将计算最小值并忽略填充值。在使用自定义训练循环训练
dlnetwork
对象或使用
assembleNetwork
函数组装网络而不进行训练时,必须将
Min
属性设置为数值标量或数值数组。
1.2.8 最大值(Max)
用于重新缩放的最大值,可以是数值数组或空数组。如果指定了
Max
属性,
Normalization
必须为
'rescale - symmetric'
或
'rescale - zero - one'
。如果
Max
为空,
trainNetwork
函数将计算最大值并忽略填充值。在使用自定义训练循环训练
dlnetwork
对象或使用
assembleNetwork
函数组装网络而不进行训练时,必须将
Max
属性设置为数值标量或数值数组。
1.2.9 拆分复输入(SplitComplexInputs)
这是一个只读属性,用于指定是否将输入数据拆分为实部和虚部:
-
0 (false)
:不拆分输入数据。
-
1 (true)
:将数据拆分为实部和虚部。当
SplitComplexInputs
为 1 时,层的输出通道数是输入数据的两倍。要将复值数据输入到神经网络中,输入层的
SplitComplexInputs
选项必须为 1。
1.2.10 层名称(Name)
层的名称,可以是字符向量或字符串标量。对于层数组输入,
trainNetwork
、
assembleNetwork
、
layerGraph
和
dlnetwork
函数会自动为名称为空的层分配名称。
1.2.11 输入数量(NumInputs)
这是一个只读属性,该层的输入数量为 0。
1.2.12 输入名称(InputNames)
这是一个只读属性,该层没有输入,输入名称为空。
1.2.13 输出数量(NumOutputs)
这是一个只读属性,该层只有一个输出。
1.2.14 输出名称(OutputNames)
这是一个只读属性,该层的输出名称默认为
{'out'}
。
1.3 序列输入层的创建示例
1.3.1 创建具有指定名称和输入大小的序列输入层
layer = sequenceInputLayer(12,'Name','seq1')
1.3.2 在层数组中包含序列输入层
inputSize = 12;
numHiddenUnits = 100;
numClasses = 9;
layers = [ ...
sequenceInputLayer(inputSize)
lstmLayer(numHiddenUnits,'OutputMode','last')
fullyConnectedLayer(numClasses)
softmaxLayer
classificationLayer]
1.3.3 创建用于图像序列的序列输入层
layer = sequenceInputLayer([224 224 3], 'Name', 'seq1')
1.4 训练序列分类网络示例
1.4.1 加载数据集
[XTrain,YTrain] = japaneseVowelsTrainData;
1.4.2 可视化第一个时间序列
figure
plot(XTrain{1}')
title("Training Observation 1")
numFeatures = size(XTrain{1},1);
legend("Feature " + string(1:numFeatures),'Location','northeastoutside')
1.4.3 定义 LSTM 网络架构
inputSize = 12;
numHiddenUnits = 100;
numClasses = 9;
layers = [ ...
sequenceInputLayer(inputSize)
lstmLayer(numHiddenUnits,'OutputMode','last')
fullyConnectedLayer(numClasses)
softmaxLayer
classificationLayer]
1.4.4 指定训练选项
maxEpochs = 70;
miniBatchSize = 27;
options = trainingOptions('adam', ...
'ExecutionEnvironment','cpu', ...
'MaxEpochs',maxEpochs, ...
'MiniBatchSize',miniBatchSize, ...
'GradientThreshold',1, ...
'Verbose',false, ...
'Plots','training - progress');
1.4.5 训练 LSTM 网络
net = trainNetwork(XTrain,YTrain,layers,options);
1.4.6 加载测试集并进行分类
[XTest,YTest] = japaneseVowelsTestData;
YPred = classify(net,XTest,'MiniBatchSize',miniBatchSize);
1.4.7 计算分类准确率
acc = sum(YPred == YTest)./numel(YTest)
1.5 不同类型 LSTM 网络的构建
1.5.1 序列到标签分类的 LSTM 网络
numFeatures = 12;
numHiddenUnits = 100;
numClasses = 9;
layers = [ ...
sequenceInputLayer(numFeatures)
lstmLayer(numHiddenUnits,'OutputMode','last')
fullyConnectedLayer(numClasses)
softmaxLayer
classificationLayer];
1.5.2 序列到序列分类的 LSTM 网络
numFeatures = 12;
numHiddenUnits = 100;
numClasses = 9;
layers = [ ...
sequenceInputLayer(numFeatures)
lstmLayer(numHiddenUnits,'OutputMode','sequence')
fullyConnectedLayer(numClasses)
softmaxLayer
classificationLayer];
1.5.3 序列到单值回归的 LSTM 网络
numFeatures = 12;
numHiddenUnits = 125;
numResponses = 1;
layers = [ ...
sequenceInputLayer(numFeatures)
lstmLayer(numHiddenUnits,'OutputMode','last')
fullyConnectedLayer(numResponses)
regressionLayer];
1.5.4 序列到序列回归的 LSTM 网络
numFeatures = 12;
numHiddenUnits = 125;
numResponses = 1;
layers = [ ...
sequenceInputLayer(numFeatures)
lstmLayer(numHiddenUnits,'OutputMode','sequence')
fullyConnectedLayer(numResponses)
regressionLayer];
1.5.5 更深的 LSTM 网络
numFeatures = 12;
numHiddenUnits1 = 125;
numHiddenUnits2 = 100;
numClasses = 9;
layers = [ ...
sequenceInputLayer(numFeatures)
lstmLayer(numHiddenUnits1,'OutputMode','sequence')
dropoutLayer(0.2)
lstmLayer(numHiddenUnits2,'OutputMode','last')
dropoutLayer(0.2)
fullyConnectedLayer(numClasses)
softmaxLayer
classificationLayer];
1.6 视频分类网络的创建
1.6.1 网络架构定义
inputSize = [28 28 1];
filterSize = 5;
numFilters = 20;
numHiddenUnits = 200;
numClasses = 10;
layers = [ ...
sequenceInputLayer(inputSize,'Name','input')
sequenceFoldingLayer('Name','fold')
convolution2dLayer(filterSize,numFilters,'Name','conv')
batchNormalizationLayer('Name','bn')
reluLayer('Name','relu')
sequenceUnfoldingLayer('Name','unfold')
flattenLayer('Name','flatten')
lstmLayer(numHiddenUnits,'OutputMode','last','Name','lstm')
fullyConnectedLayer(numClasses, 'Name','fc')
softmaxLayer('Name','softmax')
classificationLayer('Name','classification')];
1.6.2 转换为层图并连接层
lgraph = layerGraph(layers);
lgraph = connectLayers(lgraph,'fold/miniBatchSize','unfold/miniBatchSize');
1.6.3 查看网络架构
figure
plot(lgraph)
1.7 版本历史
- R2017b:引入序列输入层。
-
R2019b:默认情况下,序列输入层对零中心归一化使用通道级归一化,之前版本使用元素级归一化。若要重现之前的行为,可将
NormalizationDimension选项设置为'element'。 -
R2020a:
trainNetwork在计算归一化统计量时忽略填充值,这使得序列输入层的Normalization选项使训练对数据操作具有不变性。
1.8 扩展功能
1.8.1 C/C++ 代码生成
使用 MATLAB® Coder™ 生成 C 和 C++ 代码时,有以下限制:
- 对于向量序列输入,特征数量在代码生成期间必须为常量。
- 输入数据必须包含零个或两个空间维度。
- 代码生成不支持使用函数句柄指定的
Normalization
。
- 代码生成不支持复输入和
SplitComplexInputs
选项。
1.8.2 GPU 代码生成
使用 GPU Coder™ 为 NVIDIA® GPUs 生成 CUDA® 代码时,有以下使用说明和限制:
- 必须先构建和训练深度神经网络,然后配置代码生成器生成代码并部署卷积神经网络。
- cuDNN 库支持向量和 2 - D 图像序列,TensorRT 库仅支持向量输入序列。
- 对于向量序列输入,特征数量在代码生成期间必须为常量。
- 对于图像序列输入,高度、宽度和通道数在代码生成期间必须为常量。
- 代码生成不支持使用函数句柄指定的
Normalization
。
- 代码生成不支持复输入和
SplitComplexInputs
选项。
1.9 相关函数和主题
-
相关函数:
trainNetwork、lstmLayer、bilstmLayer、gruLayer、classifyAndUpdateState、predictAndUpdateState、resetState、sequenceFoldingLayer、flattenLayer、sequenceUnfoldingLayer、Deep Network Designer、featureInputLayer。 - 相关主题:“Sequence Classification Using Deep Learning”、“Time Series Forecasting Using Deep Learning”、“Sequence - to - Sequence Classification Using Deep Learning”、“Classify Videos Using Deep Learning”、“Visualize Activations of LSTM Network”、“Long Short - Term Memory Neural Networks”、“Specify Layers of Convolutional Neural Network”、“Set Up Parameters and Train Convolutional Neural Network”、“Deep Learning in MATLAB”、“List of Deep Learning Layers”。
通过以上对序列输入层的详细介绍,我们可以看到它在处理各种序列数据的神经网络中起着重要的作用。无论是简单的序列分类还是复杂的视频分类,序列输入层都为数据的输入和处理提供了基础。在实际应用中,我们可以根据具体的需求选择合适的属性设置和网络架构,以达到最佳的训练和预测效果。同时,要注意不同版本之间的行为变化以及代码生成的限制,确保在不同的环境中能够正确地使用序列输入层。
2. 序列输入层的应用场景与注意事项
2.1 应用场景分析
序列输入层在众多领域都有广泛的应用,以下是一些常见的场景:
2.1.1 语音识别
在语音识别任务中,语音信号是典型的序列数据。通过序列输入层将语音信号输入到神经网络中,结合 LSTM 等循环神经网络层,可以捕捉语音信号中的时序信息,从而实现准确的语音识别。例如,在上述的日语元音数据集的例子中,将语音特征作为序列数据输入到网络中进行分类,就是语音识别中的一个简单示例。
2.1.2 自然语言处理
在自然语言处理领域,文本数据可以看作是单词或字符的序列。序列输入层可以将文本数据输入到网络中,为后续的语义理解、情感分析、机器翻译等任务提供基础。例如,在机器翻译中,输入的源语言句子是一个单词序列,通过序列输入层和合适的网络架构,可以将其翻译成目标语言的句子。
2.1.3 视频分析
视频数据是由一系列图像帧组成的序列。使用序列输入层可以将视频帧序列输入到网络中,结合卷积层和循环层,可以实现视频分类、目标跟踪等任务。如前面提到的视频分类网络的创建,就是利用序列输入层处理视频序列数据。
2.2 注意事项
在使用序列输入层时,需要注意以下几个方面:
2.2.1 最小序列长度
在创建网络时,要根据实际数据的特点合理设置
MinLength
属性。如果设置不当,可能会导致在训练或预测时出现错误。例如,当使用 1 - D 卷积层时,要确保输入数据的时间步不少于滤波器大小,否则会因为序列长度不足而报错。同时,在进行下采样操作时,要考虑到序列长度的变化,避免后续层因为序列长度过短而无法正常工作。
2.2.2 归一化设置
归一化操作可以提高网络的训练效率和稳定性,但不同的归一化方式和归一化维度会对结果产生影响。在选择归一化方式时,要根据数据的特点和任务的需求进行选择。例如,如果数据的均值和标准差比较稳定,可以选择
'zscore'
归一化;如果希望将数据缩放到特定的范围,可以选择
'rescale - symmetric'
或
'rescale - zero - one'
归一化。同时,要注意在不同版本中归一化的默认行为可能会发生变化,需要根据实际情况进行调整。
2.2.3 代码生成限制
在进行代码生成时,要充分考虑到 C/C++ 代码生成和 GPU 代码生成的限制。例如,对于向量序列输入,特征数量在代码生成期间必须为常量;代码生成不支持使用函数句柄指定的
Normalization
以及复输入和
SplitComplexInputs
选项。在实际应用中,如果需要进行代码生成,要提前规划好网络架构和数据处理方式,以满足代码生成的要求。
3. 总结与展望
3.1 总结
序列输入层是处理序列数据的神经网络中的重要组成部分,它为神经网络提供了输入序列数据的接口。通过合理设置序列输入层的属性,如
InputSize
、
MinLength
、
Normalization
等,可以适应不同类型的序列数据和任务需求。同时,结合 LSTM、卷积层等其他神经网络层,可以构建出各种复杂的网络架构,用于语音识别、自然语言处理、视频分析等多个领域。
在实际应用中,要注意最小序列长度、归一化设置和代码生成限制等问题,以确保网络的正常运行和训练效果。通过本文介绍的各种示例,我们可以看到序列输入层在不同场景下的具体应用方式,为进一步的研究和实践提供了参考。
3.2 展望
随着深度学习技术的不断发展,序列输入层也可能会有更多的改进和扩展。例如,在处理更复杂的序列数据时,可能需要更灵活的归一化方式和输入处理方法;在代码生成方面,可能会有更多的优化和支持,以提高代码的性能和可移植性。同时,结合其他新兴技术,如强化学习、生成对抗网络等,序列输入层可能会在更多的领域得到应用,为解决实际问题提供更强大的工具。
未来,我们可以期待序列输入层在深度学习中的应用越来越广泛,为推动人工智能技术的发展做出更大的贡献。
4. 流程图示例
graph TD;
A[创建序列输入层] --> B[设置输入大小];
B --> C{是否需要设置其他属性};
C -- 是 --> D[设置 MinLength、Normalization 等属性];
C -- 否 --> E[构建网络架构];
D --> E;
E --> F[训练网络];
F --> G[进行预测];
G --> H{是否需要代码生成};
H -- 是 --> I[检查代码生成限制并生成代码];
H -- 否 --> J[结束];
I --> J;
这个流程图展示了使用序列输入层的基本流程,从创建序列输入层开始,经过属性设置、网络构建、训练和预测等步骤,最后根据需要进行代码生成。通过这个流程图,可以更直观地了解使用序列输入层的整个过程。
5. 常见问题解答
5.1 问:如何确定
InputSize
的值?
答:
InputSize
的值根据输入数据的类型而定。对于向量序列输入,它是特征的数量;对于图像序列输入,根据图像的维度不同,分别是包含图像高度、宽度、深度和通道数的向量。例如,对于 2 - D 图像序列输入,
InputSize
是
[h w c]
,其中
h
是图像高度,
w
是图像宽度,
c
是图像通道数。
5.2 问:
MinLength
属性有什么作用?
答:
MinLength
属性指定了输入数据的最小序列长度。在训练或预测时,如果输入数据的时间步少于
MinLength
,软件会抛出错误。在创建在时间维度上对数据进行下采样的网络时,要确保网络支持的最小序列长度不小于
MinLength
,以避免后续层因为序列长度不足而无法正常工作。
5.3 问:不同的归一化方式有什么区别?
答:不同的归一化方式有不同的作用。
'zerocenter'
归一化是减去
Mean
指定的均值;
'zscore'
归一化是减去均值并除以标准差;
'rescale - symmetric'
归一化是将输入缩放到
[-1, 1]
范围;
'rescale - zero - one'
归一化是将输入缩放到
[0, 1]
范围;
'none'
表示不进行归一化;使用函数句柄则可以自定义归一化函数。选择哪种归一化方式要根据数据的特点和任务的需求来决定。
5.4 问:在代码生成时需要注意什么?
答:在进行 C/C++ 代码生成和 GPU 代码生成时,有一些限制需要注意。例如,对于向量序列输入,特征数量在代码生成期间必须为常量;输入数据必须包含零个或两个空间维度;代码生成不支持使用函数句柄指定的
Normalization
以及复输入和
SplitComplexInputs
选项。在进行代码生成前,要确保网络架构和数据处理方式满足这些限制条件。
通过以上的总结、展望、流程图和常见问题解答,我们对序列输入层有了更全面的了解。希望本文能够帮助读者更好地使用序列输入层,在深度学习领域取得更好的成果。
超级会员免费看
5206

被折叠的 条评论
为什么被折叠?



