使用内存不足序列数据训练网络
这个例子展示了如何通过转换和组合数据存储在内存不足的序列数据上训练深度学习网络。
转换后的数据存储转换或处理从底层数据存储读取的数据。您可以使用转换后的数据存储作为深度学习应用程序的训练、验证、测试和预测数据集的来源。使用转换后的数据存储来读取内存不足的数据,或者在读取批量数据时执行特定的预处理操作。当你拥有包含预测器和标签的独立数据存储时,你可以将它们组合起来,以便将数据输入深度学习网络。
当训练网络时,软件通过填充、截断或分割输入数据来创建相同长度的小批量序列。对于内存中的数据,使用trainingOptions
函数提供填充和截断输入序列的选项,但是,对于内存不足的数据,必须手动填充和截断序列。
负荷训练数据
按照[1]和[2]中的描述加载Japanese Vowels数据集。zip文件japaneseVowels.zip
包含不同长度的序列。序列被分成两个文件夹,火车
而且测试
,分别包含训练序列和测试序列。在每个文件夹中,序列被划分为子文件夹,子文件夹从1
来9
.这些子文件夹的名称就是标签名称。一个MAT文件表示每个序列。每个序列都是一个有12行的矩阵,每个特征都有一行,列数不同,每个时间步有一列。行数是序列维数,列数是序列长度。
解压缩序列数据。
文件名=“japaneseVowels.zip”;outputFolder = fullfile(tempdir,“japaneseVowels”);解压缩(文件名,outputFolder);
对于训练预测器,创建一个文件数据存储,并将读取函数指定为负载
函数。的负载
函数,将mat文件中的数据加载到结构数组中。若要从培训文件夹中的子文件夹中读取文件,请设置“IncludeSubfolders”
选项真正的
.
folderTrain = fullfile(输出文件夹,“训练”);fdsPredictorTrain = fileDatastore(文件夹火车,...“ReadFcn”@load,...“IncludeSubfolders”,真正的);
预览数据存储。返回的结构体包含来自第一个文件的单个序列。
预览(fdsPredictorTrain)
ans =带字段的结构:X: [12×20 double]
对于标签,创建一个文件数据存储,并指定read函数为readLabel
函数,在示例的末尾定义。的readLabel
函数从子文件夹名称中提取标签。
classNames = string(1:9);fdsLabelTrain = fileDatastore(文件夹火车,...“ReadFcn”@(文件名)readLabel(文件名,类名),...“IncludeSubfolders”,真正的);
预览数据存储。输出与第一个文件的标签相对应。
预览(fdsLabelTrain)
ans =分类1
转换和组合数据存储
为了将预测器的数据存储中的序列数据输入到深度学习网络,序列的小批量必须具有相同的长度。方法转换数据存储padSequence
函数,定义在数据存储的末尾,它将序列填充或截断为长度为20的序列。
sequenceLength = 20;tdsTrain = transform(fdsPredictorTrain,@(data) padSequence(data,sequenceLength));
预览转换后的数据存储。输出对应于第一个文件中的填充序列。
X =预览(tdsTrain)
X =1×1单元格数组{12×20双}
要将两个数据存储中的预测器和标签都输入到深度学习网络中,请使用结合
函数。
cdsTrain = combine(tdsTrain,fdsLabelTrain);
预览组合的数据存储。数据存储返回一个1 × 2单元格数组。第一个元素对应于预测器。第二个元素对应于标签。
预览(cdsTrain)
ans =1×2单元格数组{12×20 double} {[1]}
定义LSTM网络体系结构
定义LSTM网络体系结构。指定输入数据的特征数量作为输入大小。指定一个带有100个隐藏单元的LSTM层,并输出序列的最后一个元素。最后,指定一个输出大小等于类数量的全连接层,然后是一个softmax层和一个classification层。
numFeatures = 12;numClasses = numel(classNames);numHiddenUnits = 100;层= [...sequenceInputLayer numFeatures lstmLayer (numHiddenUnits,“OutputMode”,“最后一次”) fullyConnectedLayer(numClasses) softmaxLayer classificationLayer];
指定培训选项。设置解算器为“亚当”
而且“GradientThreshold”
2。将mini-batch大小设置为27,并将最大epoch数设置为75。数据存储不支持变换,所以设置金宝app“洗牌”
来“永远”
.
因为迷你批的数量小,序列短,所以CPU更适合训练。集“ExecutionEnvironment”
来“cpu”
.要在GPU上训练,如果可用,请设置“ExecutionEnvironment”
来“汽车”
(默认值)。
miniBatchSize = 27;选项= trainingOptions(“亚当”,...“ExecutionEnvironment”,“cpu”,...“MaxEpochs”, 75,...“MiniBatchSize”miniBatchSize,...“GradientThreshold”2,...“洗牌”,“永远”,...“详细”0,...“阴谋”,“训练进步”);
使用指定的培训选项对LSTM网络进行培训。
net = trainNetwork(cdsTrain,layers,options);
测试网络
使用与训练数据相同的步骤创建包含保留测试数据的转换数据存储。
folderTest = fullfile(输出文件夹,“测试”);fdsPredictorTest = fileDatastore(文件夹测试,...“ReadFcn”@load,...“IncludeSubfolders”,真正的);tdsTest = transform(fdsPredictorTest,@(data) padSequence(data,sequenceLength));
使用训练好的网络对测试数据进行预测。
YPred =分类(net,tdsTest,“MiniBatchSize”, miniBatchSize);
计算测试数据的分类精度。要获得测试集的标签,请使用read函数创建一个文件数据存储readLabel
并指定包含子文件夹。属性指定输出是垂直连接的“UniformRead”
选项真正的
.
fdsLabelTest = fileDatastore(文件夹测试,...“ReadFcn”@(文件名)readLabel(文件名,类名),...“IncludeSubfolders”,真的,...“UniformRead”,真正的);YTest = readall(fdsLabelTest);
accuracy = mean(YPred == YTest)
准确度= 0.9351
功能
的readLabel
函数从指定的文件名中提取类别的标签一会
.
函数label = readLabel(文件名,classNames) filepath = fileparts(文件名);[~,label] = fileparts(filepath);label = categorical(string(label),classNames);结束
的padSequence
函数填充或截断序列数据。X
具有指定的序列长度,并以1 × 1单元格返回结果。
函数sequence = padSequence(data,sequenceLength) sequence = data. x;[C,S] = size(sequence);如果S < sequenceLength padding = 0 (C, sequencelengs);序列=[序列填充];其他的sequence = sequence(:,1:sequenceLength);结束序列={序列};结束
另请参阅
lstmLayer
|trainNetwork
|trainingOptions
|sequenceInputLayer
|结合
|变换