В этом примере показано, как классифицировать отказы на акустические записи воздушных компрессоров с помощью сети рассеивания вейвлета, соединенной с рекуррентной нейронной сетью. Пример обеспечивает возможность использовать графический процессор, чтобы ускориться, расчет рассеивания вейвлета преобразовывают. Если вы хотите использовать графический процессор, у вас должны быть Parallel Computing Toolbox™ и поддерживаемый графический процессор. Смотрите Поддержку графического процессора Релизом (Parallel Computing Toolbox) для деталей.
Набор данных состоит из акустических записей, собранных на одноступенчатом воздушном компрессоре типа оплаты [1]. Данные производятся на уровне 16 кГц. Технические требования воздушного компрессора следующие:
Область значений Давления воздуха: 0-500 lb/m2, 0-35 Kg/cm2
Асинхронный двигатель: 5 л. с., 415 В, 5:00, 50 Гц, 1440 об/мин
Датчик давления: введите PR-15, область значений 100-213 фунтов на квадратный дюйм
Каждая запись представляет одно из 8 состояний, которое включает здоровое состояние и 7 дефектных состояний. 7 дефектных состояний:
Отказ утечки вставила клапан (LIV)
Отказ клапана выхода утечки (LOV)
Отказ обратного клапана (NRV)
Поршневой кольцевой отказ
Отказ маховика
Отказ пояса наездника
Подшипник отказа
Загрузите набор данных и разархивируйте файл данных в папке, где у вас есть разрешение записи. Этот пример принимает, что вы загружаете данные во временной директории, определяемой как tempdir
в MATLAB®. Если вы приняли решение использовать другую папку, замените той папкой tempdir
в следующем. Записи хранятся как .wav файлы в папках, названных по имени их соответствующего состояния.
url = 'https://www.mathworks.com/supportfiles/audio/AirCompressorDataset/AirCompressorDataset.zip'; downloadFolder = fullfile(tempdir,'AirCompressorDataSet'); if ~exist(fullfile(tempdir,'AirCompressorDataSet'),'dir') loc = websave(downloadFolder,url); unzip(loc,fullfile(tempdir,'AirCompressorDataSet')) end
Используйте audioDatastore
управлять доступом к данным. Каждая подпапка содержит только записи обозначенного класса. Используйте имена папок в качестве меток класса.
datasetLocation = fullfile(tempdir,'AirCompressorDataSet','AirCompressorDataset'); ads = audioDatastore(datasetLocation,'IncludeSubfolders',true,... 'LabelSource','foldernames');
Исследуйте количество примеров в каждом классе. В каждом классе существует 225 записей.
countcats(ads.Labels)
ans = 8×1
225
225
225
225
225
225
225
225
Разделите данные в наборы обучающих данных и наборы тестов. Используйте 80% данных для обучения и протяните остающиеся 20% для тестирования. Переставьте данные, однажды разделяющие.
rng default
ads = shuffle(ads);
[adsTrain,adsTest] = splitEachLabel(ads,0.8,0.2);
Проверьте, что количество примеров в каждом классе является ожидаемым номером.
uniqueLabels = unique(adsTrain.Labels); tblTrain = countEachLabel(adsTrain); tblTest = countEachLabel(adsTest); H = bar(uniqueLabels,[tblTrain.Count, tblTest.Count],'stacked'); legend(H,["Training Set","Test Set"],'Location','NorthEastOutside')
Выберите некоторые случайные примеры из набора обучающих данных для графического вывода.
idx = randperm(numel(adsTrain.Files),8); Fs = 16e3; for n = 1:numel(idx) x = audioread(adsTrain.Files{idx(n)}); t = (0:size(x,1)-1)/Fs; subplot(4,2,n); plot(t,x); if n == 7 || n == 8 xlabel('Seconds'); end title(string(adsTrain.Labels(idx(n)))); end
Каждая запись имеет 50 000 выборок, произведенных на уровне 16 кГц. Создайте сеть рассеивания вейвлета на основе характеристик данных. Установите шкалу инвариантности составлять 0,5 секунды.
N = 5e4; Fs = 16e3; IS = 0.5; sn = waveletScattering('SignalLength',N,'SamplingFrequency',Fs,... 'InvarianceScale',0.5);
С этими сетевыми настройками существует 330 рассеивающихся путей и 25 раз окна на пример. Вы видите это со следующим кодом.
[~,npaths] = paths(sn); Ncfs = numCoefficients(sn); sum(npaths)
ans = 330
Ncfs
Ncfs = 25
Обратите внимание, что это уже представляет 6-кратное сокращение размера данных для каждой записи. Мы уменьшали размер данных с 50 000 выборок до 8 250 всего. Самое главное мы уменьшали размер данных вдоль измерения времени с 50 000 до 25 выборок. Это крайне важно для нашего использования текущей сети. Попытка использовать текущую сеть на исходных данных с 50 000 выборок сразу привела бы к проблемам памяти.
Получите функции рассеивания вейвлета наборов обучающих данных и наборов тестов. Если у вас есть подходящий графический процессор и Parallel Computing Toolbox, можно установить useGPU
к true
ускорять рассеивающееся преобразование. Функциональный helperBatchScatFeatures
получает рассеивающееся преобразование каждого примера.
batchsize = 64; useGPU = false; scTrain = []; while hasdata(adsTrain) sc = helperBatchScatFeatures(adsTrain,sn,N,batchsize,useGPU); scTrain = cat(3,scTrain,sc); end
Повторите процесс для протянутого набора тестов.
scTest = []; while hasdata(adsTest) sc = helperBatchScatFeatures(adsTest,sn,N,batchsize,useGPU); scTest = cat(3,scTest,sc); end
Удалите 0-th коэффициенты рассеивания порядка. И для наборов обучающих данных и для наборов тестов, помещенных, каждый 330 25 рассеивающийся преобразовывает в элемент массива ячеек для использования в обучении и тестирующий текущую сеть.
TrainFeatures = scTrain(2:end,:,:); TrainFeatures = squeeze(num2cell(TrainFeatures,[1 2])); YTrain = adsTrain.Labels; TestFeatures = scTest(2:end,:,:); TestFeatures = squeeze(num2cell(TestFeatures,[1 2])); YTest = adsTest.Labels;
Отзыв там является 1 440 учебными примерами и 360 примерами набора тестов. Соответственно TrainFeatures
и TestFeatures
массивы ячеек имеют 1 440 и 360 элементов соответственно.
Используйте количество рассеивающихся путей как количество функций. Создайте текущую сеть с одним слоем LSTM, скрывающим 512 модули. Следуйте за слоем LSTM с полносвязным слоем и наконец softmax слоем. Используйте 'zscore' нормализацию через все пути к рассеиванию во входе к сети.
[inputSize, ~] = size(TrainFeatures{1}); numHiddenUnits = 512; numClasses = numel(unique(YTrain)); layers = [ ... sequenceInputLayer(inputSize,'Normalization','zscore') lstmLayer(numHiddenUnits,'OutputMode','last') fullyConnectedLayer(numClasses) softmaxLayer classificationLayer];
Обучите сеть в течение 50 эпох с мини-пакетным размером 128. Использование оптимизатор Адама с начальной буквой изучает уровень 1e-4. Переставьте данные каждая эпоха.
maxEpochs = 50; miniBatchSize = 128; options = trainingOptions('adam', ... 'InitialLearnRate',1e-4,... 'MaxEpochs',maxEpochs, ... 'MiniBatchSize',miniBatchSize, ... 'SequenceLength','shortest', ... 'Shuffle','every-epoch',... 'Plots','training-progress',... 'Verbose',true); net = trainNetwork(TrainFeatures,YTrain,layers,options);
Training on single CPU. Initializing input data normalization. |========================================================================================| | Epoch | Iteration | Time Elapsed | Mini-batch | Mini-batch | Base Learning | | | | (hh:mm:ss) | Accuracy | Loss | Rate | |========================================================================================| | 1 | 1 | 00:00:08 | 16.41% | 2.1281 | 1.0000e-04 | | 5 | 50 | 00:00:59 | 100.00% | 0.0536 | 1.0000e-04 | | 10 | 100 | 00:01:51 | 100.00% | 0.0072 | 1.0000e-04 | | 14 | 150 | 00:02:40 | 100.00% | 0.0064 | 1.0000e-04 | | 19 | 200 | 00:03:27 | 100.00% | 0.0025 | 1.0000e-04 | | 23 | 250 | 00:04:14 | 100.00% | 0.0015 | 1.0000e-04 | | 28 | 300 | 00:05:00 | 100.00% | 0.0012 | 1.0000e-04 | | 32 | 350 | 00:05:45 | 100.00% | 0.0007 | 1.0000e-04 | | 37 | 400 | 00:06:29 | 100.00% | 0.0006 | 1.0000e-04 | | 41 | 450 | 00:07:12 | 100.00% | 0.0005 | 1.0000e-04 | | 46 | 500 | 00:07:55 | 100.00% | 0.0005 | 1.0000e-04 | | 50 | 550 | 00:08:41 | 100.00% | 0.0004 | 1.0000e-04 | |========================================================================================| Training finished: Reached final iteration.
В обучении сеть достигла близкой совершенной эффективности. Для того, чтобы гарантировать, что мы не имеем сверхподгонки к обучающим данным, используем протянутый набор тестов, чтобы определить, как хорошо наша сеть делает вывод к невидимым данным.
YPred = classify(net,TestFeatures); accuracy = 100*sum(YPred == YTest) / numel(YTest)
accuracy = 100
В этом случае мы видим, что эффективность на протянутом наборе тестов также превосходна.
figure confusionchart(YTest, YPred)
В этом примере рассеивание вейвлета преобразовывает, использовался с простой текущей сетью, чтобы классифицировать отказы на воздушный компрессор. Рассеивающееся преобразование позволило нам извлекать устойчивые функции нашего приобретения знаний проблемы. Кроме того, снижение объема данных, достигнутое вдоль измерения времени данных при помощи рассеивания вейвлета, преобразовывает, было очень важно для того, чтобы создать в вычислительном отношении выполнимую проблему для нашей текущей сети.
[1] Verma, Нищел К., Рахул Кумар Севэкула, Сонэл Диксит и Аль Сэлур. “Интеллектуальный основанный на условии Контроль Используя Акустические Сигналы для Воздушных Компрессоров”. Транзакции IEEE на Надежности 65, № 1 (март 2016): 291–309. https://doi.org/10.1109/TR.2015.2459684.
helperbatchscatfeatures - Эта функция возвращает время вейвлета, рассеивая матрицу функции для данного входного сигнала. Если useGPU
установлен в true
, рассеивающееся преобразование вычисляется на графическом процессоре.
function sc = helperBatchScatFeatures(ds,sn,N,batchsize,useGPU) % This function is only intended to support examples in the Wavelet % Toolbox. It may be changed or removed in a future release. % Read batch of data from audio datastore batch = helperReadBatch(ds,N,batchsize); if useGPU batch = gpuArray(batch); end % Obtain scattering features S = sn.featureMatrix(batch,'transform','log'); gather(batch); S = gather(S); % Subsample the features %sc = S(:,1:6:end,:); sc = S; end
helperReadBatch - Эта функция читает пакеты заданного размера от datastore и возвращает выходной параметр в одинарной точности. Каждый столбец выхода является отдельным сигналом от datastore. Выход может иметь меньше столбцов, чем пакетный размер, если datastore не имеет достаточного количества записей.
function batchout = helperReadBatch(ds,N,batchsize) % This function is only in support of Wavelet Toolbox examples. It may % change or be removed in a future release. % % batchout = readReadBatch(ds,N,batchsize) where ds is the Datastore and % ds is the Datastore % batchsize is the batchsize kk = 1; while(hasdata(ds)) && kk <= batchsize tmpRead = read(ds); batchout(:,kk) = cast(tmpRead(1:N),'single'); %#ok<AGROW> kk = kk+1; end end
Copyright 2021, The MathWorks, Inc.