В этом примере вы усиливаете графические процессоры для извлечения признаков и увеличения, чтобы уменьшить время, требуемое обучать модель глубокого обучения. Модель, которую вы обучаете, является сверточной нейронной сетью (CNN) для акустического распознавания отказа.
Audio Toolbox™ включает gpuArray
(Parallel Computing Toolbox) поддержка большинства экстракторов функции, включая популярные единицы, такие как melSpectrogram
и mfcc
. Для обзора поддержки графического процессора смотрите Поддержка графического процессора и Генерация кода.
Загрузите и разархивируйте воздушный набор данных компрессора [1]. Этот набор данных состоит из записей от воздушных компрессоров в здоровом состоянии или одном из семи дефектных состояний.
url = 'https://www.mathworks.com/supportfiles/audio/AirCompressorDataset/AirCompressorDataset.zip'; downloadFolder = fullfile(tempdir,'AirCompressorDataset'); datasetLocation = tempdir; if ~isfolder(fullfile(datasetLocation,'AirCompressorDataset')) loc = websave(downloadFolder,url); unzip(loc,fullfile(datasetLocation,'AirCompressorDataset')) end
Создайте audioDatastore
объект управлять данными и разделить его в наборы обучения и валидации.
ads = audioDatastore(downloadFolder,'IncludeSubfolders',true,'LabelSource','foldernames'); rng default [adsTrain,adsValidation] = splitEachLabel(ads,0.8);
Визуализируйте количество файлов в наборах обучения и валидации.
uniqueLabels = unique(adsTrain.Labels); tblTrain = countEachLabel(adsTrain); tblValidation = countEachLabel(adsValidation); H = bar(uniqueLabels,[tblTrain.Count, tblValidation.Count],'stacked'); legend(H,["Training Set","Validation Set"],'Location','NorthEastOutside')
Выберите случайные примеры из набора обучающих данных для графического вывода. Каждая запись имеет 50 000 выборок, произведенных на уровне 16 кГц.
t = (0:5e4-1)/16e3; tiledlayout(4,2,'TileSpacing','compact','Padding','compact') for n = 1:numel(uniqueLabels) idx = find(adsTrain.Labels==uniqueLabels(n)); [x,fs] = audioread(adsTrain.Files{idx(randperm(numel(idx),1))}); nexttile plotHandle = plot(t,x); if n == 7 || n == 8 xlabel('Seconds'); else set(gca,'xtick',[]) end title(string(uniqueLabels(n))); end
В этом примере вы выполняете извлечение признаков и увеличение данных при обучении сети. В этом разделе вы задаете извлечение признаков, и увеличение конвейерно обрабатывают и сравнивают скорость трубопровода, выполняемого на центральном процессоре против скорости трубопровода, выполняемого на графическом процессоре. Выход этого трубопровода является входом к CNN, который вы обучаете.
Создайте audioFeatureExtractor
возразите, чтобы извлечь mel спектры с помощью 200 мс mel окна с транзитным участком на 5 мс. Выход от extract
numHops
- 128 1 массивом.
afe = audioFeatureExtractor('SampleRate',fs, ... 'FFTLength',4096, ... 'Window',hann(round(fs*0.2),'periodic'), ... 'OverlapLength',round(fs*0.195), ... 'melSpectrum',true); setExtractorParams(afe,"melSpectrum",'NumBands',128); featureVector = extract(afe,x); [numHops,numFeatures,numChannels] = size(featureVector)
numHops = 586
numFeatures = 128
numChannels = 1
Методы глубокого обучения голодны данных, и обучающий набор данных в этом примере относительно мал. Используйте путаницу [2] метод увеличения, чтобы эффективно увеличить набор обучающих данных. В путанице вы объединяете функции, извлеченные из двух звуковых сигналов как взвешенная сумма. Два сигнала имеют различные метки, и метка, присвоенная объединенной матрице функции, вероятностно присвоена на основе смесительного коэффициента. Увеличение путаницы реализовано в объекте поддержки, Mixup
.
Создайте трубопровод, чтобы выполнить следующие шаги:
Извлеките логарифмическую-mel спектрограмму.
Примените путаницу к матрицам функции. Mixup
поддержка объектных выходных параметров массив ячеек, содержащий функции и метку.
Создайте две версии трубопровода для сравнения: тот, который выполняет трубопровод на вашем центральном процессоре и тот, который преобразует необработанный звуковой сигнал в gpuArray
так, чтобы трубопровод был выполнен на вашем графическом процессоре.
offset = eps; adsTrainCPU = transform(adsTrain,@(x)log10(extract(afe,x)+offset)); mixerCPU = Mixup(adsTrainCPU); adsTrainCPU = transform(adsTrainCPU,@(x,info)mix(mixerCPU,x,info),'IncludeInfo',true); adsTrainGPU = transform(adsTrain,@gpuArray); adsTrainGPU = transform(adsTrainGPU,@(x)log10(extract(afe,x)+offset)); mixerGPU = Mixup(adsTrainGPU); adsTrainGPU = transform(adsTrainGPU,@(x,info)mix(mixerGPU,x,info),'IncludeInfo',true);
Для набора валидации примените трубопровод извлечения признаков, но не увеличение. Поскольку вы не применяете путаницу, создаете объединенный datastore, чтобы вывести массив ячеек, содержащий функции и метку. Снова, создайте один трубопровод валидации, который выполняется на вашем графическом процессоре и одном трубопроводе валидации, который выполняется на вашем центральном процессоре.
adsValidationGPU = transform(adsValidation,@gpuArray); adsValidationGPU = transform(adsValidationGPU,@(x){log10(extract(afe,x)+offset)}); adsValidationGPU = combine(adsValidationGPU,arrayDatastore(adsValidation.Labels)); adsValidationCPU = transform(adsValidation,@(x){log10(extract(afe,x)+offset)}); adsValidationCPU = combine(adsValidationCPU,arrayDatastore(adsValidation.Labels));
Сравните время, которое требуется для центрального процессора и одного графического процессора, чтобы извлечь функции и выполнить увеличение данных.
tic for ii = 1:numel(adsTrain.Files) x = read(adsTrainCPU); end cpuPipeline = toc; reset(adsTrainCPU) tic for ii = 1:numel(adsTrain.Files) x = read(adsTrainGPU); end wait(gpuDevice) % Ensure all calculations are completed gpuPipeline = toc; reset(adsTrainGPU) fprintf(['Read, extract, and augment train set (CPU): %0.2f seconds\n' ... 'Read, extract, and augment train set (GPU): %0.2f seconds\n' ... 'Speedup (CPU time)/(GPU time): %0.3f\n\n'], ... cpuPipeline,gpuPipeline,cpuPipeline/gpuPipeline)
Read, extract, and augment train set (CPU): 110.80 seconds Read, extract, and augment train set (GPU): 34.65 seconds Speedup (CPU time)/(GPU time): 3.198
Чтение от datastore вносит существенное количество полного времени к трубопроводу. Сравнение только экстракции и увеличения показывает еще большее ускорение. Сравните только извлечение признаков на графическом процессоре по сравнению с на центральном процессоре.
x = read(ads); extract(afe,x); % Incur initialization cost outside timing loop tic for ii = 1:numel(adsTrain.Files) features = log10(extract(afe,x)+offset); end cpuFeatureExtraction = toc; x = gpuArray(x); % Incur initialization cost outside timing loop extract(afe,x); tic for ii = 1:numel(adsTrain.Files) features = log10(extract(afe,x)+offset); end wait(gpuDevice) % Ensure all calculations are completed gpuFeatureExtraction = toc; fprintf(['Extract features from train set (CPU): %0.2f seconds\n' ... 'Extract features from train set (GPU): %0.2f seconds\n' ... 'Speedup (CPU time)/(GPU time): %0.3f\n\n'], ... cpuFeatureExtraction,gpuFeatureExtraction,cpuFeatureExtraction/gpuFeatureExtraction)
Extract features from train set (CPU): 50.57 seconds Extract features from train set (GPU): 4.48 seconds Speedup (CPU time)/(GPU time): 11.299
Задайте сверточную нейронную сеть, которая берет увеличенную mel спектрограмму, как введено. Эта сеть применяет один сверточный слой, состоящий из 48 фильтров с 3х3 ядрами, сопровождаемыми слоем нормализации партии. и слоем активации ReLU. Измерение времени затем сворачивается с помощью макс. слоя объединения. Наконец, выход слоя объединения сокращен с помощью полносвязного слоя, сопровождаемого слоями классификации и softmax. Смотрите Список слоев глубокого обучения (Deep Learning Toolbox) для получения дополнительной информации.
numClasses = numel(categories(adsTrain.Labels)); imageSize = [numHops,afe.FeatureVectorLength]; layers = [ imageInputLayer(imageSize,'Normalization','none') convolution2dLayer(3,48,'Padding','same') batchNormalizationLayer reluLayer maxPooling2dLayer([numHops,1]) fullyConnectedLayer(numClasses) softmaxLayer classificationLayer('Classes',categories(adsTrain.Labels)); ];
Чтобы задать опции обучения, используйте trainingOptions
(Deep Learning Toolbox). Установите ExecutionEnvironment
к multi-gpu
усиливать несколько графических процессоров, при наличии. В противном случае можно установить ExecutionEnvironment
к gpu
. Компьютер, используемый в этом примере, имеет доступ к четырем Титанам V устройств графического процессора. В этом примере сетевое обучение всегда усиливает графические процессоры.
miniBatchSize = 128; options = trainingOptions('adam', ... 'Shuffle','every-epoch', ... 'MaxEpochs',40, ... 'LearnRateSchedule',"piecewise", ... 'LearnRateDropPeriod',15, ... 'LearnRateDropFactor',0.2, ... 'MiniBatchSize',miniBatchSize, ... 'Plots','training-progress', ... 'Verbose',false, ... 'ValidationData',adsValidationCPU, ... 'ValidationFrequency',ceil(numel(adsTrain.Files)/miniBatchSize), ... 'ExecutionEnvironment','multi-gpu');
Вызовите trainNetwork
(Deep Learning Toolbox), чтобы обучить сеть с помощью центрального процессора для трубопровода извлечения признаков. Средой выполнения для сетевого обучения является ваш графический процессор (процессоры).
tic net = trainNetwork(adsTrainCPU,layers,options);
cpuTrainTime = toc;
Замените данные о валидации в опциях обучения с основанным на графическом процессоре трубопроводом. Обучите сеть с помощью графического процессора (процессоров) для трубопровода извлечения признаков. Средой выполнения для сетевого обучения является ваш графический процессор (процессоры).
options.ValidationData = adsValidationGPU; tic net = trainNetwork(adsTrainGPU,layers,options);
gpuTrainTime = toc;
Распечатайте результаты синхронизации для обучения с помощью центрального процессора для извлечения признаков и увеличения и обучения с помощью графического процессора (процессоров) для извлечения признаков и увеличения.
fprintf(['Training time (CPU): %0.2f seconds\n' ... 'Training time (GPU): %0.2f seconds\n' ... 'Speedup (CPU time)/(GPU time): %0.3f\n\n'], ... cpuTrainTime,gpuTrainTime,cpuTrainTime/gpuTrainTime)
Training time (CPU): 4242.82 seconds Training time (GPU): 731.77 seconds Speedup (CPU time)/(GPU time): 5.798
Сравните время, которое требуется, чтобы выполнить предсказание на одних 3 вторых клипах, когда извлечение признаков выполняется на графическом процессоре по сравнению с центральным процессором. В обоих случаях сетевое предсказание происходит на вашем графическом процессоре.
signalToClassify = read(ads); gpuFeatureExtraction = gputimeit(@()predict(net,log10(extract(afe,gpuArray(signalToClassify))+offset))); cpuFeatureExtraction = gputimeit(@()predict(net,log10(extract(afe,(signalToClassify))+offset))); fprintf(['Prediction time for 3 s of data (feature extraction on CPU): %0.2f ms\n' ... 'Prediction time for 3 s of data (feature extraction on GPU): %0.2f ms\n' ... 'Speedup (CPU time)/(GPU time): %0.3f\n\n'], ... cpuFeatureExtraction*1e3,gpuFeatureExtraction*1e3,cpuFeatureExtraction/gpuFeatureExtraction)
Prediction time for 3 s of data (feature extraction on CPU): 41.62 ms Prediction time for 3 s of data (feature extraction on GPU): 7.71 ms Speedup (CPU time)/(GPU time): 5.397
Сравните время, которое требуется, чтобы выполнить предсказание на наборе 3 вторых клипов, когда извлечение признаков выполняется на графическом процессоре (процессорах) по сравнению с центральным процессором. В обоих случаях сетевое предсказание происходит на вашем графическом процессоре (процессорах).
adsValidationGPU = transform(adsValidation,@(x)gpuArray(x)); adsValidationGPU = transform(adsValidationGPU,@(x){log10(extract(afe,x)+offset)}); adsValidationCPU = transform(adsValidation,@(x){log10(extract(afe,x)+offset)}); gpuFeatureExtraction = gputimeit(@()predict(net,adsValidationGPU,'ExecutionEnvironment','multi-gpu')); cpuFeatureExtraction = gputimeit(@()predict(net,adsValidationCPU,'ExecutionEnvironment','multi-gpu')); fprintf(['Prediction time for validation set (feature extraction on CPU): %0.2f s\n' ... 'Prediction time for validation set (feature extraction on GPU): %0.2f s\n' ... 'Speedup (CPU time)/(GPU time): %0.3f\n\n'], ... cpuFeatureExtraction,gpuFeatureExtraction,cpuFeatureExtraction/gpuFeatureExtraction)
Prediction time for validation set (feature extraction on CPU): 34.11 s Prediction time for validation set (feature extraction on GPU): 5.53 s Speedup (CPU time)/(GPU time): 6.173
Известно, что можно уменьшить время, которое требуется, чтобы обучить сеть путем усиления устройств графического процессора. Это позволяет вам более быстро выполнить итерации и разработать свою итоговую систему. Во многих учебных настройках можно достигнуть дополнительного увеличения производительности путем усиления устройств графического процессора для увеличения данных и извлечения признаков. Этот пример показывает значительное уменьшение в полное время, которое требуется, чтобы обучить CNN при усилении устройств графического процессора для увеличения данных и извлечения признаков. Кроме того, усиление устройств графического процессора для извлечения признаков во время вывода, и для одно наблюдений и для наборов данных, достигает значительного увеличения производительности.
Объект поддержки, Mixup
, помещается в вашу текущую папку, когда вы открываете этот пример.
type Mixup
classdef Mixup < handle %MIXUP Mixup data augmentation % mixer = Mixup(augDatastore) creates an object that can mix features % at a randomly set ratio and then probabilistically set the output % label as one of the two original signals. % % Mixup Properties: % MixProbability - Mix probability % AugDatastore - Augmentation datastore % % Mixup Methods: % mix - Apply mixup % % Copyright 2021 The MathWorks, Inc. properties (SetAccess=public,GetAccess=public) %MixProbability Mix probability % Specify the probability that mixing is applied as a scalar in the % range [0,1]. If unspecified, MixProbability defaults to 1/3. MixProbability (1,1) {mustBeNumeric} = 1/3; end properties (SetAccess=immutable,GetAccess=public) %AUGDATASTORE Augmentation datastore % Specify a datastore from which to get the mixing signals. The % datastore must contain a label in the info returned from reading. % This property is immutable, meaning it cannot be changed after % construction. AugDatastore end methods function obj = Mixup(augDatastore) obj.AugDatastore = augDatastore; end function [dataOut,infoOut] = mix(obj,x,infoIn) %MIX Apply mixup % [dataOut,infoOut] = mix(mixer,x,infoIn) probabilistically mix % the input, x, and its associated label contained in infoIn % with a signal randomly drawn from the augmentation datastore. % The output, dataOut, is a cell array with two columns. The % first column contains the features and the second column % contains the label. if rand > obj.MixProbability % Only mix ~1/3 the dataset % Randomly set mixing coefficient. Draw from a normal % distribution with mean 0.5 and contained within [0,1]. lambda = max(min((randn./10)+0.5,1),0); % Read one file from the augmentation datastore. subDS = subset(obj.AugDatastore,randi([1,numel(obj.AugDatastore.UnderlyingDatastores{1}.Files)])); [y,yInfo] = read(subDS); % Mix the features element-by-element according to lambda. dataOut = lambda*x + (1-lambda)*y; % Set the output label probabilistically based on the mixing coefficient. if lambda < rand labelOut = yInfo.Label; infoOut.Label = labelOut; else labelOut = infoIn.Label; end infoOut.Label = labelOut; % Combine the output data and labels. dataOut = [{dataOut},{labelOut}]; else % Do not apply mixing dataOut = [{x},{infoIn.Label}]; infoOut = infoIn; end end end end
[1] Verma, Нищел К., и др. "Интеллектуальный основанный на условии Контроль Используя Акустические Сигналы для Воздушных Компрессоров". Транзакции IEEE на Надежности, издании 65, № 1, март 2016, стр 291–309. DOI.org (Crossref), doi:10.1109/TR.2015.2459684.
[2] Huszar, Ференц. "Путаница: информационно-зависимое Увеличение Данных". InFERENCe. 03 ноября 2017. Полученный доступ 15 января 2019. https://www.inference.vc/mixup-data-dependent-data-augmentation/.