В этом примере вы разрабатываете модель глубокого обучения, чтобы обнаружить отказы в воздушном компрессоре с помощью акустических измерений. После разработки модели вы группируете систему так, чтобы можно было распознать отказы на основе потоковой передачи входных данных.
Загрузите и разархивируйте воздушный набор данных компрессора [1]. Этот набор данных состоит из записей от воздушных компрессоров в здоровом состоянии или одном из семи дефектных состояний.
loc = matlab.internal.examples.downloadSupportFile('audio','AirCompressorDataset/AirCompressorDataset.zip'); unzip(loc,pwd)
Создайте audioDatastore
Объект (Audio Toolbox) управлять данными и разделить его в наборы обучения и валидации. Вызовите countEachLabel
(Audio Toolbox), чтобы смотреть распределение меток в наборах обучения и валидации.
ads = audioDatastore(pwd,'IncludeSubfolders',true,'LabelSource','foldernames'); [adsTrain,adsValidation] = splitEachLabel(ads,0.9,0.1); countEachLabel(adsTrain)
ans=8×2 table
Label Count
_________ _____
Bearing 203
Flywheel 203
Healthy 203
LIV 203
LOV 203
NRV 203
Piston 203
Riderbelt 203
countEachLabel(adsValidation)
ans=8×2 table
Label Count
_________ _____
Bearing 22
Flywheel 22
Healthy 22
LIV 22
LOV 22
NRV 22
Piston 22
Riderbelt 22
adsTrain = shuffle(adsTrain); adsValidation = shuffle(adsValidation);
Можно уменьшать обучающий набор данных, используемый в этом примере, чтобы ускорить время выполнения за счет эффективности. В общем случае сокращение набора данных является хорошей практикой для разработки и отладки.
reduceDataset = false; if reduceDataset adsTrain = splitEachLabel (adsTrain, 20); end
Данные состоят из записей timeseries акустики от неисправных или здоровых воздушных компрессоров. По сути, существуют прочные отношения между выборками вовремя. Слушайте запись и постройте форму волны.
[sampleData,sampleDataInfo] = read(adsTrain); fs = sampleDataInfo.SampleRate; soundsc(sampleData,fs) plot(sampleData) xlabel("Sample") ylabel("Amplitude") title("State: " + string(sampleDataInfo.Label)) axis tight
Поскольку выборки связаны во времени, можно использовать рекуррентную нейронную сеть (RNN), чтобы смоделировать данные. Сеть долгой краткосрочной памяти (LSTM) является популярным выбором RNN, потому что это спроектировано, чтобы не исчезать и взрывать градиенты. Прежде чем можно будет обучить сеть, важно подготовить данные соответственно. Часто, лучше преобразовывать или извлекать функции из 1-мерных данных сигнала для того, чтобы обеспечить более богатый набор функций модели, чтобы извлечь уроки из.
Следующий шаг должен извлечь набор акустических функций, использованных как входные параметры к сети. Audio Toolbox™ позволяет вам извлечь спектральные дескрипторы, которые обычно используются в качестве входных параметров в задачах машинного обучения. Можно извлечь функции с помощью отдельных функций, или можно использовать audioFeatureExtractor
(Audio Toolbox), чтобы упростить рабочий процесс и сделать все это целиком.
trainFeatures = cell(1,numel(adsTrain.Files)); windowLength = 512; overlapLength = 0; aFE = audioFeatureExtractor('SampleRate',fs, ... 'Window',hamming(windowLength,'periodic'),... 'OverlapLength',overlapLength,... 'spectralCentroid',true, ... 'spectralCrest',true, ... 'spectralDecrease',true, ... 'spectralEntropy',true, ... 'spectralFlatness',true, ... 'spectralFlux',false, ... 'spectralKurtosis',true, ... 'spectralRolloffPoint',true, ... 'spectralSkewness',true, ... 'spectralSlope',true, ... 'spectralSpread',true); reset(adsTrain) tic for index = 1:numel(adsTrain.Files) data = read(adsTrain); trainFeatures{index} = (extract(aFE,data))'; end fprintf('Feature extraction of training set took %f seconds.\n',toc);
Feature extraction of training set took 13.648354 seconds.
Набор обучающих данных содержит относительно небольшое количество акустических записей для обучения модель глубокого обучения. Популярный метод, чтобы увеличить набор данных должен использовать путаницу. В путанице вы увеличиваете свой набор данных путем смешивания функций и меток от двух различных экземпляров класса. Путаница была переформулирована [2] как метки, чертившие от вероятностного распределения вместо смешанных меток. Функция поддержки, путаница, берет учебные функции, сопоставленные метки и количество смесей на наблюдение и затем выводит смеси и сопоставленные метки.
trainLabels = adsTrain.Labels; numMixesPerInstance = 2; тик [augData, augLabels] = путаница (trainFeatures, trainLabels, numMixesPerInstance); trainLabels = кошка (1, trainLabels, augLabels); trainFeatures = кошка (2, trainFeatures, augData); fprintf'Feature augmentation of train set took %f seconds.\n'toc;
Feature augmentation of train set took 0.250037 seconds.
Повторите извлечение признаков для функций валидации.
validationFeatures = cell(1,numel(adsValidation.Files)); reset(adsValidation) tic for index = 1:numel(adsValidation.Files) data = read(adsValidation); validationFeatures{index} = (extract(aFE,data))'; end fprintf('Feature extraction of validation set took %f seconds.\n',toc);
Feature extraction of validation set took 1.388853 seconds.
Затем вы задаете и обучаете сеть. Чтобы пропустить обучение сеть, установите downloadPretrainedSystem
к true
, затем продолжите к следующему разделу.
downloadPretrainedSystem = false; if downloadPretrainedSystem местоположение = matlab.internal.examples.downloadSupportFile ('audio','AcousticsBasedMachineFaultRecognition/AcousticsBasedMachineFaultRecognition.zip'); разархивируйте (местоположение, pwd) addpath (fullfile (pwd,'AcousticsBasedMachineFaultRecognition')) end
Слой LSTM изучает долгосрочные зависимости между временными шагами данных о последовательности или временных рядов. Первый lstmLayer
имеет 100 скрытых модулей и выходные данные о последовательности. Затем слой уволенного используется, чтобы уменьшать сверхподбор кривой. Второй lstmLayer
выводит последний шаг последовательности времени.
numHiddenUnits = 100; dropProb = 0.2; слои = [ ... sequenceInputLayer (aFE.FeatureVectorLength,'Normalization','zscore') lstmLayer (numHiddenUnits,"OutputMode","sequence") dropoutLayer (dropProb) lstmLayer (numHiddenUnits,"OutputMode","last") fullyConnectedLayer (numel (уникальный (adsTrain.Labels))) softmaxLayer classificationLayer];
Чтобы задать гиперпараметры для сети, используйте trainingOptions
.
miniBatchSize = 128; validationFrequency = пол (numel (trainFeatures)/miniBatchSize); опции = trainingOptions ("adam", ... "MiniBatchSize", miniBatchSize, ... "MaxEpochs",35, ... "Plots","training-progress", ... "Verbose"ложь, ... "Shuffle","every-epoch", ... "LearnRateSchedule","piecewise", ... "LearnRateDropPeriod",30, ... "LearnRateDropFactor",0.1, ... "ValidationData", {validationFeatures, adsValidation.Labels}, ... "ValidationFrequency", validationFrequency);
Чтобы обучить сеть, используйте trainNetwork
.
airCompNet = trainNetwork(trainFeatures,trainLabels,layers,options);
Просмотрите график беспорядка для данных о валидации.
validationResults = classify(airCompNet,validationFeatures); cm = confusionchart(validationResults,adsValidation.Labels); accuracy = mean(validationResults == adsValidation.Labels)*100; cm.title("Accuracy: " + accuracy + " (%)")
Если у вас есть обучивший сеть с удовлетворительной эффективностью, можно применить сеть к тестовым данным способом потоковой передачи.
Существует много дополнительных факторов, чтобы учесть, чтобы заставить систему работать в реальной встраиваемой системе.
Например,
Уровень или интервал, в котором классификация может быть выполнена точными результатами
Размер сети в терминах сгенерированного кода (память программ) и веса (память данных)
КПД сети в терминах скорости расчета
В MATLAB можно подражать, как сеть развертывается и используется в оборудовании на действительной встраиваемой системе, и начните отвечать на эти важные вопросы.
Если вы обучаете свою модель глубокого обучения, вы развернете ее в целевой процессор. Это означает, что также необходимо развернуться, код раньше выполнял извлечение признаков. Используйте generateMATLABFunction
метод audioFeatureExtractor
сгенерировать функцию MATLAB, совместимую с генерацией кода C/C++. Задайте IsStreaming
как true
так, чтобы сгенерированная функция была оптимизирована для потоковой обработки.
filename = fullfile(pwd,"extractAudioFeatures"); generateMATLABFunction(aFE,filename,'IsStreaming',true);
Сохраните обучивший сеть как файл MAT.
save('AirCompressorFaultRecognitionModel.mat','airCompNet')
Создайте функцию, которая комбинирует классификацию извлечений признаков и глубокого обучения.
type recognizeAirCompressorFault.m
function scores = recognizeAirCompressorFault(audioIn,rs) % This is a streaming classifier function persistent airCompNet if isempty(airCompNet) airCompNet = coder.loadDeepLearningNetwork('AirCompressorFaultRecognitionModel.mat'); end if rs airCompNet = resetState(airCompNet); end % Extract features using function features = extractAudioFeatures(audioIn); % Classify [airCompNet,scores] = predictAndUpdateState(airCompNet,features); end
Затем вы тестируете классификатор потоковой передачи в MATLAB. Потоковое аудио одна система координат за один раз, чтобы представлять систему, когда это было бы развернуто во встроенной системе реального времени. Это позволяет вам измерить и визуализировать синхронизацию и точность реализации потоковой передачи.
Поток в нескольких звуковых файлах и графике классификация выходов заканчивается для каждой системы координат данных. Во временном интервале, равном длине каждого файла, оцените выход классификатора.
reset(adsValidation) N = 10; labels = categories(ads.Labels); numLabels = numel(labels); % Create a dsp.AsyncBuffer to read audio in a streaming fashion audioSource = dsp.AsyncBuffer; % Create a dsp.AsyncBuffer to accumulate scores scoreBuffer = dsp.AsyncBuffer; % Create a dsp.AsyncBuffer to record execution time. timingBuffer = dsp.AsyncBuffer; % Pre-allocate array to store results streamingResults = categorical(zeros(N,1)); % Loop over files for fileIdx = 1:N % Read one audio file and put it in the source buffer [data,dataInfo] = read(adsValidation); write(audioSource,data); % Inner loop over frames rs = true; while audioSource.NumUnreadSamples >= windowLength % Get a frame of audio data x = read(audioSource,windowLength); % Apply streaming classifier function tic score = recognizeAirCompressorFault(x,rs); write(timingBuffer,toc); % Store score for analysis write(scoreBuffer,score); rs = false; end reset(audioSource) % Store class result for that file scores = read(scoreBuffer); [~,result] = max(scores(end,:),[],2); streamingResults(fileIdx) = categorical(labels(result)); % Plot scores to compare over time figure plot(scores) %#ok<*NASGU> legend(string(airCompNet.Layers(end).Classes),'Location','northwest') xlabel("Time Step") ylabel("Score") str = sprintf('Known label = %s\nPredicted label = %s',string(dataInfo.Label),string(streamingResults(fileIdx))); title(str) end
Сравните результаты испытаний для версии потоковой передачи классификатора и непотоковой передачи.
testError = mean(validationResults(1:N) ~= streamingResults); disp("Error between streaming classifier and non-streaming: " + testError*100 + " (%)")
Error between streaming classifier and non-streaming: 0 (%)
Анализируйте время выполнения. Время выполнения, когда состояние сбрасывается, часто выше бюджета на 32 мс. Однако в действительной, развернутой системе, то время инициализации будет только понесено однажды. Время выполнения основного цикла составляет приблизительно 10 мс, который является значительно ниже бюджета на 32 мс для эффективности в реальном времени.
executionTime = read(timingBuffer)*1000; budget = (windowLength/aFE.SampleRate)*1000; plot(executionTime,'o') title('Execution Time Per Frame') xlabel('Frame Number') ylabel('Time (ms)') yline(budget,'',{'Budget'},'LineWidth',2)
function [augData,augLabels] = mixup(data,labels,numMixesPerInstance) augData = cell(1,numel(data)*numMixesPerInstance); augLabels = repelem(labels,numMixesPerInstance); kk = 1; for ii = 1:numel(data) for jj = 1:numMixesPerInstance lambda = max(min((randn./10)+0.5,1),0); % Find all available data with different labels. availableData = find(labels~=labels(ii)); % Randomly choose one of the available data with a different label. numAvailableData = numel(availableData); idx = randi([1,numAvailableData]); % Mix. augData{kk} = lambda*data{ii} + (1-lambda)*data{availableData(idx)}; % Specify the label as randomly set by lambda. if lambda < rand augLabels(kk) = labels(availableData(idx)); else augLabels(kk) = labels(ii); end kk = kk + 1; 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/.